本文作者:劉觀宇,360奇舞團高階前端工程師、技術經理,曾參加360導航、360影視、360金融、360遊戲等多個大型前端專案。關注W3C標準、IOT、人工智慧與機器學習的最新進展,W3C CSS工作組成員。
十年磨一劍,霜刃未曾試。今日把示君,誰有不平事。 —— 唐·賈島《劍客》
遊戲概況
Grid Garden1是Codepip2建立的一款寓教於樂的線上網頁遊戲,遊戲共有28關。玩家可以通過過關的方式掌握CSS最新標準CSS Grid。
遊戲的設定是一個花園種植胡蘿蔔的場景,玩家通過在程式碼區填寫CSS Grid的相關程式碼完成除草、澆水等任務。通過玩家的辛勤勞作,一定能夠吃上純天然、無公害的胡蘿蔔。
開啟遊戲,我們發現,遊戲存在多語言版。在左側底部就可以切換各種語言。事實上,筆者對自己的英語水平是非常有信心的,所以毫不猶豫的切換到——簡體中文版。
除了程式碼區和任務區,玩家可以在選關區選擇28關的任意一關來挑戰;當玩家在程式碼區敲入程式碼時候,右側的任務和結果展示區會實時根據程式碼展現結果。如果程式碼完成了任務,則點選提交按鈕,會進入下一關,如果玩家通關的話,則展示通關特效;如果程式碼不能完成任務,提交按鈕會灰掉。如果玩家硬來,程式碼區會有一個錯誤特效供玩家欣賞:-(
除了遊戲本身,遊戲的目的是加深玩家對CSS Grid的理解。說到CSS Grid,這可是一種強大的Web頁面佈局方式。恰當的使用CSS Grid,可以高效地解決很多常見的佈局問題,而且優雅、簡潔。完整的CSS Grid屬性參考,可查閱這裡3。由於CSS Grid標準尚屬CR(CR,Candidate Recommendation)階段,如果你是最新標準的愛好者,還可以跟進CSS工作組關於CSS Grid的最新進展4。
儘管如此,現在主流瀏覽器都已經有了不同程度的支援,支援度如下圖所示:
說到這裡,各位都迫不及待地想要在遊戲中一試身手了吧,那麼話不多說,Let's Go。
過關實錄
跟網格項玩耍
也許各位玩家完全沒有接觸過CSS Grid,剛剛進來可能會有些不知所措。我們姑且認為前面幾關是教學關。一般遊戲的教學關都會有一個人物在螢幕上蹦來蹦去外加叨逼叨來普及各種概念和操作。那麼筆者現在就來飾演一下這個人物。
- CSS Grid元素主要分為兩大類:
網格容器
和網格項
。網格容器
是父元素,網格項
是子元素。 - 對於
網格容器
和網格項
各有不同的屬性修飾。 - 宣告Grid佈局要做的事情是在
網格容器
的CSS程式碼中指定display: grid;
、display: inline-grid;
或者display: subgrid;
網格線
構成網格結構的分界線,是定位網格項的參照。下圖就是行row
和列column
的第一個網格線的位置。換句話說,對於一個每行有5列的網格,它的每一行總共有6個網格線
。如果這點看不清楚,那可能需要複習植樹問題了:-(
網格軌道
是指相鄰的網格線
之間的部分,下圖箭頭所指是一個網格軌道。
掌握了這些知識我們就可以開始過關之旅了。
第1關到第11關設定主要是針對網格項
屬性grid-column-start
和grid-column-end
展開的,相當的簡單,相信玩家一定可以很快的完成。
下面簡單總結一下第1-11關:
grid-column-start
和grid-column-end
作用於網格項
。- 上述值可配合使用來解決跨行跨列問題。
grid-column-start
和grid-column-end
中,start不一定比end小,逆向是被允許的。- 可以設定負值,負值的意思是從最後一個
網格線
算起的數值。 - 除了取數值外,還可以使用
span
關鍵字。格式是span <number>
意思是跨越多少個網格軌道
- 可以使用
grid-column: <start>/<end>
來簡寫,span
關鍵字適用此縮寫。
上面可能出錯的地方在於,設定數值時候,是確定網格線
的順序而非網格軌道
的順序,尤其是負數時候,而span
後面跟著的數字是網格軌道
的個數。只要牢記這點就很容易。
第12關與第13關,主要展示了CSS Grid在行row
上設定的能力,二維空間的設定是Grid佈局比flex
佈局擴充的一個方面。
這兩關也比較簡單。
從第14關開始,我們開始綜合運用行與列的屬性。 第14和15關的過關,需要靈活利用上述關鍵字。規範中還可以給軌道線命名,這裡暫時沒有遇到,我們先不使用“命名”這個利器。
第16關的意思是可以行列的簡寫方式,依然可以使用grid-area
屬性再次化簡,grid-area
接收4個由/
隔開的值,依次為:grid-row-start
, grid-column-start
, grid-row-end
, grid-column-end
。
第17關告訴我們,重迭覆蓋是不影響計算機制的。
依然很簡單,過。
針對17關的重疊,第18-19關引入了屬性關鍵字:order
,order
類似於z-index
,表明疊放順序,數值越大,越在上。允許負數。
很簡單是不是。
跟網格容器玩耍
上面我們對網格項
的“一波操作猛如虎”,下面我們再來看一看,對於網格容器
的操作,能不能“橫掃千軍我做主”。
第20關到第22關主要針對網格容器
的屬性grid-template-columns
和grid-template-rows
展開的。
下面簡單總結一下第20-22關:
grid-template-columns
和grid-template-rows
用於設定Grid佈局的行列中網格軌道
的大小- repeat函式可以簡化多個同值,格式為
repeat(N, value)
,其中N是個數,value是值。repeat可以與其他值混用,如:grid-template-columns: repeat(N-1, value) value
- 定義上述屬性時,允許長度單位混合使用。
第23-25關,主要說明了關鍵字fr
的使用。
下面總結一下第23-25關:
fr
是“分數”的英文單詞fraction
的簡寫。fr
用於等分等分網格容器剩餘空間。那麼fr
是怎麼分配空間的呢?舉個例子說明:設有A、B、C三個網格軌道
,他們的grid-template-columns
的設定依次是1fr
、2fr
和3fr
。那麼他們共同把一個行分為6等分,則A,B,C的空間就依次獲得了這一行的1/6、2/6和3/6。fr
是可以和其他單位混用的,如grid-template-columns: 1fr 50px 1fr 1fr;
。計算優先順序記住一點即可:除了auto
之外,先計算所有固定值(包括百分數)後,剩下的空間再計算fr
。
第26關介紹grid-template-rows
與前面的grid-template-columns
語法類似。留給玩家嘗試。
第27關介紹了grid-template-columns
與grid-template-rows
的簡寫方式grid-template
,寫法是:grid-template-rows
/ grid-template-columns
經歷了百轉千回,我們終於來到了關底,我們來看看大BOSS的尊容:
WTF?只能寫一行程式碼麼?
仔細想想:grid-template
最簡潔,格式是/
隔開的先行後列。
先解決行:需要把50px先分出去,後面100%給到花草。再解決列,列的場景是典型的fr
使用場景,雜草佔空間的1/5,胡蘿蔔佔4/5。
於是程式碼是:grid-template: 1fr 50px/1fr 4fr;
Bingo!恭喜你,通關成功!
結語
是的,我們已經最快速度領略了CSS Grid的風采。然而,對於整個的CSS Grid我們僅僅做了最常用的展示,更多的好玩的做法,還要等待大家的發掘,以及標準的演進。
文內連結
相關文章
致謝
感謝李鬆峰老師、高峰、劉博文對本文修訂提出的中肯意見。 設計師王旋美眉幫忙設計了精美的題圖。 在此誠摯的表示感謝。
關於奇舞週刊
《奇舞週刊》是360公司專業前端團隊「奇舞團」運營的前端技術社群。關注公眾號後,直接傳送連結到後臺即可給我們投稿。