去年在 CSS Conf 科普了一下《 CSS Grid Layout 》相关的概念。会后 PostCSS 的作者 @Andrey Sitnik 给我力荐 grid-kiss 这个PostCSS插件。说这个插件可以让CSS Grid变得更为简单。一直都想尝试一下,就是没动手,今天体验了一下,还是很有意思的。今天花点时间整理一下,跟大家一起分享。
在详细介绍这个插件之前,先简单的告诉大家,我们这里所说的Grid是CSS布局中的一个模块。它不是早前所说的网格系统(Grid system),而是CSS 布局自带的一个布局模块。这个模块被称为 CSS Grid ,也有人把其称为CSS原生网格。
如果你从未接触过CSS Grid相关的知识,建议你先阅读站上早前分享过的CSS Grid相关教程。特别推荐大家阅读这篇译文《CSS Grid布局指南》,如果你觉得译文质量不够好,你也可以移步阅读 @Chris House 写的原文《 A Complete Guide to CSS Grid Layout 》。
这里假设你已经对CSS Grid有了一定的基础了解,哪怕是最基础的知识。因为我们今天不是来介绍CSS Grid的基础知识,而是介绍如何使用PostCSS插件 grid-kiss 让制作网格变得更容易、更简单。如果你感兴趣的话,欢迎继续往下阅读。
grid-kiss是PostCSS万千 插件 中的一个,旨在用一个形象的网格(代码中画的网格)来取代CSS Grid自带的24个属性。简单的说,就是grid-kiss把在代码中画好的网格编译出CSS Grid对应的网格属性。
上面也说过了,grid-kiss是用来把画好的网格编译成CSS对应的网格属性。那究竟是怎么样的,先给大家看一个作者在Github提供的示例,让大家在脑海中有一个简单印象。
比如,在编译前的CSS代码中有这样一段代码:
body {
grid-kiss:
"+-------------------------------+ "
"| header ↑ | 120px"
"+-------------------------------+ "
" "
"+-- 30% ---+ +--- auto --------+ "
"| .sidebar | | main | auto "
"+----------+ +-----------------+ "
" "
"+-------------------------------+ "
"| ↓ | 60px "
"| → footer ← | "
"+-------------------------------+ "
}
经过PostCSS编译之后出来的CSS代码:
body > header {
grid-area: header;
align-self: start
}
body > .sidebar {
grid-area: sidebar
}
body > main {
grid-area: main
}
body > footer {
grid-area: footer;
justify-self: center;
align-self: end
}
body {
display: grid;
align-content: space-between;
grid-template-rows: 120px 1fr 60px;
grid-template-columns: 30% 1fr;
grid-template-areas:
"header header"
"sidebar main "
"footer footer"
}
在浏览器中将看到如下图的效果:
如果你想立马体验的话,你可以通过 playground 在线工具尝试一把。另外还可以在Codepen上看看 @jonathanneal 在Codepen上提供的 插件模板 。
如果grid-kiss和媒体查询结合在一起,可以轻易的实现响应式布局效果。如下图所示:
是不是很神奇,是不是没想到未来的CSS还可以这么的写。可以说,大家把CSS都给玩坏了。同时也能证明 @Sylvain 写的这个PostCSS插件是多么的强大,又是多有意思。
文章开头就说了grid-kiss是PostCSS的一个插件,如果你想要正常的使用这个插件,或者尝试玩一把另类的网格制作方式。那么本地就要有一个PostCSS的工作环境。当然了,如果你为了省事的话,你可以使用 playground 。这里还是说怎么在本地使用吧。
我个人喜欢使用PostCSS和Gulp配合使用,如果从没接触过PostCSS,也不用担心,你可以通过 PostCSS深入学习这个系列 中的《 PostCSS深入学习:Gulp设置 》一文配置好环境。接下来的内容假设你配置好PostCSS和Gulp的本地环境。
环境有了,咱们就来安装grid-kiss吧。你可以通过 yarn 或者 npm 的方式来进行安装。
yarn add postcss-grid-kiss --dev
npm install postcss-grid-kiss --save-dev
我采用的是后面这种方式安装的。安装完成后,需要在 gulpfile.js 做一些简单的配置:
var gridkiss = require('postcss-grid-kiss');
gulp.task('css', function(){
var processors = [
// autoprefixer(browserOptions),
cssnext(browserOptions),
gridkiss({
fallback: false,
screwIE: false,
optimizeCalc: false
})
];
return gulp.src('./src/*.css')
.pipe(postcss(processors))
.pipe(gulp.dest('./dest'));
});
其中最重要的,也是很关键的部分:
gridkiss({
fallback: false,
screwIE: false,
optimizeCalc: false
})
这三个是grid-kiss的配置选项。具体这几个选项是什么意思?稍后介绍。为了让你能本地更好的运行起来,可以把 gulpfile.js 和 package.json 保存到你项目的根目录下。同时建议你的测试项目结构如图那样:
这个时候打开命令终端,把路径切换到项目根目下,执行:
npm i
然后在命令终端执行 gulp 命令。这个时候 src/style.css (编译前的样式文件)就会编译到 dest/style.css (编译后的样式文件)。同时也表明你的环境是OK的。后面我们的样式都是在 src/style.css 中编辑。另外,你的命令终端不要关闭,这样你只要修改了 style.css 文件,保存之后, dest/style.css 就会自动更新。
前面的环境配置中也展示了,grid-kiss有三个选项,在使用的时候可以自行配置。
postcss([ gridkiss({ ...options }) ])
截至2016年12月, CSS Grid布局规范 只是一个候选规范,并没有得到广泛的支持。到2017年3月,支持的浏览器会越来越多,Chrome和Firefox将开始默认支持Grid布局。其中,Mozilla将在3月7日发布的Firefox 52版本上开始支持。 @meyerweb 也说 CSS Grid就要来了 !
那么grid-kiss提供了一个配置项 fallback 用来做浏览器降级处理。其默认值是 false ,如果把它设置为 true 。就会对CSS Grid做降级处理,通过 position 和 calc() 模拟网格布局,让不支持CSS Grid的浏览器也能正常的访问。
这个选项是用来忽略IE浏览器的降级处理,其默认值 false 。 screwIE 生效有一个条件,那就是 fallback 设置了 true 。
由于IE不支持 @supports ,所以grid-kiss需要通过添加一个特殊的媒体查询 @media screen and (min-width:/0) 只让IE识别。
如果你的项目不需要考虑IE浏览器,又为了减少编译出来的文件体积,你可以这样设置grid-kiss:
postcss([ gridkiss({ fallback: true, screwIE: true }) ])
optimizeCalc 默认值是 true 。主要用来尽可能简化 calc() 表达式。和 screwIE 类似,如果要让 optimizeCalc 生效,前提是 fallback 设置的值为 true 。
有关于grid-kiss这三个配置参数的详细介绍可以 点击原作者做的相关阐述 。
文章开头,看到的示例是通过中折线 - 和加号 + 来在文件中绘制网格。除此之外还有另外两种方式。
div {
grid-kiss:
"┌──────┐ ┌──────┐ "
"│ │ │ ↑ │ "
"│ │ │ bar →│ 200px "
"│ ↓ │ └──────┘ "
"│ baz │ - "
"│ ↑ │ ┌──────┐ "
"│ │ │ ↑ │ 200px "
"└──────┘ │ │ "
" │ foo │ - "
"┌──────┐ │ │ "
"│ qux │ │ ↓ │ 200px "
"│ ↓ │ │ │ "
"└─20em─┘ └──────┘ "
}
main {
grid-kiss:
"╔═══════╗ ╔════════════════╗ "
"║ ║ ║ .article ║ auto "
"║ ↑ ║ ╚════════════════╝ "
"║ nav ║ ╔════╗ ╔════════╗ "
"║ ║ ║ ║ ║ aside →║ 240px"
"╚═ 25% ═╝ ╚════╝ ╚═ 80em ═╝ "
}
前面简单的展示了绘制网格的方式。那么在实际绘制网格,可以依据下面几点来操作:
/n )来决定,而且每一行具有相同的缩进 " )来控制 + 来控制,然后另一个 + 表示创建新一列 更多的使用方式,这里就不一一阐述了,感兴趣的可以查看插件提供的 使用文档 。另外把对齐方式在这里展示一下:
"+---+ +---+ +---+" "| a | | b | | c |" "+---+ +---+ +---+" "+---+ +---+ +---+" "| d | | e | | f |" "+---+ +---+ +---+" "+---+ +---+ +---+" "| g | | h | | i |" "+---+ +---+ +---+"
"+---+ +---+ +---+ " "| a | | b | | c | " "+---+ +---+ +---+ " "+---+ +---+ +---+ " "| d | | e | | f | " "+---+ +---+ +---+ " "+---+ +---+ +---+ " "| g | | h | | i | " "+---+ +---+ +---+ "
" +---+ +---+ +---+" " | a | | b | | c |" " +---+ +---+ +---+" " +---+ +---+ +---+" " | d | | e | | f |" " +---+ +---+ +---+" " +---+ +---+ +---+" " | g | | h | | i |" " +---+ +---+ +---+"
" +---+ +---+ +---+ " " | a | | b | | c | " " +---+ +---+ +---+ " " +---+ +---+ +---+ " " | d | | e | | f | " " +---+ +---+ +---+ " " +---+ +---+ +---+ " " | g | | h | | i | " " +---+ +---+ +---+ "
"+---+ +---+ +---+" "| a | | b | | c |" "+---+ +---+ +---+" "+---+ +---+ +---+" "| d | | e | | f |" "+---+ +---+ +---+" "+---+ +---+ +---+" "| g | | h | | i |" "+---+ +---+ +---+"
" +---+ +---+ +---+ " " | a | | b | | c | " " +---+ +---+ +---+ " " +---+ +---+ +---+ " " | d | | e | | f | " " +---+ +---+ +---+ " " +---+ +---+ +---+ " " | g | | h | | i | " " +---+ +---+ +---+ "
" +---+ +---+ +---+ " " | a | | b | | c | " " +---+ +---+ +---+ " " +---+ +---+ +---+ " " | d | | e | | f | " " +---+ +---+ +---+ " " +---+ +---+ +---+ " " | g | | h | | i | " " +---+ +---+ +---+ "
"+---+ +---+ +---+" "| a | | b | | c |" "+---+ +---+ +---+" "+---+ +---+ +---+" "| d | | e | | f |" "+---+ +---+ +---+" "+---+ +---+ +---+" "| g | | h | | i |" "+---+ +---+ +---+"
"+---+ +---+ +---+" "| a | | b | | c |" "+---+ +---+ +---+" "+---+ +---+ +---+" "| d | | e | | f |" "+---+ +---+ +---+" "+---+ +---+ +---+" "| g | | h | | i |" "+---+ +---+ +---+" " " " "
" " " " "+---+ +---+ +---+" "| a | | b | | c |" "+---+ +---+ +---+" "+---+ +---+ +---+" "| d | | e | | f |" "+---+ +---+ +---+" "+---+ +---+ +---+" "| g | | h | | i |" "+---+ +---+ +---+"
" " "+---+ +---+ +---+" "| a | | b | | c |" "+---+ +---+ +---+" "+---+ +---+ +---+" "| d | | e | | f |" "+---+ +---+ +---+" "+---+ +---+ +---+" "| g | | h | | i |" "+---+ +---+ +---+" " "
"+---+ +---+ +---+" "| a | | b | | c |" "+---+ +---+ +---+" " " "+---+ +---+ +---+" "| d | | e | | f |" "+---+ +---+ +---+" " " "+---+ +---+ +---+" "| g | | h | | i |" "+---+ +---+ +---+"
" " "+---+ +---+ +---+" "| a | | b | | c |" "+---+ +---+ +---+" " " "+---+ +---+ +---+" "| d | | e | | f |" "+---+ +---+ +---+" " " "+---+ +---+ +---+" "| g | | h | | i |" "+---+ +---+ +---+" " "
" " "+---+ +---+ +---+" "| a | | b | | c |" "+---+ +---+ +---+" " " " " "+---+ +---+ +---+" "| d | | e | | f |" "+---+ +---+ +---+" " " " " "+---+ +---+ +---+" "| g | | h | | i |" "+---+ +---+ +---+" " "
使用 < 或 ← :
+-------------+ +-------------+ | .item-a < | or | .item-a ← | +-------------+ +-------------+
使用 > 或 → :
+-------------+ +-------------+ | > .item-a | or | → .item-a | +-------------+ +-------------+
使用 > 和 > 或 ← 和 → :
+--------------+ +--------------+ | < .item-a > | or | ← .item-a → | +--------------+ +--------------+
使用 > 和 < 或者 → 和 ← :
+--------------+ +--------------+ | > .item-a < | or | → .item-a ← | +--------------+ +--------------+
使用 ^ 或者 ↑ :
+-------------+ +-------------+ | .item-a | or | .item-a | | ^ | | ↑ | +-------------+ +-------------+
使用 v 或 ↓ :
+-------------+ +-------------+ | v | or | ↓ | | .item-a | | .item-a | +-------------+ +-------------+
使用 ^ 和 v 或者 ↑ 和 ↓ :
+-------------+ +-------------+ | ^ | | ↑ | | .item-a | or | .item-a | | v | | ↓ | +-------------+ +-------------+
使用 v 和 ^ 或者 ↓ 和 ↑ :
+-------------+ +-------------+ | v | | ↓ | | .item-a | or | .item-a | | ^ | | ↑ | +-------------+ +-------------+
上面展示了网格内对齐方式,下面来实战一下,看一个小示例:
.grid {
grid-kiss:
" +-------+ +-------+ +-------+ "
" | .a | | .b | | .c | "
" +-------+ +-------+ +-------+ "
" +-------+ +-------+ +-------+ "
" | .d | | .e | | .f | "
" +-------+ +-------+ +-------+ "
" +-------+ +-------+ +-------+ "
" | .g | | .h | | .i | "
" +-------+ +-------+ +-------+ "
" | 200px | | 200px | | 200px | "
}
示例效果如下图所示:
上面演示了grid-kiss制作CSS Grid。那么是不是就说grid-kiss就完全能编译出CSS Grid规范中对应中所有的属性呢?那么支持的属性有:
display:grid grid-template-columns grid-template-rows grid-template-areas justify-content align-content grid-area justify-self align-self 不支持的属性有:
grid-column-gap grid-row-gap grid-gap justify-items align-items grid-auto-columns grid-auto-rows grid-auto-flow grid grid-column-start grid-column-end grid-row-start grid-row-end grid-column grid-row 有关于这方面的详细介绍,可以 点击这里 。
如果你耐心的看到这里,那说明你对grid-kiss有所了解了。如果你跟着上面的一起操作过的话,那你对其有了更深入的了解。由于CSS Grid还没有得到很好的支持,不过这样尝试也不未尝不可。自己尝试下来,虽然它能更形象的帮助我们实现CSS Grid布局。但并不能说他就是万能的,比如说前面就提到过,这个插件还有很多CSS Grid对应的属性不支持。抛开这方面而言,在编辑器里绘制多格还是需要一定的时间,如果你是处女座,那有可能更纠结。另外如果你对CSS Grid的每个属性都非常的了解的话,使用手写属性制作网格有可能还是要比这个方式更快。
今天把这个抛出来,让大家体验一下另类的CSS玩法。特别是有了PostCSS之后,可以说,CSS可以有更多的玩法。如果你感兴趣,你也可以玩出另类。(^_^)。
常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《 图解CSS3:核心技术与案例实战 》。