|
1 | 1 | # PostCSS Media Minmax |
2 | 2 |
|
3 | | ------ |
| 3 | +> 写简单优雅的 Media Queries! |
| 4 | +
|
| 5 | +Media Queries 中的 `min-width` 和 `max-width` 等属性非常容易混淆,每次看到他们,我都想哭。现在[新的规范](http://dev.w3.org/csswg/mediaqueries/#mq-min-max)中,可以使用更加直观的 `>=`或`<=` 替代 media queries 中的 min-/max- 前缀。 |
| 6 | + |
| 7 | +这是一个实现 CSS Media Queries Level 4 Polyfill 的插件,让你现在就可以使用这些特性,妈妈再也不用担心我记不住了,鹅妹子嘤! |
| 8 | + |
| 9 | + |
| 10 | +[English](README.md) |
4 | 11 |
|
5 | | -Media Queries min/max prefix shorthand |
| 12 | +----- |
6 | 13 |
|
7 | 14 |  |
| 15 | + |
| 16 | + |
| 17 | +## 安装 |
| 18 | + |
| 19 | + $ npm install postcss-media-minmax |
| 20 | + |
| 21 | +## 快速开始 |
| 22 | + |
| 23 | +示例 1: |
| 24 | + |
| 25 | +```js |
| 26 | +var fs = require('fs') |
| 27 | +var postcss = require('postcss') |
| 28 | +var minmax = require('postcss-media-minmax') |
| 29 | + |
| 30 | +var css = fs.readFileSync('input.css', 'utf8') |
| 31 | + |
| 32 | +var output = postcss() |
| 33 | + .use(minmax()) |
| 34 | + .process(css) |
| 35 | + .css |
| 36 | + |
| 37 | +console.log('\n====>Output CSS:\n', output) |
| 38 | +``` |
| 39 | + |
| 40 | +或者只需: |
| 41 | + |
| 42 | +```js |
| 43 | +var output = postcss(minmax()) |
| 44 | + .process(css) |
| 45 | + .css |
| 46 | +``` |
| 47 | + |
| 48 | +input.css: |
| 49 | + |
| 50 | +```css |
| 51 | +@media screen and (width >= 500px) and (width <= 1200px) { |
| 52 | + .bar { |
| 53 | + display: block; |
| 54 | + } |
| 55 | +} |
| 56 | +``` |
| 57 | + |
| 58 | +你将得到: |
| 59 | + |
| 60 | +```css |
| 61 | +@media screen and (min-width: 500px) and (max-width: 1200px) { |
| 62 | + .bar { |
| 63 | + display: block; |
| 64 | + } |
| 65 | +} |
| 66 | +``` |
| 67 | + |
| 68 | +## CSS 语法 |
| 69 | + |
| 70 | +``` |
| 71 | +<mf-range> = <mf-name> [ '<' | '>' ]? '='? <mf-value> |
| 72 | + | <mf-value> [ '<' | '>' ]? '='? <mf-name> |
| 73 | + | <mf-value> '<' '='? <mf-name> '<' '='? <mf-value> |
| 74 | + | <mf-value> '>' '='? <mf-name> '>' '='? <mf-value> |
| 75 | +``` |
| 76 | + |
| 77 | + |
| 78 | +## 如何使用 |
| 79 | + |
| 80 | +### 简写 |
| 81 | + |
| 82 | +示例 1中同一个 feature name 同时存在 `>=` 和 `<=` 时,可以简写为: |
| 83 | + |
| 84 | +```css |
| 85 | +@media screen and (500px <= width <= 1200px) { |
| 86 | + .bar { |
| 87 | + display: block; |
| 88 | + } |
| 89 | +} |
| 90 | +/* 或者 */ |
| 91 | +@media screen and (1200px >= width >= 500px) { |
| 92 | + .bar { |
| 93 | + display: block; |
| 94 | + } |
| 95 | +} |
| 96 | +``` |
| 97 | + |
| 98 | +都会得到一样的输出结果: |
| 99 | + |
| 100 | +```css |
| 101 | +@media screen and (min-width: 500px) and (max-width: 1200px) { |
| 102 | + .bar { |
| 103 | + display: block; |
| 104 | + } |
| 105 | +} |
| 106 | +``` |
| 107 | +**注意**:当 feature name 在中间的时候,一定要保证两个 `<=` 或 `>=` 的方向一致,否则不会转换。 |
| 108 | + |
| 109 | +例如在下面的示例中,width 大于等于 500px 同时又大于等于 1200px,这在语法和逻辑上都是错误的。 |
| 110 | + |
| 111 | +```css |
| 112 | +@media screen and (1200px <= width >= 500px) { |
| 113 | + .bar { |
| 114 | + display: block; |
| 115 | + } |
| 116 | +} |
| 117 | +``` |
| 118 | + |
| 119 | +### 支持的 feature name |
| 120 | + |
| 121 | +规范中目前以下属性支持 min-/max 前缀,PostCSS Media Minmax 全部支持自动转换。 |
| 122 | + |
| 123 | +* `width` |
| 124 | +* `height` |
| 125 | +* `device-width` |
| 126 | +* `device-height` |
| 127 | +* `aspect-ratio` |
| 128 | +* `device-aspect-ratio` |
| 129 | +* `color` |
| 130 | +* `color-index` |
| 131 | +* `monochrome` |
| 132 | +* `resolution` |
| 133 | + |
| 134 | + |
| 135 | + |
| 136 | +### 支持在 `@custom-media` 中使用 & Node Watch |
| 137 | + |
| 138 | +```js |
| 139 | +var fs = require('fs') |
| 140 | +var chokidar = require('chokidar') |
| 141 | +var postcss = require('postcss') |
| 142 | +var minmax = require('minmax') |
| 143 | +var customMedia = require('postcss-custom-media') |
| 144 | + |
| 145 | +var src = 'input.css' |
| 146 | + |
| 147 | +console.info('Watching…\nModify the input.css and save.') |
| 148 | + |
| 149 | + |
| 150 | +chokidar.watch(src, { |
| 151 | + ignored: /[\/\\]\./, |
| 152 | + persistent: true |
| 153 | +}).on('all', |
| 154 | + function(event, path, stats) { |
| 155 | + var css = fs.readFileSync(src, 'utf8') |
| 156 | + var output = postcss() |
| 157 | + .use(customMedia()) |
| 158 | + .use(minmax()) |
| 159 | + .process(css) |
| 160 | + .css; |
| 161 | + fs.writeFileSync('output.css', output) |
| 162 | + }) |
| 163 | + |
| 164 | +``` |
| 165 | + |
| 166 | + |
| 167 | +input.css: |
| 168 | + |
| 169 | +```css |
| 170 | +@custom-media --foo (width >= 20em) and (width <= 50em); |
| 171 | +@custom-media --bar (height >= 300px) and (height <= 600px); |
| 172 | + |
| 173 | +@media (--foo) and (--bar) { |
| 174 | + |
| 175 | +} |
| 176 | +``` |
| 177 | + |
| 178 | +output.css: |
| 179 | + |
| 180 | +```css |
| 181 | +@media (min-width: 20em) and (max-width: 50em) and (min-height: 300px) and (max-height: 600px) { |
| 182 | + |
| 183 | +} |
| 184 | +``` |
| 185 | + |
| 186 | +### Grunt |
| 187 | + |
| 188 | +```js |
| 189 | +module.exports = function(grunt) { |
| 190 | + grunt.initConfig({ |
| 191 | + pkg: grunt.file.readJSON('package.json'), |
| 192 | + postcss: { |
| 193 | + options: { |
| 194 | + processors: [ |
| 195 | + require('autoprefixer-core')({ browsers: ['> 0%'] }).postcss, //Other plugin |
| 196 | + require('postcss-media-minmax')(), |
| 197 | + ] |
| 198 | + }, |
| 199 | + dist: { |
| 200 | + src: ['src/*.css'], |
| 201 | + dest: 'build/grunt.css' |
| 202 | + } |
| 203 | + } |
| 204 | + }); |
| 205 | + |
| 206 | + grunt.loadNpmTasks('grunt-contrib-uglify'); |
| 207 | + grunt.loadNpmTasks('grunt-postcss'); |
| 208 | + |
| 209 | + grunt.registerTask('default', ['postcss']); |
| 210 | +} |
| 211 | +``` |
| 212 | + |
| 213 | +### Gulp |
| 214 | + |
| 215 | +```js |
| 216 | +var gulp = require('gulp'); |
| 217 | +var rename = require('gulp-rename'); |
| 218 | +var postcss = require('gulp-postcss'); |
| 219 | +var selector = require('postcss-media-minmax') |
| 220 | +var autoprefixer = require('autoprefixer-core') |
| 221 | + |
| 222 | +gulp.task('default', function () { |
| 223 | + var processors = [ |
| 224 | + autoprefixer({ browsers: ['> 0%'] }), //Other plugin |
| 225 | + minmax() |
| 226 | + ]; |
| 227 | + gulp.src('src/*.css') |
| 228 | + .pipe(postcss(processors)) |
| 229 | + .pipe(rename('gulp.css')) |
| 230 | + .pipe(gulp.dest('build')) |
| 231 | +}); |
| 232 | +gulp.watch('src/*.css', ['default']); |
| 233 | +``` |
| 234 | + |
| 235 | + |
| 236 | +## 贡献 |
| 237 | + |
| 238 | +* 安装相关的依赖模块。 |
| 239 | +* 尊重编码风格(安装 [EditorConfig](http://editorconfig.org/))。 |
| 240 | +* 在[test](test)目录添加测试用例。 |
| 241 | +* 运行测试。 |
| 242 | + |
| 243 | +``` |
| 244 | +$ git clone https://github.com/postcss/postcss-media-minmaxs.git |
| 245 | +$ git checkout -b patch |
| 246 | +$ npm install |
| 247 | +$ npm test |
| 248 | +``` |
| 249 | + |
| 250 | +## 致谢 |
| 251 | + |
| 252 | +* 感谢 PostCSS 作者 [Andrey Sitnik](https://github.com/ai),带给我们如此简单易用的 CSS 语法解析工具。 |
| 253 | +* 感谢 [Tab Atkins Jr.](http://xanthir.com/contact/) 辛苦编写了 Media Queries Level 4 规范。 |
| 254 | +* 感谢 [@紫云飞](http://weibo.com/p/1005051708684567) 对本插件的建议和帮助。 |
| 255 | + |
| 256 | +## [Changelog](CHANGELOG.md) |
| 257 | + |
| 258 | +## [License](LICENSE) |
0 commit comments