1 | CSS MQPacker
|
2 | ============
|
3 |
|
4 | Pack same CSS media query rules into one media query rule.
|
5 |
|
6 | Written with [PostCSS][1].
|
7 |
|
8 |
|
9 | INSTALLATION
|
10 | ------------
|
11 |
|
12 | $ npm install css-mqpacker
|
13 |
|
14 | Or install as [Grunt plugin][2].
|
15 |
|
16 |
|
17 | QUICK USAGE
|
18 | -----------
|
19 |
|
20 | Read `from.css`, process its content, and output processed CSS to STDOUT.
|
21 |
|
22 | ```js
|
23 | #!/usr/bin/env node
|
24 |
|
25 | 'use strict';
|
26 |
|
27 | var fs = require('fs');
|
28 | var mqpacker = require('css-mqpacker');
|
29 |
|
30 | var original = fs.readFileSync('from.css', 'utf8');
|
31 | var processed = mqpacker.pack(original, {
|
32 | from: 'from.css',
|
33 | map: {
|
34 | inline: false
|
35 | },
|
36 | to: 'to.css'
|
37 | });
|
38 | console.log(processed.css);
|
39 | ```
|
40 |
|
41 | If `test.css` has:
|
42 |
|
43 | ```css
|
44 | @charset "UTF-8";
|
45 |
|
46 | .foo::before {
|
47 | content: "foo on small";
|
48 | }
|
49 |
|
50 | @media screen and (min-width: 769px) {
|
51 | .foo::before {
|
52 | content: "foo on medium";
|
53 | }
|
54 | }
|
55 |
|
56 | .bar::before {
|
57 | content: "bar on small";
|
58 | }
|
59 |
|
60 | @media screen and (min-width: 769px) {
|
61 | .bar::before {
|
62 | content: "bar on medium";
|
63 | }
|
64 | }
|
65 | ```
|
66 |
|
67 | You will get following output:
|
68 |
|
69 | ```css
|
70 | @charset "UTF-8";
|
71 |
|
72 | .foo::before {
|
73 | content: "foo on small";
|
74 | }
|
75 |
|
76 | .bar::before {
|
77 | content: "bar on small";
|
78 | }
|
79 |
|
80 | @media screen and (min-width: 769px) {
|
81 | .foo::before {
|
82 | content: "foo on medium";
|
83 | }
|
84 | .bar::before {
|
85 | content: "bar on medium";
|
86 | }
|
87 | }
|
88 |
|
89 | /*# sourceMappingURL=to.css.map */
|
90 | ```
|
91 |
|
92 | Sweet!
|
93 |
|
94 |
|
95 | API
|
96 | ---
|
97 |
|
98 | ### pack(css, [options])
|
99 |
|
100 | Packs media queries in `css`.
|
101 |
|
102 | The second argument is optional. The `options` is same as the second argument of
|
103 | PostCSS's `process()` method. This is useful for generating Source Map.
|
104 |
|
105 | ```javascript
|
106 | var fs = require('fs');
|
107 | var mqpacker = require('css-mqpacker');
|
108 |
|
109 | var css = fs.readFileSync('from.css', 'utf8');
|
110 | var result = mqpacker.pack(css, {
|
111 | from: 'from.css',
|
112 | map: {
|
113 | inline: false
|
114 | },
|
115 | to: 'to.css'
|
116 | });
|
117 | fs.writeFileSync('to.css', result.css);
|
118 | fs.writeFileSync('to.css.map', result.map);
|
119 | ```
|
120 |
|
121 | See also [PostCSS document][3] for more about `options`.
|
122 |
|
123 |
|
124 | ### postcss
|
125 |
|
126 | Returns [PostCSS processor][4].
|
127 |
|
128 | You can use this property for combining with other PostCSS processors such as
|
129 | [Autoprefixer][5].
|
130 |
|
131 | ```javascript
|
132 | var autoprefixer = require('autoprefixer');
|
133 | var mqpacker = require('css-mqpacker');
|
134 | var postcss = require('postcss');
|
135 |
|
136 | var css = fs.readFileSync('test.css', 'utf8');
|
137 | postcss().use(
|
138 | autoprefixer.postcss
|
139 | ).use(
|
140 | mqpacker.postcss
|
141 | ).process(css);
|
142 | ```
|
143 |
|
144 |
|
145 | KNOWN ISSUE
|
146 | -----------
|
147 |
|
148 | ### The "First Win" Algorithm
|
149 |
|
150 | CSS MQPacker is implemented with the "first win" algorithm. This means:
|
151 |
|
152 | ```css
|
153 | .foo {
|
154 | width: 10px;
|
155 | }
|
156 |
|
157 | @media (min-width: 640px) {
|
158 | .foo {
|
159 | width: 150px;
|
160 | }
|
161 | }
|
162 |
|
163 | .bar {
|
164 | width: 20px;
|
165 | }
|
166 |
|
167 | @media (min-width: 320px) {
|
168 | .bar {
|
169 | width: 200px;
|
170 | }
|
171 | }
|
172 |
|
173 | @media (min-width: 640px) {
|
174 | .bar {
|
175 | width: 300px;
|
176 | }
|
177 | }
|
178 | ```
|
179 |
|
180 | Becomes:
|
181 |
|
182 | ```css
|
183 | .foo {
|
184 | width: 10px;
|
185 | }
|
186 |
|
187 | .bar {
|
188 | width: 20px;
|
189 | }
|
190 |
|
191 | @media (min-width: 640px) {
|
192 | .foo {
|
193 | width: 150px;
|
194 | }
|
195 | .bar {
|
196 | width: 300px;
|
197 | }
|
198 | }
|
199 |
|
200 | @media (min-width: 320px) {
|
201 | .bar {
|
202 | width: 200px;
|
203 | }
|
204 | }
|
205 | ```
|
206 |
|
207 | This breaks cascading order of `.bar`, and displayed in `200px` instead of
|
208 | `300px` if a viewport wider than `640px`.
|
209 |
|
210 | I suggest defining queries order at first:
|
211 |
|
212 | ```css
|
213 | @media (min-width: 320px) { /*! Wider than 320px */ }
|
214 | @media (min-width: 640px) { /*! Wider than 640px */ }
|
215 | ```
|
216 |
|
217 |
|
218 | ### Multiple Classes
|
219 |
|
220 | CSS MQPacker changes order of rulesets. This may breaks CSS applying order.
|
221 |
|
222 | ```css
|
223 | @media (min-width: 320px) {
|
224 | .foo {
|
225 | width: 100px;
|
226 | }
|
227 | }
|
228 |
|
229 | @media (min-width: 640px) {
|
230 | .bar {
|
231 | width: 200px;
|
232 | }
|
233 | }
|
234 |
|
235 | @media (min-width: 320px) {
|
236 | .baz {
|
237 | width: 300px;
|
238 | }
|
239 | }
|
240 | ```
|
241 |
|
242 | Becomes:
|
243 |
|
244 | ```css
|
245 | @media (min-width: 320px) {
|
246 | .foo {
|
247 | width: 100px;
|
248 | }
|
249 | .baz {
|
250 | width: 300px;
|
251 | }
|
252 | }
|
253 |
|
254 | @media (min-width: 640px) {
|
255 | .bar {
|
256 | width: 200px;
|
257 | }
|
258 | }
|
259 | ```
|
260 |
|
261 | Fine. But If a HTML element has `class="bar baz"` and viewport width larget than
|
262 | `640px`, that element `width` incorrectly set to `200px` instead of `300px`.
|
263 |
|
264 |
|
265 | LICENSE
|
266 | -------
|
267 |
|
268 | MIT: http://hail2u.mit-license.org/2014
|
269 |
|
270 |
|
271 | [1]: https://github.com/ai/postcss
|
272 | [2]: https://github.com/hail2u/grunt-css-mqpacker
|
273 | [3]: https://github.com/postcss/postcss#source-map-1
|
274 | [4]: https://github.com/postcss/postcss#processor
|
275 | [5]: https://github.com/postcss/autoprefixer-core
|