css是英文Cascading Style Sheets的縮寫。 它是一種用來表現HTML(標準通用標記語言的一個應用)或XML(標準通用標記語言的一個子集)等檔案樣式的計算機語言。那麼如何搭建系統CSS架構呢,一起來學習學習!
搭建CSS法則
在專案開始的時候,我們談論了開發者關於他們的流程和痛點,並問他們的介面設計系統如何讓他們的工作量變簡單。
完成我的前端指導問卷,這些導致一系列前端規則和系統封裝。這裡有些我們建立的CSS具體規則。
模組化 —— 設計系統在每一個方面都是模組,這是非常實用寫CSS的方法。這在元件之間需要清晰分隔。
可讀性是關鍵 ——開發者必須在第一眼理解CSS程式碼,並且理解每一個選擇器的目的。
清晰勝過簡潔 —— 設計系統有時候看上去很冗長,但是作為交換,它提供清晰和韌性。保持CSS可讀性和可擴充套件性意味著犧牲簡潔的語法。
保持平面化 —— 長的選擇器要回避,無論什麼地方,儘可能保持CSS獨立DOM和模組化。
避免衝突 —— 因為元件會部署許多不同的應用,保證設計系統之間的CSS不會和其他的庫和系統有衝突,這很重要。通過系統空間命名Class名可以完成這個,更多的會在之後描述。
從這些規則中,我們搭建了制約和語法,包含了這些規則,以滿足開發者的需求。這裡有一個我們總結出的class語法:
全域性名稱空間
所有的Class都和設計系統關聯的都以全域性名稱空間為字首,這就是公司名稱後面加一個連體符
-
如果你工作的CSS框架是用於單個網站或者如果你對你的開發環境有絕對控制,那麼引入全域性名稱空間是不需要的。但是如果你的設計系統是混合的技術,那麼為系統特定程式碼建立一個標識是很重要的。作為第三方開發者,在多個環境中利用他們的系統,營銷團隊可能會失控,因此Lightning Design System引用了相似的方法到他們的系統之中(通過字首-),在我們的例子中,許多我們客戶的開發者使用Angular,因此他們已經很熟悉名稱空間的概念,因為Angular使用ng-作為名稱空間,為Angular特殊的程式碼。
Class字首
除了名稱空間,我們新增字首到每個Class,為了使之更加明顯,這個這個Class是做什麼的。下面是我們使用的類字首:
c- 用於UI元件,比如-c-card 或-c-header
l- 用於佈局相關樣式, 比爾-l-grid__item或-l--two-column
u- 用於公共部分, 比如-u-margin-bottom-double 或-u-margin-bottom-double
is- 和 has- 用於特定狀態, 比如-is-active或 -is-disabled. 適用於這些狀態為基礎的樣式。
js- 用於目標特定功能, 比如-modal-trigger. 這些class沒有繫結樣式; 他們只是為了行為而保留的. 對於大多數案例, 這些 js- 類將在元素上會切換基於狀態的類。
我被灌輸來自Harry Roberts的一個概念,並且一開始在我認為這有道理的同事,我還是持有質疑的態度的,僅僅因為這是額外的字元並且我認為字首會降低程式碼可讀性。然而我的想法是不對的。在實施類字首之後,我發現他們對於分清每個類的角色十分有幫助並且對於破譯一個應用的程式碼庫十分容易一目瞭然。對於設計系統使用者,這種清晰的程式碼能夠整理清楚頭緒,特別有用。
BEM語法
BEM 代表了“塊元素修飾”,這意味著:
Block 主要元件塊, 比如-c-card或者-c-btn
Element 是主要塊的一個子類,比如-c-card__title
Modifier 是一個元件樣式的各種變化, 比如-c-alert--error
這種方法論已經很受歡迎了,將這些概念和全域性名稱空間和類字首結合在一起,允許我們創造更明顯封裝的類名。
把它們都放到一起:解剖一個類
全域性名稱空間的結合,類別字首,和BEM語法引出了一個明確的.(是的,冗長的)類字元創,允許開發者們在構造UI的時候演繹他在之間扮演的角色。
讓我們檢查下以下的例子:
-c-btn--secondary
cn- 是來自設計系統的用於所有樣式的全域性名稱空間。
c- 是class的類別, 在案例中,c- 一位置“元件”
btn 是塊名(“Block(塊)” 就是BEM中的“B”)
--secondary 是一個修飾成分, 指向一個塊的變化多端的樣式 (“Modifier(修飾)” 就是BEM中的“M”)
這裡有另一個例子:
-l-grid__item
cn- 再一次出現就是系統的全域性名稱空間。
l- 是類的類別, 在這種情況下l- 意味著 “佈局”
grid 是塊名
__item 是一個元素, 表明那是塊中的一個分支(“Element”在BEM中指“E”)
還有一個:
-c-primary-nav__submenu
cn- 是系統的全域性名稱空間。
c- 是類的類別, 在這個例子中c- 意味著 “component”
primary-nav 是塊名
__submenu是一個元素, 指出他是塊的子元素 (“Element” 在BEM中是“E”)
此外,毫無疑問,這些類比大多數其他方法的類更加冗長,但是對於這種特殊的系統,這些約定很有意義。
其他技巧
明確細節
為了防止程式碼瓦解,我們詳細說明如何處理這麼多細小的細節,就像註釋、程式碼塊之間的空間距,tab還是space等等。感謝上天,Harry Roberts已經將一個極佳的綜合的資源整合在了一起,稱之為CSS Guidelines,對於這些型別的約定,這個作為我們的底線。我們梳理所有的程式碼並且標記出我們偏離Harry指出地方的計劃。
Sass父選擇器
我一直有個關於CSS的一個問題,是找出究竟在哪裡放一個規定的規則。如果我有一個主要的導航元件,我要把這些樣式放在頭部還是在部分的主要導航Sass?謝天謝地,Sass父元素原則器出現了,這允許我們把所有的元件特定的樣式放在一個根元素下:
-c-primary-nav {
/**
* Nav appearing in header
* 1) Right-align navigation when it appears in the header
*/
-c-header & {
margin-left: auto; /* 1 */
}}
這意味著,所有的主要導航樣式都可以在一個主導航Sass部分中找到,而不是將他們分成好幾個檔案。
Sass巢狀的明確規則
在Sass中巢狀可能十分方便,但是增加了糟糕輸出的危險,會有過長的選擇器字元創。我們遵循《盜夢空間》規則,巢狀永遠不超過3層。
牢記設計系統的CSS平坦規則,我們希望在下列情況中限制巢狀:
一個樣式塊修飾
媒體查詢
父元素選擇器
狀態
樣式塊裝飾 對於裝飾來說,如果規則只有幾行長度,裝飾塊可以被巢狀在父元素中,就像下面這樣:
-c-alert {
border: 1px solid gray;
color: gray;
/**
* 錯誤彈出
*/
&--error {
border-color: red;
color: red;
}}
由於&符號,這會編譯成:
-c-alert {
border: 1px solid gray;
color: gray;}-c-alert--error {
border-color: red;
color: red;}
對於長樣式塊,我們不會巢狀裝飾程式碼,因為這減少了程式碼的可讀性。
媒體查詢器
元件特定媒體查詢器能夠在元件塊中巢狀。
-c-primary-nav {
/* Base styles */
/**
* 1) On larger displays, convert to a horizontal list
*/
@media all and (min-width: 40em) {
display: flex;
}}
這個會被編譯成:
-c-primary-nav {
/* Base styles */}@media all and (min-width: 40em) {
-c-primary-nav {
display: flex;
}}
父元素選擇器
設計系統會充分使用Sass的父元素選擇器原理。這裡允許所有的給定元件的規則在一個地方維護。
-c-primary-nav {
/**
* Nav appearing in header
* 1) Right-align navigation when it appears in the header
*/
-c-header & {
margin-left: auto; /* 1 */
}}
這會被編譯成:
-c-header -c-primary-nav {
display: flex;}
cn-c-primary-nav所有樣式都會在一個地方找到,而不是分散在許多部分檔案之中。
狀態
元件的狀態必須包括在一個巢狀的元素之中。這包括了hover, focus,和active狀態:
-c-btn {
background: blue;
&:hover, &:focus {
background: red;
}}
這需要編譯為:
-c-btn {
background: blue;}-c-btn:hover, -c-btn:focus {
background: red;}
狀態同樣可以選用通用類的形式,比如is-和 has-:
-c-accordion__panel {
overflow: hidden;
max-height: 0;
&-is-active {
max-height: 40em;
}}
者會被編譯成:
-c-accordion__panel {
overflow: hidden;
max-height: 0;}-c-accordion__-is-active {
max-height: 40em;}
為了建立一個堅固的系統,將這些規則都放入一個地方中,給我們需要堅持的一些制約和規定。當我們遇到一些規定不是很明顯或者有多重解決方案的情況下,我們需要一次談話,討論如何處理這些問題,如果需要的話可以更新方針。