@@ -7,48 +7,47 @@ Pack same CSS media query rules into one using PostCSS
7
7
SYNOPSIS
8
8
--------
9
9
10
- A CSS file processed with a CSS pre-processor may have same queries that can
11
- merge:
10
+ A well componentized CSS file may have same media queries that can merge:
12
11
13
12
``` css
14
- .foo ::before {
15
- content : " foo on small " ;
13
+ .foo {
14
+ width : 240 px ;
16
15
}
17
16
18
- @media screen and (min-width : 769 px ) {
19
- .foo ::before {
20
- content : " foo on medium " ;
17
+ @media screen and (min-width : 768 px ) {
18
+ .foo {
19
+ width : 576 px ;
21
20
}
22
21
}
23
22
24
- .bar ::before {
25
- content : " bar on small " ;
23
+ .bar {
24
+ width : 160 px ;
26
25
}
27
26
28
- @media screen and (min-width : 769 px ) {
29
- .bar ::before {
30
- content : " bar on medium " ;
27
+ @media screen and (min-width : 768 px ) {
28
+ .bar {
29
+ width : 384 px ;
31
30
}
32
31
}
33
32
```
34
33
35
- This PostCSS plugin packs exactly same queries (and optionally sorts) like this :
34
+ This PostCSS plugin packs exactly same media queries :
36
35
37
36
``` css
38
- .foo ::before {
39
- content : " foo on small " ;
37
+ .foo {
38
+ width : 240 px ;
40
39
}
41
40
42
- .bar ::before {
43
- content : " bar on small " ;
41
+ .bar {
42
+ width : 160 px ;
44
43
}
45
44
46
- @media screen and (min-width : 769 px ) {
47
- .foo ::before {
48
- content : " foo on medium " ;
45
+ @media screen and (min-width : 768 px ) {
46
+ .foo {
47
+ width : 576 px ;
49
48
}
50
- .bar ::before {
51
- content : " bar on medium " ;
49
+ .bar {
50
+ width : 384 px ;
52
51
}
53
52
}
54
53
```
@@ -70,40 +69,40 @@ Of course, this package can be used as PostCSS plugin:
70
69
71
70
" use strict" ;
72
71
73
- var fs = require (" fs" );
74
- var postcss = require (" postcss" );
72
+ const fs = require (" fs" );
73
+ cosnt postcss = require (" postcss" );
75
74
76
- var css = fs .readFileSync (" from.css" , " utf8" );
77
75
postcss ([
78
76
require (" autoprefixer-core" )(),
79
77
require (" css-mqpacker" )()
80
- ]).process (css).then (function (result ) {
78
+ ]).process (fs . readFileSync ( " from. css" , " utf8 " ) ).then (function (result ) {
81
79
console .log (result .css );
82
80
});
83
81
```
84
82
83
+ It is a recommended way to use this tool.
84
+
85
85
86
86
### As standard Node.js package
87
87
88
- Read ` from.css ` , process its content, and output processed CSS to STDOUT.
88
+ This package is also a Node.js module. For exmaple, you can read ` from.css ` ,
89
+ process its content, and output processed CSS to STDOUT:
89
90
90
91
``` javascript
91
92
#! / usr/ bin/ env node
92
93
93
94
" use strict" ;
94
95
95
- var fs = require (" fs" );
96
- var mqpacker = require (" css-mqpacker" );
96
+ const fs = require (" fs" );
97
+ const mqpacker = require (" css-mqpacker" );
97
98
98
- var original = fs .readFileSync (" from.css" , " utf8" );
99
- var processed = mqpacker .pack (original, {
99
+ cosole .log (mqpacker .pack (fs .readFileSync (" from.css" , " utf8" ), {
100
100
from: " from.css" ,
101
101
map: {
102
102
inline: false
103
103
},
104
104
to: " to.css"
105
- });
106
- console .log (processed .css );
105
+ }).css );
107
106
```
108
107
109
108
@@ -134,14 +133,18 @@ format instead of Node.js stack trace.
134
133
135
134
The ` --sort ` option does not currently support a custom function.
136
135
136
+ If you install this package in global, CLI will be available somewhere in the
137
+ ` $PATH ` .
138
+
137
139
138
140
OPTIONS
139
141
-------
140
142
141
143
### sort
142
144
143
- By default, CSS MQPacker pack and order media queries as they are defined. If
144
- you want to sort queries automatically, pass ` sort: true ` to this module.
145
+ By default, CSS MQPacker pack and order media queries as they are defined ([ the
146
+ “first win” algorithm] [ 1 ] ). If you want to sort media queries automatically,
147
+ pass ` sort: true ` to this module.
145
148
146
149
``` javascript
147
150
postcss ([
@@ -165,10 +168,10 @@ postcss([
165
168
]).process (css);
166
169
```
167
170
168
- In this example, all your queries will sort by A-Z order.
171
+ In this example, all your media queries will sort by A-Z order.
169
172
170
- This sorting function directly pass to ` Array#sort() ` method of an array of all
171
- your queries.
173
+ This sorting function is directly passed to ` Array#sort() ` method of an array of
174
+ all your media queries.
172
175
173
176
174
177
API
@@ -180,17 +183,16 @@ Packs media queries in `css`.
180
183
181
184
The second argument is optional. The ` options ` are:
182
185
183
- - [ options] [ 1 ] mentioned above
184
- - the second argument of [ PostCSS’s ` process() ` method] [ 2 ]
186
+ - [ options] [ 2 ] mentioned above
187
+ - the second argument of [ PostCSS’s ` process() ` method] [ 3 ]
185
188
186
189
You can specify both at the same time.
187
190
188
191
``` javascript
189
- var fs = require (" fs" );
190
- var mqpacker = require (" css-mqpacker" );
192
+ cosnt fs = require (" fs" );
193
+ const mqpacker = require (" css-mqpacker" );
191
194
192
- var css = fs .readFileSync (" from.css" , " utf8" );
193
- var result = mqpacker .pack (css, {
195
+ const result = mqpacker .pack (fs .readFileSync (" from.css" , " utf8" ), {
194
196
from: " from.css" ,
195
197
map: {
196
198
inline: false
@@ -203,11 +205,184 @@ fs.writeFileSync("to.css.map", result.map);
203
205
```
204
206
205
207
208
+ NOTES
209
+ -----
210
+
211
+ With CSS MQPacker, the processed CSS is always valid CSS, but you and your
212
+ website user will get unexpected results. This section explains how CSS MQPacker
213
+ works and what you should keep in mind.
214
+
215
+
216
+ ### CSS Cascading Order
217
+
218
+ CSS MQPacker changes rulesets’ order. This means the processed CSS will have an
219
+ unexpected cascading order. For example:
220
+
221
+ ``` css
222
+ @media (min-width : 640px ) {
223
+ .foo {
224
+ width : 300px ;
225
+ }
226
+ }
227
+
228
+ .foo {
229
+ width : 400px ;
230
+ }
231
+ ```
232
+
233
+ Becomes:
234
+
235
+ ``` css
236
+ .foo {
237
+ width : 400px ;
238
+ }
239
+
240
+ @media (min-width : 640px ) {
241
+ .foo {
242
+ width : 300px ;
243
+ }
244
+ }
245
+ ```
246
+
247
+ ` .foo ` is always ` 400px ` with original CSS. With processed CSS, however, ` .foo `
248
+ is ` 300px ` if viewport is wider than ` 640px ` .
249
+
250
+ This does not occur on small project. However, this could occur frequently on
251
+ large project. For example, if you want to override a CSS framework (like
252
+ Bootstrap) component declaration, your whole CSS code will be something similar
253
+ to above example. To avoid this problem, you should pack only CSS you write, and
254
+ then concaenate with a CSS framework.
255
+
256
+
257
+ ### The “First Win” Algorithm
258
+
259
+ CSS MQPacker is implemented with the “first win” algorithm. This means:
260
+
261
+ ``` css
262
+ .foo {
263
+ width : 10px ;
264
+ }
265
+
266
+ @media (min-width : 640px ) {
267
+ .foo {
268
+ width : 150px ;
269
+ }
270
+ }
271
+
272
+ .bar {
273
+ width : 20px ;
274
+ }
275
+
276
+ @media (min-width : 320px ) {
277
+ .bar {
278
+ width : 200px ;
279
+ }
280
+ }
281
+
282
+ @media (min-width : 640px ) {
283
+ .bar {
284
+ width : 300px ;
285
+ }
286
+ }
287
+ ```
288
+
289
+ Becomes:
290
+
291
+ ``` css
292
+ .foo {
293
+ width : 10px ;
294
+ }
295
+
296
+ .bar {
297
+ width : 20px ;
298
+ }
299
+
300
+ @media (min-width : 640px ) {
301
+ .foo {
302
+ width : 150px ;
303
+ }
304
+ .bar {
305
+ width : 300px ;
306
+ }
307
+ }
308
+
309
+ @media (min-width : 320px ) {
310
+ .bar {
311
+ width : 200px ;
312
+ }
313
+ }
314
+ ```
315
+
316
+ This breaks cascading order of ` .bar ` , and ` .bar ` will be displayed in ` 200px `
317
+ instead of ` 300px ` even if a viewport wider than ` 640px ` .
318
+
319
+ I suggest defining a query order on top of your CSS:
320
+
321
+ ``` css
322
+ @media (min-width : 320px ) { /* Wider than 320px */ }
323
+ @media (min-width : 640px ) { /* Wider than 640px */ }
324
+ ```
325
+
326
+ If you use simple ` min-width ` queries only, [ the ` sort ` option] [ 4 ] can help.
327
+
328
+
329
+ ### Multiple Classes
330
+
331
+ CSS MQPacker works only with CSS. This may break CSS applying order to an
332
+ elements that have multiple classes. For example:
333
+
334
+ ``` css
335
+ @media (min-width : 320px ) {
336
+ .foo {
337
+ width : 100px ;
338
+ }
339
+ }
340
+
341
+ @media (min-width : 640px ) {
342
+ .bar {
343
+ width : 200px ;
344
+ }
345
+ }
346
+
347
+ @media (min-width : 320px ) {
348
+ .baz {
349
+ width : 300px ;
350
+ }
351
+ }
352
+ ```
353
+
354
+ Becomes:
355
+
356
+ ``` css
357
+ @media (min-width : 320px ) {
358
+ .foo {
359
+ width : 100px ;
360
+ }
361
+ .baz {
362
+ width : 300px ;
363
+ }
364
+ }
365
+
366
+ @media (min-width : 640px ) {
367
+ .bar {
368
+ width : 200px ;
369
+ }
370
+ }
371
+ ```
372
+
373
+ The result looks good. However, if an HTML element has ` class="bar baz" ` and
374
+ viewport width larger than ` 640px ` , that element ` width ` incorrectly set to
375
+ ` 200px ` instead of ` 300px ` . This problem cannot be resolved only with CSS, so be
376
+ careful!
377
+
378
+
206
379
LICENSE
207
380
-------
208
381
209
382
MIT: http://hail2u.mit-license.org/2014
210
383
211
384
212
- [ 1 ] : #options
213
- [ 2 ] : https://github.com/postcss/postcss#source-map
385
+ [ 1 ] : #the-first-win-algorithm
386
+ [ 2 ] : #options
387
+ [ 3 ] : http://api.postcss.org/global.html#processOptions
388
+ [ 4 ] : #sort
0 commit comments