grid-kiss讓網格制作變得更容易
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目的
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"
}</code></pre>
在瀏覽器中將看到如下圖的效果:

如果你想立馬體驗的話,你可以通過 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:
yarn add postcss-grid-kiss --dev
npm:
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'));
});</code></pre>
其中最重要的,也是很關鍵的部分:
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 }) ])
fallback
截至2016年12月, CSS Grid布局規范 只是一個候選規范,并沒有得到廣泛的支持。到2017年3月,支持的瀏覽器會越來越多,Chrome和Firefox將開始默認支持Grid布局。其中,Mozilla將在3月7日發布的Firefox 52版本上開始支持。
那么grid-kiss提供了一個配置項 fallback 用來做瀏覽器降級處理。其默認值是 false ,如果把它設置為 true 。就會對CSS Grid做降級處理,通過 position 和 calc() 模擬網格布局,讓不支持CSS Grid的瀏覽器也能正常的訪問。
screwIE
這個選項是用來忽略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
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 ═╝ "
}
如何繪制網格
前面簡單的展示了繪制網格的方式。那么在實際繪制網格,可以依據下面幾點來操作:
- 繪制不同的區域,可以得到不同的網格。你可以使用一些工作來幫助你繪制網格,比如 AsciiFlow
- 在每個區寫一個CSS選擇器來匹配相應的元素。它可以是一個元素標簽、類名或ID選擇器或其他有效的選擇器
- 匹配的元素必須是網格元素的子元素
- 單獨的每一行由一個換行符( \n )來決定,而且每一行具有相同的縮進
- 每一行的開始和結束由一個雙引號( " )來控制
- 確定每個轉角是正確對齊,可以使用 + 來控制,然后另一個 + 表示創建新一列
更多的使用方式,這里就不一一闡述了,感興趣的可以查看插件提供的 使用文檔 。另外把對齊方式在這里展示一下:
水平對齊方式控制
justify-content: stretch
"+---+ +---+ +---+"
"| a | | b | | c |"
"+---+ +---+ +---+"
"+---+ +---+ +---+"
"| d | | e | | f |"
"+---+ +---+ +---+"
"+---+ +---+ +---+"
"| g | | h | | i |"
"+---+ +---+ +---+"

justify-content: start
"+---+ +---+ +---+ "
"| a | | b | | c | "
"+---+ +---+ +---+ "
"+---+ +---+ +---+ "
"| d | | e | | f | "
"+---+ +---+ +---+ "
"+---+ +---+ +---+ "
"| g | | h | | i | "
"+---+ +---+ +---+ "

justify-content:end
" +---+ +---+ +---+"
" | a | | b | | c |"
" +---+ +---+ +---+"
" +---+ +---+ +---+"
" | d | | e | | f |"
" +---+ +---+ +---+"
" +---+ +---+ +---+"
" | g | | h | | i |"
" +---+ +---+ +---+"

justify-content:center
" +---+ +---+ +---+ "
" | a | | b | | c | "
" +---+ +---+ +---+ "
" +---+ +---+ +---+ "
" | d | | e | | f | "
" +---+ +---+ +---+ "
" +---+ +---+ +---+ "
" | g | | h | | i | "
" +---+ +---+ +---+ "

justify-content: space-between
"+---+ +---+ +---+"
"| a | | b | | c |"
"+---+ +---+ +---+"
"+---+ +---+ +---+"
"| d | | e | | f |"
"+---+ +---+ +---+"
"+---+ +---+ +---+"
"| g | | h | | i |"
"+---+ +---+ +---+"

justify-content: space-evenly
" +---+ +---+ +---+ "
" | a | | b | | c | "
" +---+ +---+ +---+ "
" +---+ +---+ +---+ "
" | d | | e | | f | "
" +---+ +---+ +---+ "
" +---+ +---+ +---+ "
" | g | | h | | i | "
" +---+ +---+ +---+ "

justify-content:space-around
" +---+ +---+ +---+ "
" | a | | b | | c | "
" +---+ +---+ +---+ "
" +---+ +---+ +---+ "
" | d | | e | | f | "
" +---+ +---+ +---+ "
" +---+ +---+ +---+ "
" | g | | h | | i | "
" +---+ +---+ +---+ "

垂直對齊方式控制
align-content: stretch
"+---+ +---+ +---+"
"| a | | b | | c |"
"+---+ +---+ +---+"
"+---+ +---+ +---+"
"| d | | e | | f |"
"+---+ +---+ +---+"
"+---+ +---+ +---+"
"| g | | h | | i |"
"+---+ +---+ +---+"

align-content: start
"+---+ +---+ +---+"
"| a | | b | | c |"
"+---+ +---+ +---+"
"+---+ +---+ +---+"
"| d | | e | | f |"
"+---+ +---+ +---+"
"+---+ +---+ +---+"
"| g | | h | | i |"
"+---+ +---+ +---+"
" "
" "

align-content: end
" "
" "
"+---+ +---+ +---+"
"| a | | b | | c |"
"+---+ +---+ +---+"
"+---+ +---+ +---+"
"| d | | e | | f |"
"+---+ +---+ +---+"
"+---+ +---+ +---+"
"| g | | h | | i |"
"+---+ +---+ +---+"

align-content: center
" "
"+---+ +---+ +---+"
"| a | | b | | c |"
"+---+ +---+ +---+"
"+---+ +---+ +---+"
"| d | | e | | f |"
"+---+ +---+ +---+"
"+---+ +---+ +---+"
"| g | | h | | i |"
"+---+ +---+ +---+"
" "

align-content: space-between
"+---+ +---+ +---+"
"| a | | b | | c |"
"+---+ +---+ +---+"
" "
"+---+ +---+ +---+"
"| d | | e | | f |"
"+---+ +---+ +---+"
" "
"+---+ +---+ +---+"
"| g | | h | | i |"
"+---+ +---+ +---+"

align-content: space-evenly
" "
"+---+ +---+ +---+"
"| a | | b | | c |"
"+---+ +---+ +---+"
" "
"+---+ +---+ +---+"
"| d | | e | | f |"
"+---+ +---+ +---+"
" "
"+---+ +---+ +---+"
"| g | | h | | i |"
"+---+ +---+ +---+"
" "

align-content: space-around
" "
"+---+ +---+ +---+"
"| a | | b | | c |"
"+---+ +---+ +---+"
" "
" "
"+---+ +---+ +---+"
"| d | | e | | f |"
"+---+ +---+ +---+"
" "
" "
"+---+ +---+ +---+"
"| g | | h | | i |"
"+---+ +---+ +---+"
" "

區域內水平對齊方式
justify-self: start
使用 < 或 ← :
+-------------+ +-------------+
| .item-a < | or | .item-a ← |
+-------------+ +-------------+

justify-self: end
使用 > 或 → :
+-------------+ +-------------+
| > .item-a | or | → .item-a |
+-------------+ +-------------+

justify-self: stretch
使用 > 和 > 或 ← 和 → :
+--------------+ +--------------+
| < .item-a > | or | ← .item-a → |
+--------------+ +--------------+

justify-self:center
使用 > 和 < 或者 → 和 ← :
+--------------+ +--------------+
| > .item-a < | or | → .item-a ← |
+--------------+ +--------------+

區域內垂直對齊方式
align-self:start
使用 ^ 或者 ↑ :
+-------------+ +-------------+
| .item-a | or | .item-a |
| ^ | | ↑ |
+-------------+ +-------------+

align-self: end
使用 v 或 ↓ :
+-------------+ +-------------+
| v | or | ↓ |
| .item-a | | .item-a |
+-------------+ +-------------+

align-self: stretch
使用 ^ 和 v 或者 ↑ 和 ↓ :
+-------------+ +-------------+
| ^ | | ↑ |
| .item-a | or | .item-a |
| v | | ↓ |
+-------------+ +-------------+

align-self: center
使用 v 和 ^ 或者 ↓ 和 ↑ :
+-------------+ +-------------+
| v | | ↓ |
| .item-a | or | .item-a |
| ^ | | ↑ |
+-------------+ +-------------+

上面展示了網格內對齊方式,下面來實戰一下,看一個小示例:
.grid {
grid-kiss:
" +-------+ +-------+ +-------+ "
" | .a | | .b | | .c | "
" +-------+ +-------+ +-------+ "
" +-------+ +-------+ +-------+ "
" | .d | | .e | | .f | "
" +-------+ +-------+ +-------+ "
" +-------+ +-------+ +-------+ "
" | .g | | .h | | .i | "
" +-------+ +-------+ +-------+ "
" | 200px | | 200px | | 200px | "
}
示例效果如下圖所示:

grid-kiss中不足之處
上面演示了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可以有更多的玩法。如果你感興趣,你也可以玩出另類。(^_^)。
來自:http://www.w3cplus.com/preprocessor/keep-css-grids-simple-with-postcss-grid-kiss.html