這是一篇我喜歡的思想,經驗,理念,以及過去幾年中我所試驗的理念的集合。它覆蓋了HTML語義,前端架構的組件和方法,類命名模式,和HTTP內容壓縮。css
咱們不會中止探索
而咱們一切探索的終點
將會到達咱們出發的地方
因而咱們第一次認識了這個地方。
T.S. Eliot — 「一人」
關於語義
語義是對標記與符號之間的關係,以及它們的含義的研究。在語言學中,這主要是對語言中的符號(如單詞,短語,或聲音)意義的研究。在前端web開發的上下文中,語義大可能是與元素,屬性,和屬性值(包括像Microdata之類的擴展)的一致認贊成義相關。這些認贊成義一般在規範中被定義概念,它們能夠幫助程序員(也就是人類)更好的理解網站中信息的不一樣方面。可是,即便是規範化之後,元素,屬性,和屬性值的語義仍是受制於開發者對其的適應與吸取。這可能會致使後續對正式認同語義的修改(這也是一個HTML 設計原則)。
區別不一樣類型的HTML語義
編寫「語義HTML」原則是現代專業前端開發的基礎之一。大部分語義關於存在的本質屬性或是指望的內容(例如h1element,langattribute,emailvalue of thetypeattribute, Microdata)。
然而,不是全部的語義都要源於內容。Class名不能是「非語義」(unsemantic)的。不管使用什麼名字,都要有意義、有目的。Class名的語義能夠和那些HTML元素不同。 咱們能夠統一利用「全局」的語義命名HTML元素、某些HTML屬性、微數據等等,以避免和「本地」的網站/應用專屬的經常包含在屬性值內的語義相混淆,好比theclassattribute。 儘管在HTML5 specification section on classes 重複的認爲「最佳的實踐」 以下…
html
以這種很是簡單的例子:前端
從上面的例子很明顯的看出,類名news並無告訴你任何內容。它沒給你組件的組織結構的任何信息,它不能用於說明內容是否是「新聞」。類名的語義與內容的性質已經減小的關聯,架構功能已經變小,或者也很容易讓其餘開發者使用。
內容無關的類名
另外一種可選的方法是在設計中從重複結構和功能模式中派生類名的語義。大多數可重用的組件都帶有與內容無關的類名。
咱們不該該懼怕在清晰明確的層級間創建聯繫,而不是讓類名嚴格地反映特定的內容。這樣作不會讓類變得「沒有語義」,它僅僅意味着它們的語義不是從內容中派生出來的。若是附加的HTML元素幫助建立魯棒性強,柔軟度大,可重用的組件,咱們就不要懼怕把這些元素包含進來。這樣作也不會讓HTML變得沒有語義,它僅僅意味着你使用了恰好超過標記內容最小所需的元素。
前端架構
組件/模板/面向對象架構的設計宗旨就是開發出一套包含一系列不一樣類型的可重用組件。在規範的應用程序中,關於類名稱的語義,由實用主義者們推進並服務他們的主要目的——提供有意義的,靈活的,可重用的關聯供開發者使用。
可重用及可組合的組件
可伸縮的HTML/CSS大致上必須依賴於HTML內的層級,這樣就能夠創造可重用的組件。一個靈活且可重用的組件既不能依賴存在於DOM 樹的某個部分,也不能須要使用特定的元素類型。它應該能適用於不一樣的編輯器而且很容易主體化。若是必要的話,多餘的HTML元素(除了那些須要標記內容的元素)能夠用來讓組價更強壯。Nicole Sullivan所謂的媒體對象就是很好的例子。
組件能夠很容易的組合受益於類型選擇器的廢止和支持class。下面的示例展現了btn組件與uilist組件的簡易組合。問題是,指定.btn不如指定.uilist(這將覆蓋共享屬性),uilist組件須要一個錨標記做爲子節點。html5
使用class來修飾子DOM元素是提升易用性、使用uilist來組合其餘組件的一種方法。雖然這有助於減小指定規則,主要的好處是可讓你對任何類型的子節點應用結構化的樣式。git
JavaScript指定class
使用JavaScript指定class的形式的能夠下降風險:組件的主題或結構的改變時破壞對其對應的Javascript。一種有效的方法是:Javascript鉤子只使用js-*的特定class,而且一直保持。程序員
這樣作,你能夠減小風險:組件的結構或主題改變時會無心中影響任何須需的JavaScript行爲或複雜功能。
組件編輯器
組件一般具備與基礎組件有些許差異的多種不一樣外觀,好比,一個不一樣顏色的背景或者邊框。有兩種主要的模式被用來建立這些不一樣的組件。我稱它們爲「單類」模式和「多類」模式。
「單類」模式github
「多類」模式web
若是你使用了預處理器,就可使用Sass的@extend功能,來縮減一些使用「單類」模式時所涉及的維護工做。但是,即便有預處理器的幫助,我仍然傾向於使用「多類」模式,和在HTML中增長編輯類。
我發現這是一個更具伸縮性的模式。例如,用基礎的btn組件,給它增添5種類型的按鈕和3種額外的尺寸。使用「多類」模式你最終將得到9種可混用匹配的類。但使用「單類」模式你將有24種類。
若是確實須要的話,它給組件作一些上下文的修改也更容易。你或許會想在另外一個組件中,對任意一個btn作一些外觀的細微調整。後端
「多類」模式意味着在組件中,你只需一個組件內的選擇器,來標示btn-樣式元素的任意一種類型。而「單類」模式意味着你必須承擔任何可能的按鈕類型,而且在一個新按鈕變量被建立的時候調整選擇符。
結構化的類名
在建立組件,還有在此基礎上的「主題」的時候,有些類被用做組件的邊界,有些被用做組件的修飾器,有些被用來將一些DOM節點渲染到一個更大的抽象的展示組件中。
咱們很難推斷出btn(組件),btn-primary(修飾器),btn-group(組件)和btn-group-item(組件中的子對象)這些樣式之間的關係,由於這些命名並無清楚的揭示這些類的目的。沒有統一的模式。
早在2011年,我開始使用命名模式,這讓我很快的理解了DOM片斷節點之間外在的關係,這比嘗試經過來回移動HTML,CSS和JS文件來拼湊整個網站的結構要來得快不少。在要點中的標記的方式主要是受BEM系統的命名方式所影響,但被我改變成了我認爲容易使用的方式。
自從我開始寫這篇文章,其餘的幾支團隊和框架(譯者加:做者)採用了這種方法。MontageJS修改了符號變成另一個風格,我更偏心的而且目前正使用的是SUIT 工具包:架構
這只是我此刻發現有用的一個命名模式,它能夠採起任何形式。但好處在於消除 僅僅依賴(單)連字符或下劃線,或者駝峯式大小寫的類名的歧義。
注意原文件大小和http壓縮
凡討論到模塊化和可擴展,css成爲有關文件大小和膨脹的關注性問題。Nicole Sullivan的談話中常常說起到節省文件大小(和維護改進)。而節省文件大小是一些公司例如facebook,在採用這種模塊化和可擴展方法時遇到的問題。進一步地,我想分享,在預處理器上編寫且大量使用HTML元素時我對編寫完的文件進行http壓縮的效果。
當Twitter Bootstrap問世時,我改寫了已經編譯的css,使其能更好的反映出我是如何手寫來進行語義化,而且比較先後文件的大小。在同時精簡了這兩個文件以後,手寫來進行語義化的css比預處理器上寫的要小大約10%。可是當兩個文件都採用gzip壓縮了以後,預處理器上寫的比手寫進行語義化的css要小大約5%。
此處凸顯了在通過 HTTP 壓縮以後進行文件大小對比的重要性, 由於壓縮後的文件的大小並不能徹底說明問題. 這也暗示了有經驗的 CSS 開發者在使用預處理器的時候無需過多糾結於在編譯以後的 CSS 中會出現的必定程度的重複, 由於在 HTTP 壓縮以後它的尺寸會天然地變得更小. 經過預處理器處理過的更具維護性的 CSS 代碼所帶來的益處將會賽過對原始文件以及壓縮輸出的 CSS 文件的大小或美學上的考量。
在另外一次實踐中, 我從一個在線網站上下載了一份有 60KB 大小的 HTML 文檔, 從中刪除了全部的 class 屬性(它們構成了許多可重用的組件). 這樣處理以後將文檔的大小減少到了 25KB. 當原始文檔和分離過的文檔各自被 gzip 壓縮事後, 它們的尺寸變成了 7.6KB 和 6KB – 僅 1.6KB 的區別. 對於那些經過自由使用 class 而實際對文件大小產生的影響真的不值得再強調和放大了。
我怎樣學會中止煩惱的…
許多熟練的開發人員的經驗,通過多年,已經致使了大規模網站和應用程序開發的巨大轉變。儘管如此,對那些在乎識形態上斷奶的個體來講,「語義化HTML」是指使用內容派生類名(即便是這樣,只能做爲最後的手段),在你變得能夠敏銳地意識到那個方法不切實際的性質以前,一般須要你完成一個大型應用程序。你必須準備放棄舊的觀念,看看替代品,甚至你能夠重拾以前摒棄的方法。
一旦你開始寫做你和其餘人不只要維護並且要積極迭代的不平凡的網站和應用程序時,你很快就會發現,儘管你盡了最大的努力,你的代碼開始變得愈來愈難維護。一些人提出了他們本身的方法來解決這些問題,你值得花時間去探索他們的工做:妮可的博客和面向對象的CSS項目,喬納森斯努克的可伸縮的CSS模塊化架構,和Yandex開發的塊元素修改器方法。當你選擇用HTML和CSS寫做,並試圖減小你花在寫做和編輯CSS上的時間,這涉及到必須接受若是你想改變HTML元素的風格,你必須花更多的時間修改元素的類上。這證實是至關實用的,不管對前端仍是後端開發人員——任何人均可以從新排列預先構建的「樂高積木」;事實證實,沒有人能夠發明css鍊金術。