1. 程式人生 > >完美CSS文檔的8個最佳實踐

完美CSS文檔的8個最佳實踐

風格 產品經理 sta war support display 主題 ucd 發生

在css的世界,文檔沒有被得到充分的利用。由於文檔對終端用戶不可見,因此它的價值常常被忽視。另外,如果你第一次為css編寫文檔,可能很難確定哪些內容值得記錄,以及如何能夠高效完成編寫。

然而,為CSS編寫文檔可以為你的項目提供很多好處:促進更好的代碼實踐、降低新員工的上手難度。在本文中,我將說明編寫CSS文檔的優點,並分享我認為的最佳實踐。讓文檔為你工作,而不是阻礙你的工作。

1. 制定基本規則

當你和你的團隊不清楚CSS文檔具體需要編寫哪些內容、文檔應該如何工作時,你很難跟上編寫CSS文檔的潮流。因此,第一步是約定好你將使用哪些規則以及如何執行它們。你可以在一個動態文檔中記錄這些內容,這樣團隊中的每個人都能夠參與其中。通過動態記錄,當你的規則發生改變或增加內容時,你可以保持文檔及時更新。一個共享的谷歌文檔,你自己代碼文檔的wiki頁面,或者(甚至更好)你自己的“實時樣式指南”頁面都是很好的放置文檔的地方。

現在讓我們看看你可以實際設置哪些“基本規則”。

2. 說明代碼庫的結構

了解代碼是如何組織的,能夠讓任何人在第一天就上手代碼。一個實現的簡單方法是創建一個文件結構的映射文件,你可以在其中介紹文件都包含哪些內容以及去哪兒找到這些內容。這樣做時要特別註意那些可能有歧義的地方。例如,標註“button.css”文件裏包含buttons的樣式並沒有很大幫助,但是指出“custom”文件夾是項目自定義樣式所在的位置,則可以為閱讀的人節省時間。

下面是個例子:

project root
└── srs
├── styles // 基本樣式,放在這裏的樣式應該在應用的任何地方都可用
├── bootstrap-custom // 覆蓋基礎樣式的自定義樣式
├── custom // 應用的自定義樣式
├── demos // 演示樣式和交互的示例
├── fonts
├── img // 只在樣式表中使用的圖片
├── variables // 自定義主題中使用的變量
└── styles.less // 導入所有基本樣式
└── components
├── alerts
└── alert.less // alert組件的自定義樣式。每個組件都有自己的樣式表,可以定制它,防止代碼臃腫和樣式泄露

如果你想要覆蓋由Bootstrap定義的樣式,那麽:

  1. 找出在Bootstrap框架中定義樣式的樣式表。

  2. 進入“src/styles/bootstrap-custom”。

  3. 查找相同的樣式表。

  4. 如果不存在,請在該目錄中創建一個相同名稱的新樣式表。

  5. 加上你重寫樣式的代碼,並註釋出重要的內容。

  6. 最後,在“src/styles/style.less”中導入新的樣式。

場景 #2

如果你想要添加一個新樣式,該樣式不會覆蓋Bootstrap原有樣式,並且在應用的任何地方都要能引用到它,那麽:

  1. 進入“src/styles/custom”。

  2. 找到一個可以添加該樣式的樣式表(請思考:這是特定的定義一個按鈕的樣式,還是可以復用的樣式?),並將其放到最合適的地方。

  3. 如果現有的樣式表都不適合加上這個新樣式,那麽就新建一個樣式表。

  4. 按照我們的命名規則來命名它。

  5. 添加你的新樣式並註釋出重要的內容。

  6. 最後,在“src/styles/style.less”中導入新的樣式。

場景 #3

如果你想為一個組件增加一個新樣式(這意味著只有這個組件會用到這個新樣式,無論該組件是應用在什麽地方用到的),那麽:

  1. 進入“src/components”。

  2. 找到你想要寫樣式的組件。

  3. 在這個組件的路徑下找到改組件的樣式表。

  4. 最後,在該樣式表中添加你的新樣式並註釋出重要的內容。

這個指南:

  • 幫助我們有條理地組織樣式。

  • 按照新樣式的繼承性質,新樣式能夠保持有效,因為我們在正確的地方重寫的樣式。

  • 避免開發人員編寫過於復雜的樣式。

  • 避免樣式影響到非目標元素。

3. 建立你的編碼標準

你的編碼標準或者CSS樣式指南是指你的團隊就編寫CSS達成的一致意見。這包括編寫代碼的最佳實踐,如格式化、命名規則和語法約定。下面是我認為值得分享的幾個有用方法:

不要做 vs 要做 列表

使用這種格式指出你需要避免的事情,並提供一個可行的替代方案。這可以消除歧義並鼓勵人們去做一件具體的事。例如:

不要做要做

不要使用tab進行縮進。

要用四個空格進行縮進。

不要用下劃線_或“駝峰法”來命名類或者ID。

要用破折號分隔單詞。

不要用類或ID名來反映底層標記結構。.container-span 和 .small-header-div 是不好的名字。

要從對象的角度考慮CSS,並使用簡單的名次作為名稱。.global-alert 和 .badge是好的名字。

不要用ID或過於特定的選擇器來寫樣式。只有在絕對必要的時候才使用它們(如表單控制或頁面錨定)。

要用類來寫樣式,從而增加可復用性,減少CSS選擇器沖突。

最佳實踐列表

將你的指導原則總結為最佳實踐,並舉例說明。這會讓大家更容易閱讀和理解。例如:

最佳實踐舉例

在不同的行上寫多個選擇器。

.btn,

.btn-link {

}

在選擇器和左括號之間間隔一個空格。

.selector {

}

盡可能使用十六進制值的簡寫。

#fff vs #ffffff

用小寫字母寫十六進制值。

#3d3d3d vs #3D3D3D

將url放在單引號中。通常單引號要優於雙引號,因為它更容易鍵入。

url (‘/image.png’) vs url (“/image.png”)

除了角度(deg)和時間(s或ms)之外,不要為0值寫單位。

margin-right: 0; vs margin-right: 0px;

不同開發人員寫代碼的方式可能差別很大。這就是為什麽團隊制定編碼標準很重要。這確保了代碼在項目中是一致的,這使得閱讀、編寫和審查變得更加容易。但是請確保你在編碼標準中包含的任何內容都是團隊同意的實踐。

我曾經做過一個項目,在這個項目的動態樣式指南中實踐了上面的內容。作為代碼的一部分,我們會提交上傳這些最佳實踐。然後為了確保大家都能看到這些內容,在合並代碼之前,團隊中的每個人都要拉取這些內容。這保證了每個人都有時間來審查和討論這些實踐。

4. 避免冗長的樣式表

當你把樣式分解為更小、更集中的樣式表時,更容易為它們寫文檔。這樣也可節省時間,因為你不用為拆解到一目了然的樣式表寫文檔。

例如,相較於用一個800行的樣式表來包含所有的樣式類型,你可以為每種樣式類型寫一個文件。這樣可以節省時間,因為你不必在一個文件中上下滾動來查找某些內容,在每次添加或重命名一個新部分時,也不必每次更新索引。

在一個長文件中,一個長索引……

   \*-------------------------------------------*/
variables.less


Index
- Color Palette
- Typography
- Buttons
- Forms
- Layout
- Messaging & Status
- General
- Navigation
- Carousel
- Jumbotron
\*-------------------------------------------*/

拆分文件,不再需要索引: 技術分享圖片

在大型應用中工作時可以參考的另一個示例是modlet workflow https://css-tricks.com/key-building-large-javascript-apps-modlet-workflow/。它解釋了為什麽使用較小文件可以更容易地在應用程序中測試和組裝它們。

5.利用約定的樣式指南編寫CSS文檔

寫好CSS編寫文檔的一個重要原因是寫好的CSS樣式,反之亦然。這意味著即使你的CSS代碼庫不是最好的,執行文檔規則也可以使你朝著更好的系統前進。

這就是說我們需要用約定的樣式指南來編寫CSS文檔。這背後的理念是,樣式指南可以幫助你確定良好的CSS結構,為了創建良好的結構你需要區分:

  • 定義應用外觀和感覺的基礎樣式(包括你正在使用的任何CSS框架)

  • 為特定組件寫的自定義樣式

  • 為特定頁面寫的自定義樣式

技術分享圖片

CSS的大部分應該由基礎樣式組成,因為它們在應用程序中的任何地方都可用,並且影響到處於默認狀態的所有元素。自定義樣式應該在你添加具有特定外觀和行為的組件時才寫,或者在頁面中某個元素或組件的布局需要特殊處理的情況下才寫。

描述這個特定的設置如何在您的應用程序中工作的一個很好的方法,就是創建一個樣式指南站點地圖。一旦你了解樣式指南在應用程序中的樣子,就可以利用約定的樣式指南來為元素編寫文檔。例如,如果你已經在樣式指南中定義了按鈕和導航的外觀,那麽就很明確應該在哪裏為它們添加新的樣式和文檔(在“buttons.css”和“Navs.css”中)。但是對於用按鈕組成的導航呢?

有一個樣式指南可以幫助你做出這個決定,你可以從展示和使用標簽的角度來比較按鈕和導航的外觀。

技術分享圖片

<button type="button" class="btn btn-primary">Primary</button>
<button type="button" class="btn btn-secondary">Secondary</button>
<button type="button" class="btn btn-emphasis">Emphasis</button>
<button type="button" class="btn btn-primary disabled">Primary</button>
<button type="button" class="btn btn-secondary disabled">Secondary</button>
<button type="button" class="btn btn-emphasis disabled">Emphasis</button>

技術分享圖片

  < ul class="nav nav-tabs" > 
< li class="active">< a href="#" >Active< /a >< /li >
< li >< a href="#" >Nav Item< /a >< /li >
< li >< a href="#" >Nav Item< /a >< /li >
< li class="disabled ">< a href="#" >Nav Item< /a >< /li >
< /ul >

在這個例子中,CSS有兩個點來定義按鈕組成的導航:

  1. 如果標簽遵循導航的結構,使用帶鏈接的列表,或者是看起來像按鈕的帶連接的< nav >標簽,那麽將導航樣式添加到“navs.css”。

  2. 如果你使用的標簽是< button >,那麽將樣式添加到“buttons.css”中。你甚至可以將它添加為單獨的樣式表(如“buttons-groupp.css”)。在這種情況下,“導航”一詞將不再合適,因為HTML按鈕作為導航項可訪問性較低。

6.將你的樣式表分成幾個部分

一旦你將樣式表分解成更易於管理的小文件,那麽你還可以通過將每個樣式分解為各個單獨的部分來繼續這一練習。

首先,每個樣式表至少應該包括一個標題和簡短的描述(如果有用)。標題可以與文件名一樣簡單,首字母大寫以便更像標題(例如:樣式表“buttons.css”的標題可以是“Buttons”),也可以與文件名相同,如下所示:

 /**
* icons.css
*/
.icon {
font-family: ‘bitovi‘;
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
}

在瀏覽器調試代碼的時候,使用文件名寫標題特別有用。在大多數情況下,文件已經和其他文件一起編譯了,我可以根據標題找到相關樣式寫在哪個文件中。

另外請註意,我所使用的註釋樣式是用/*開頭而不是/。這是一個在JSDoc中使用的慣例,用來解析應該包含在自動生成文檔中的註釋。我建議使用這種風格,因為許多在使用的樣式指南生成器使用JSDoc格式,當你準備使用生成器時,你的代碼將需要很少的額外改動。

無論如何,你可以使用其他樣式來註釋一段代碼,例如:

/*-------------------------------------------*\
icons.css
\*-------------------------------------------*/
.icon {
font-family: ‘bitovi‘;
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
}

在某種程度上,這取決於你的團隊認為什麽樣式最能使一段代碼脫穎而出。唯一的要求是在開始的時候使用/ ,在結束時使用 /。真正重要的是,無論使用哪種方法,都要堅持使用它,並在CSS代碼中貫徹使用。

如果你覺得一段描述在特定的樣式表中很有用,你可以添加它作為第一個註釋的一部分。例如:

/**
* icons.css
*
* 圖標應該以簡單而有意義的方式傳達它們所代表的功能的概念。
* 當設計新的圖標時,一定要消除任何復雜的內容,並遵循圖標集的線性和輕量級外觀。
*
*/
.icon {
font-family: ‘bitovi‘;
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
}

這樣做會加強把代碼拆分成幾個小部分的想法。此外,試著將描述分解成多行(Harry Roberts推薦最多80個字符),這樣在打開多個文件或在Github上閱讀時更容易閱讀。

在添加了標題和描述之後,你可以更進一步,將樣式表中的樣式劃分為幾個部分。要做到這一點,請考慮如何從邏輯上解釋樣式表的內容。例如,樣式表“buttons.css”通常會有一部分內容,通過.btn類名來定義按鈕的默認樣式。然後將有更多的樣式定義不同的顏色、大小和結構,可以結合起來進一步定制按鈕的外觀和行為。把每一種樣式單獨放在一小節中將讓你更容易理解和找到新樣式或覆蓋樣式應該放在哪兒。此外,當代碼以片段形式顯示時,查看文件並不那麽可怕,而在一個很難分辨樣式是從哪裏開始、到哪兒結束的長文件中,查找內容是很可怕的事。

讓我們來看個比較的例子。首先,一個沒有分段的代碼塊:

.label-condensed-variant(@color) {
&:before {
background-color: @color;
}
}
.label {
border-radius: 0;
font-family: @font-family-bold;
font-size: 85%;
position: relative;
&.label--condensed {
font-size: @font-size-xsmall;
color: @gray;
background: transparent;
padding-right: @padding-small;
&.label--primary {
.label-condensed-variant(@label-primary-bg);
}
&.label--success {
.label-condensed-variant(@label-success-bg);
}
&.label--info {
.label-condensed-variant(@label-info-bg);
}
&.label-warning {
.label--condensed-variant(@label-warning-bg);
}
&.label--danger {
.label-condensed-variant(@label-danger-bg);
}
}
&.label--simple {
font-family: @font-family-base;
font-size: @font-size-xsmall - 1;
color: @gray;
border: 1px solid @gray-light;
padding: 2px;
border-radius: @border-radius-small;
text-transform: uppercase;
}
}

接下來是同樣的代碼塊進行了分段處理:

/**
* bootstrap-custom/_labels.less 標簽
*
* 覆蓋由bootstrap框架定義的默認樣式。
*
*/
.label {
border-radius: 0;
font-family: @font-family-bold;
font-size: 85%;
position: relative;
}
/**
* 簡明標簽
*
* 修改標簽以提供帶有彩色圓圈的較小和較窄的版本,以便在空間較小的區域使用(例如,在列表視圖中)。
*/
.label {
&.label--condensed {
font-size: @font-size-xsmall;
color: @gray;
background: transparent;
padding-right: @padding-small;
}
}
/**
* 簡明標簽 - 顏色
*/
.label-condensed-variant(@color) { // 用變量來設置圓的顏色
&:before {
padding: 0px; max-width: 100%; box-sizing: border-box !important; word-wrap: inherit !important; font-size: inherit; line-height: inherit; color: rgb(91, 218, 237); word-break: inherit !important; white-space: inherit !important;">@color;
}
}
.label {
&.label--condensed {
&.label--primary {
.label-condensed-variant(@label-primary-bg);
}
&.label--success {
.label-condensed-variant(@label-success-bg);
}
&.label--info {
.label-condensed-variant(@label-info-bg);
}
&.label--warning {
.label-condensed-variant(@label-warning-bg);
}
&.label--danger {
.label-condensed-variant(@label-danger-bg);
}
}
}
/**
* 簡單標簽
*
* 修改標簽以提供不使用顏色的簡單線性版本。
*/
.label {
&.label--simple {
font-family: @font-family-base;
font-size: @font-size-xsmall - 1;
color: @gray;
border: 1px solid @gray-light;
padding: @padding-small;
border-radius: @border-radius-small;
text-transform: uppercase;
}
}

7.為樣式表的內容設置索引

這是提供樣式表內容快照的好方法,尤其是在那些不知出於什麽原因,必須存在長樣式表的項目中(雖然不喜歡這樣的項目,但是它們確實存在)。

樣式表索引通常長這樣:

/**
* icons.css
*
* 圖標應該以一種簡單而有意義的方式表達它們所代表的函數的概念。
* 在設計新圖標時,一定要刪除任何復雜的內容,並遵循圖標集的線性和輕量級外觀。
*
* Index
* - Icon Font
* - Icon Variations
* - Icon Animations
*
*/

盡管我很喜歡索引的整潔和實用,但我不得不承認它們很容易被遺忘,因此也就會慢慢過時了。當它們很長時,更新它們也是一件痛苦的事情,尤其是你正在使用數字來寫索引(所以請避免使用這些數字!)

使用索引的另一種方法是讓樣式指南成器通過查看樣式表來為你工作,查找你定義的部分,並為你生成索引。在本文的最後,我將進一步討論這個主題。

8.找到文檔的最佳平衡點

這是文檔的秘訣所在。剛開始寫文檔時很容易被帶動,進入寫文檔的狂熱狀態,然後忘記它,最後只剩下你的代碼庫中有一部分代碼被過度文檔化了,剩下的代碼就沒有文檔了。和生活中的一切事情一樣,秘訣就是找到平衡。記錄那些需要註意的部分,比如有不可預見的依賴額外的資源需要註意的重要事項。也就是說,並不是所有代碼都應該被記錄下來,但是將代碼分解成塊,並在必要時解釋這些代碼塊是什麽絕對是有用的。通過這種方式,文檔變成了一個有用的工具,它是你工作流程的一部分,而不是你避免去做的事後添加的東西。那你到底是應該怎麽做呢?下面舉個例子:

假設你需要實現下面卡片組件的標記和CSS:

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

根據這個設計,你會發現需要設計以下各部分樣式:

  • 基礎卡片樣式設計

  • 卡片網格

  • 卡片列表

  • 黑色版卡片

你可以使用這些樣式分解CSS實現,並使用文檔來指導。首先,你的“cards.css”樣式表可以包含一個簡單介紹如下:

/**
* cards.css
*
* 以下是card組件的樣式。
*
* Index
* - Card Base
* - Card Grid
* - Card List
* - Card Dark
*/

你可以在介紹中包含更多有用的信息,但是由於才剛剛開始,一些簡單的介紹就可以幫助建立文檔框架。

然後,我們將在其中添加你需要的部分:

/**
* cards.css
*
* 以下是card組件的樣式。
*
* Index
* - Card Base
* - Card Grid
* - Card List
* - Card Dark
*/
/**
* 基礎卡片
*/
/**
* 卡片網格
*/
/**
* 卡片列表
*/
/**
* 黑色版卡片
*/

考慮到這些部分的樣式,你可以可視化代碼的結構。你應該知道,卡片的基礎樣式設計應該靈活且獨立,這樣你就可以輕松地使卡片在網格、列表或黑色版本中工作。

然後,在編寫代碼時,你可以通過註釋使描述更具體:

/**
* 基礎卡片
*
* 主要用來定義默認卡片的外觀和行為:
* - Card Image
* - Card Content
* - Card Footer
*/
.card {...}
.card__image {...}
.card__logo {...}
.card__content {...}
.card__footer {...}

我認為這些是文檔應該包含的基本內容,因為它可以作為代碼布局的指南,並且可以快速地告知下一個工作的人代碼是如何組織的。

下一步是添加特定規則的註釋,對於不是特別明確的樣式,這些註釋可以用來解釋樣式是做什麽用的。例如:

/**
* 基礎卡片
*
* 主要用來定義默認卡片的外觀和行為:
* - Card Image
* - Card Logo
* - Card Content
* - Card Footer
*/
.card {
@media (max-width: {{ screen-xs }} ) {
border: none; /* 因為卡片在手機上占用了100%的屏幕 */
}
}
.card__image {...}
.card__logo {...}
.card__content {
flex: 1 1 auto; /* "auto" 需要加上,以避免在IE瀏覽器崩潰。*/
}

這種方法的優點在於,文檔可以在代碼實現的過程中起到支持和指的作用,而不是代碼完成後添加的內容。

下面是一些Bootstrap框架的例子,這些例子說明了註釋是有用的,是值得深入研究細節的。

示例 #1

// Need .dropdown-toggle since :last-child doesn‘t apply, 
// given that a .dropdown-menu is used immediately after it
.btn-group > .btn:last-child:not(:first-child),
.btn-group > .dropdown-toggle:not(:first-child) {
.border-left-radius(0);
}

這個註釋說明了為什麽這些樣式存在,以及它們在做什麽。它也很短,也很關鍵,用一種隨意的語言來表達想法。

示例 #2

// Checkbox and radio options
//
// In order to support the browser‘s form validation feedback, powered by the
// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
// `display: none;` or `visibility: hidden;` as that also hides the popover.
// Simply visually hiding the inputs via `opacity` would leave them clickable in
// certain cases which is prevented by using `clip` and `pointer-events`.
// This way, we ensure a DOM element is visible to position the popover from.
//
// See https://github.com/twbs/bootstrap/pull/12794 and
// https://github.com/twbs/bootstrap/pull/14559 for more information.
[data-toggle="buttons"] {
> .btn,
> .btn-group > .btn {
input[type="radio"],
input[type="checkbox"] {
position: absolute;
clip: rect(0,0,0,0);
pointer-events: none;
}
}
}

這是一個更深入的文檔示例,解釋了實現決策背後的邏輯,並提供了附加信息的鏈接。

更進一步

了解了這些最佳實踐,下一步是將動態樣式指南作為文檔的一部分。動態樣式指南是一個實時文檔,它顯示你在代碼中包含的註釋,就像一個網站一樣,因此你可以獨立於源代碼來瀏覽文檔。

動態樣式指南強大的地方是,實際的文檔與代碼一起變化,並可以很容易地隨著代碼的變化而更新,從而使其保持同步和相關。

另一個好處是,你可以讓團隊中的其他人使用這些文檔,這些人可能不會直接與代碼交互(比如設計人員、產品經理或QA工程師)。這些團隊成員也會發現,了解UI是如何形成的也很有幫助。

在實時樣式指南中,你可以包括代碼的交互式演示,並且可以獨立於代碼結構進一步組織文檔。

總結

文檔化CSS首先要有明確的規則和結構良好的代碼庫。當把文檔作為工作流程的一部分完成時,它也可以作為一個指南來構造您的代碼,並在代碼增長時保持組織結構。這樣額外的好處是,可以清楚地說明代碼的位置,以及應該添加新代碼的地方,這樣可以在快速跟蹤開發的同時降低新成員的上手難度。

最後提醒:8個最佳實踐

  1. 制定基本規則

  2. 說明代碼庫的結構

  3. 建立你的編碼標準

  4. 避免冗長的樣式表

  5. 利用約定的樣式指南編寫CSS文檔

  6. 將你的樣式表分成幾個部分

  7. 為樣式表的內容設置索引

  8. 找到文檔的最佳平衡點

完美CSS文檔的8個最佳實踐