• Stars
    star
    675
  • Rank 66,879 (Top 2 %)
  • Language
    JavaScript
  • Created almost 11 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Pack same CSS media query rules into one using PostCSS

CSS MQPacker

Pack same CSS media query rules into one using PostCSS

SYNOPSIS

A well componentized CSS file may have same media queries that can merge:

.foo {
	width: 240px;
}

@media screen and (min-width: 768px) {
	.foo {
		width: 576px;
	}
}

.bar {
	width: 160px;
}

@media screen and (min-width: 768px) {
	.bar {
		width: 384px;
	}
}

This tool packs exactly same media queries:

.foo {
	width: 240px;
}

.bar {
	width: 160px;
}

@media screen and (min-width: 768px) {
	.foo {
		width: 576px;
	}
	.bar {
		width: 384px;
	}
}

INSTALL

$ echo @hail2u:registry=https://npm.pkg.github.com >> .npmrc
$ npm install --save-dev @hail2u/css-mqpacker

If you or your team member does not have GitHub account, you can install directly from the GitHub repository:

$ npm install --save-dev github:hail2u/node-css-mqpacker#<TAG>

<TAG> should be replaced with one of the available tags.

USAGE

Of course, this package can be used as PostCSS plugin:

const fs = require("fs");
const postcss = require("postcss");

postcss([
	require("@hail2u/css-mqpacker")()
]).process(fs.readFileSync("from.css", "utf8")).then(function (result) {
	console.log(result.css);
});

It is a recommended way to use this tool.

As standard Node.js package

This package is also a Node.js module. For example, you can read from.css, process its content, and output processed CSS to STDOUT:

const fs = require("fs");
const mqpacker = require("@hail2u/css-mqpacker");

console.log(mqpacker.pack(fs.readFileSync("from.css", "utf8"), {
	from: "from.css",
	map: {
		inline: false
	},
	to: "to.css"
}).css);

As CLI Program

This package also installs a command line interface.

$ node ./node_modules/.bin/mqpacker --help
Usage: mqpacker [options] INPUT [OUTPUT]

Description:
  Pack same CSS media query rules into one using PostCSS

Options:
  -s, --sort       Sort “min-width” queries.
      --sourcemap  Create source map file.
  -h, --help       Show this message.
      --version    Print version information.

Use a single dash for INPUT to read CSS from standard input.

Examples:
  $ mqpacker fragmented.css
  $ mqpacker fragmented.css > packed.css

When PostCSS failed to parse INPUT, CLI shows a CSS parse error in GNU error format instead of Node.js stack trace.

The --sort option does not currently support a custom function.

OPTIONS

sort

By default, CSS MQPacker pack and order media queries as they are defined (the “first win” algorithm). If you want to sort media queries automatically, pass sort: true to this module.

postcss([
	mqpacker({
		sort: true
	})
]).process(css);

Currently, this option only supports min-width queries with specific units (ch, em, ex, px, and rem). If you want to do more, you need to create your own sorting function and pass it to this module like this:

postcss([
	mqpacker({
		sort: function (a, b) {
			return a.localeCompare(b);
		}
	})
]).process(css);

In this example, all your media queries will sort by A-Z order.

This sorting function is directly passed to Array#sort() method of an array of all your media queries.

API

pack(css[, options])

Packs media queries in css.

The second argument is optional. The options are:

You can specify both at the same time.

const fs = require("fs");
const mqpacker = require("@hail2u/css-mqpacker");

const result = mqpacker.pack(fs.readFileSync("from.css", "utf8"), {
	from: "from.css",
	map: {
		inline: false
	},
	sort: true,
	to: "to.css"
});
fs.writeFileSync("to.css", result.css);
fs.writeFileSync("to.css.map", result.map);

NOTES

With CSS MQPacker, the processed CSS is always valid CSS, but you and your website user will get unexpected results. This section explains how CSS MQPacker works and what you should keep in mind.

CSS Cascading Order

CSS MQPacker changes rulesets’ order. This means the processed CSS will have an unexpected cascading order. For example:

@media (min-width: 640px) {
	.foo {
		width: 300px;
	}
}

.foo {
	width: 400px;
}

Becomes:

.foo {
	width: 400px;
}

@media (min-width: 640px) {
	.foo {
		width: 300px;
	}
}

.foo is always 400px with original CSS. With processed CSS, however, .foo is 300px if viewport is wider than 640px.

This does not occur on small project. However, this could occur frequently on large project. For example, if you want to override a CSS framework (like Bootstrap) component declaration, your whole CSS code will be something similar to above example. To avoid this problem, you should pack only CSS you write, and then concatenate with a CSS framework.

The “First Win” Algorithm

CSS MQPacker is implemented with the “first win” algorithm. This means:

.foo {
	width: 10px;
}

@media (min-width: 640px) {
	.foo {
		width: 150px;
	}
}

.bar {
	width: 20px;
}

@media (min-width: 320px) {
	.bar {
		width: 200px;
	}
}

@media (min-width: 640px) {
	.bar {
		width: 300px;
	}
}

Becomes:

.foo {
	width: 10px;
}

.bar {
	width: 20px;
}

@media (min-width: 640px) {
	.foo {
		width: 150px;
	}
	.bar {
		width: 300px;
	}
}

@media (min-width: 320px) {
	.bar {
		width: 200px;
	}
}

This breaks cascading order of .bar, and .bar will be displayed in 200px instead of 300px even if a viewport wider than 640px.

I suggest defining a query order on top of your CSS:

@media (min-width: 320px) { /* Wider than 320px */ }
@media (min-width: 640px) { /* Wider than 640px */ }

If you use simple min-width queries only, the sort option can help.

Multiple Classes

CSS MQPacker works only with CSS. This may break CSS applying order to an elements that have multiple classes. For example:

@media (min-width: 320px) {
	.foo {
		width: 100px;
	}
}

@media (min-width: 640px) {
	.bar {
		width: 200px;
	}
}

@media (min-width: 320px) {
	.baz {
		width: 300px;
	}
}

Becomes:

@media (min-width: 320px) {
	.foo {
		width: 100px;
	}
	.baz {
		width: 300px;
	}
}

@media (min-width: 640px) {
	.bar {
		width: 200px;
	}
}

The result looks good. However, if an HTML element has class="bar baz" and viewport width larger than 640px, that element width incorrectly set to 200px instead of 300px. This problem cannot be resolved only with CSS, so be careful!

LICENSE

MIT

More Repositories

1

html-best-practices

For writing maintainable and scalable HTML documents
4,113
star
2

vim-css3-syntax

CSS3 syntax (and syntax defined in some foreign specifications) support for Vim's built-in syntax/css.vim
CSS
537
star
3

node-csswring

A CSS minifier for PostCSS
JavaScript
157
star
4

normalize.scss

Modularized and Sassy normalize.css
CSS
130
star
5

color-blindness-emulation

SVG filter collection that emulate 8 types of color blindness
HTML
107
star
6

drawic

A small set of SVG social icons
HTML
84
star
7

jquery.query-yql

Query YQL simply.
HTML
48
star
8

scss-partials

SCSS partials
CSS
41
star
9

roremu-ipusamu

ロレム・イプサムはそこそこ意味の通った英数字交じりの日本語の文章をCC0で登録・収集するプロジェクトです。主にウェブ・ページやウェブ・アプリケーション等のモックアップに使うことを想定しています。
33
star
10

hail2u.net-styles

Repository for tracking (or stalking) changes on CSS or Sassy CSS (SCSS) files for Hail2u.net.
CSS
33
star
11

jquery.table-filter

Insert a input form for filtering table rows dynamically.
JavaScript
28
star
12

jquery.highlight-search-terms

jQuery Plugin: Highlight Search Terms: Highlight search terms in referrer URL from Google, Yahoo!, Bing and custom site.
JavaScript
21
star
13

hail2u.net

The source files of Hail2u website
HTML
20
star
14

mn

The monospace fonts from the Google Fonts directory
HTML
19
star
15

google-code-prettify-language-handlers

Additional or modified language handlers for Google Code Prettify.
JavaScript
17
star
16

html-best-practices-ja-detailed

普通のHTMLの書き方: 保守しやすく、規模に依存しないHTML文書のために
HTML
16
star
17

node-gfmtoc

The GitHub flavored Markdown ToC generator.
JavaScript
15
star
18

jquery.harmonize-text

Change font-size of selected elements to harmonize text with their parent element.
JavaScript
13
star
19

grunt-css-mqpacker

Pack same media query rules into one media query rule using CSS MQPacker.
JavaScript
12
star
20

vim-css-syntax

Patched version of Vim's built-in `syntax/css.vim`.
Vim Script
8
star
21

node-edjo

Convert CSS file into Every Declaration Just Once format.
CSS
8
star
22

postcss-single-charset

A PostCSS plugin for popping first @charset rule up in CSS file
JavaScript
8
star
23

detect-font-loading

A JavaScript library for adding class name to `html` element when font loaded.
JavaScript
8
star
24

scss-functions

Drop-in but useless SCSS functions.
CSS
6
star
25

unutm

A JavaScript library for removing Urchin Traffic Monitor (UTM) parameters from URL
JavaScript
6
star
26

node-pit-ro

Read-only pit for Node.js.
JavaScript
5
star
27

hail2u.github.com

GitHub Pages of Kyo Nagashima.
HTML
5
star
28

bookmark-all

Firefox extension: Bookmark all opening tabs quickly without any dialog.
JavaScript
4
star
29

scss-column-equation

Generate variables for creating CSS column definition, the Sassy way.
CSS
4
star
30

h2u_colorscheme

gVim colorscheme: h2u_black, h2u_dark, and h2u_white.
Vim Script
4
star
31

postcss-fmt

Format a CSS file.
JavaScript
3
star
32

hail2u.net-weblog

Blosxom entry files for Weblog - Hail2u.net.
3
star
33

grunt-svg-rasterizer

Rasterize SVG file with Inkscape CLI.
JavaScript
3
star
34

grunt-selector4096

Warn if CSS file has more than equal 4096 selectors.
JavaScript
3
star
35

grunt-pubsubhubbub_publish

Publish a feed updates to Google PubSubHubbub hub.
JavaScript
3
star
36

jquery.xhashchange

jQuery Plugin: Add hashchange event to any browser
JavaScript
3
star
37

hail2u-ipsum

Generating dummy text from Hail2u website
JavaScript
3
star
38

grunt-long-url

Warn long URL in CSS files.
JavaScript
3
star
39

ufyu

blosxom plugin: Simple TXT-to-HTML coverter.
Perl
2
star
40

amp

Some old thoughts about AMP
2
star
41

abbread

Spreads a `title` attribute of an `abbr` element
JavaScript
2
star
42

vscode-color-scheme-for-windows-terminal

Bring VSCode Dark/Light theme to Windows Terminal
2
star
43

iine.hail2u.net

DISCONTINUED
HTML
2
star
44

postcss-round-float

A PostCSS plugin for rounding floating-point numbers in CSS file
JavaScript
2
star
45

context-style-switcher

Firefox extension: Change Page Style via context menu or toolbar button.
JavaScript
2
star
46

picks.hail2u.net

DISCONTINUED
CSS
1
star
47

grunt-rsync-ac

Run "rsync -aC --exclude-from=.rsyncignore".
JavaScript
1
star
48

node-dns-prefetch

Generate <link rel="dns-prefetch">s from URL.
JavaScript
1
star
49

vim-float-round

Round float numbers of current line.
Vim Script
1
star
50

node-git-release

Automatic release tool for Git
JavaScript
1
star
51

vim-tass-syntax

Vim syntax file for TASS
Vim Script
1
star
52

grunt-png2ico

Generate ICO file from multiple PNG files with ImageMagick.
JavaScript
1
star
53

node-inlining

Inline external CSS files referenced by link element to the HTML file
HTML
1
star
54

asamashi09

外部ドメインに置いたテンプレート・ファイルにより出力をカスタマイズすることができるPure JavaScriptなAmazonアソシエイト・ツール
JavaScript
1
star