網站客服 www.aynuip.live 
微信客服 www.aynuip.live 
經典總結!語義化HTML和前端架構
發布時間:2014-10-08 13:51:25 點擊瀏覽:
1322099011525.jpg

    這是一篇思想,經驗,理念,以及過去幾年中試驗的理念的集合。它覆蓋了HTML語義,前端架構的組件和方法,類命名模式,和HTTP內容壓縮。

“我們不會停止探索
而我們一切探索的終點
將會到達我們出發的地方
于是我們第一次認識了這個地方。”


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 重復的認為“最佳的實踐” 如下…

…作者鼓勵用 [class attribute] 值來描述內容的顯示,而不是描述的內容所需的表現值。
…沒有內在的理由這樣做。事實上,它往往是大型網站或應用程序工作時的一個障礙。

  • 內容層語義已經擔任HTML元素和其他屬性。
  • 類名很少或根本沒有賦予語義有用的信息給計算機或瀏覽,除非它的一小部分(計算機可讀)約定的名字 - 微格式的部分。
  • 類名稱的主要目的是為CSS和JavaScript設置鉤子。 如果你不需要給你的web文檔添加演示和行為,那么你可能不需要在你的HTML文件中使用classes。
  • 類名應該提供有用的信息給開發商。當你讀一個DOM代碼段的時候,有助于了解一個特定的類的名字是要干什么,特別是在前期與多個開發團隊,包括非HTML組件工作的人。

以這種非常簡單的例子:
  1.    

    News

  2.     [news content]
復制代碼
從上面的例子很明顯的看出,類名news并沒有告訴你任何內容。它沒給你組件的組織結構的任何信息,它不能用于說明內容是不是“新聞”。類名的語義與內容的性質已經減少的關聯,架構功能已經變小,或者也很容易讓其他開發者使用。


內容無關的類名
另一種可選的方法是在設計中從重復結構和功能模式中派生類名的語義。大多數可重用的組件都帶有與內容無關的類名。  

我們不應該害怕在清晰明確的層級間建立聯系,而不是讓類名嚴格地反映特定的內容。這樣做不會讓類變得“沒有語義”,它僅僅意味著它們的語義不是從內容中派生出來的。如果附加的HTML元素幫助創建魯棒性強,柔軟度大,可重用的組件,我們就不要害怕把這些元素包含進來。這樣做也不會讓HTML變得沒有語義,它僅僅意味著你使用了剛好超過標記內容最小所需的元素。


前端架構
組件/模板/面向對象架構的設計宗旨就是開發出一套包含一系列不同類型的可重用組件。在規范的應用程序中,關于類名稱的語義,由實用主義者們推動并服務他們的主要目的——提供有意義的,靈活的,可重用的關聯供開發者使用。


可重用及可組合的組件
可伸縮的HTML/CSS大體上必須依賴于HTML內的層級,這樣就可以創造可重用的組件。一個靈活且可重用的組件既不能依賴存在于DOM 樹的某個部分,也不能需要使用特定的元素類型。它應該能適用于不同的編輯器并且很容易主體化。如果必要的話,多余的HTML元素(除了那些需要標記內容的元素)可以用來讓組價更強壯。Nicole Sullivan所謂的媒體對象就是很好的例子。 

組件可以很容易的組合受益于類型選擇器的廢止和支持class。下面的示例展示了btn組件與uilist組件的簡易組合。問題是,指定.btn不如指定.uilist(這將覆蓋共享屬性),uilist組件需要一個錨標記作為子節點。
  1. .btn { /* styles */ }
  2. .uilist { /* styles */ }
  3. .uilist a { /* styles */ }
復制代碼
  1.     Home
  2.     About
  3.     Login
復制代碼
使用class來修飾子DOM元素是提高易用性、使用uilist來組合其他組件的一種方法。雖然這有助于減少指定規則,主要的好處是可以讓你對任何類型的子節點應用結構化的樣式。
  1. .btn { /* styles */ }
  2. .uilist { /* styles */ }
  3. .uilist-item { /* styles */ }
復制代碼
  1.     Home
  2.     About
  3.    
  4.         Login
  5.    
復制代碼


JavaScript指定class
使用JavaScript指定class的形式的可以降低風險:組件的主題或結構的改變時破壞對其對應的Javascript。一種有效的方法是:Javascript鉤子只使用js-*的特定class,并且一直保持。
復制代碼
這樣做,你可以減少風險:組件的結構或主題改變時會無意中影響任何必需的JavaScript行為或復雜功能。


組件編輯器
組件通常具有與基礎組件有些許差別的多種不同外觀,比如,一個不同顏色的背景或者邊框。有兩種主要的模式被用來創建這些不同的組件。我稱它們為“單類”模式和“多類”模式。

“單類”模式
  1. .btn, .btn-primary { /* button template styles */ }
  2. .btn-primary { /* styles specific to save button */ }
復制代碼

“多類”模式
  1. .btn { /* button template styles */ }
  2. .btn-primary { /* styles specific to primary button */ }
  3.  
  4. Default
  5. Login
復制代碼
如果你使用了預處理器,就可以使用Sass的@extend功能,來縮減一些使用“單類”模式時所涉及的維護工作。可是,即使有預處理器的幫助,我仍然傾向于使用“多類”模式,和在HTML中增加編輯類。

我發現這是一個更具伸縮性的模式。例如,用基礎的btn組件,給它增添5種類型的按鈕和3種額外的尺寸。使用“多類”模式你最終將獲得9種可混用匹配的類。但使用“單類”模式你將有24種類。

如果確實需要的話,它給組件做一些上下文的修改也更容易。你或許會想在另一個組件中,對任意一個btn做一些外觀的細微調整。
  1. /* "multi-class" adjustment */
  2. .thing .btn { /* adjustments */ }
  3.  
  4. /* "single-class" adjustment */
  5. .thing .btn,
  6. .thing .btn-primary,
  7. .thing .btn-danger,
  8. .thing .btn-etc { /* adjustments */ }
復制代碼
“多類”模式意味著在組件中,你只需一個組件內的選擇器,來標示btn-樣式元素的任意一種類型。而“單類”模式意味著你必須承擔任何可能的按鈕類型,并且在一個新按鈕變量被創建的時候調整選擇符。


結構化的類名
在創建組件,還有在此基礎上的“主題”的時候,有些類被用作組件的邊界,有些被用作組件的修飾器,有些被用來將一些DOM節點渲染到一個更大的抽象的展現組件中。

我們很難推斷出btn(組件),btn-primary(修飾器),btn-group(組件)和btn-group-item(組件中的子對象)這些樣式之間的關系,因為這些命名并沒有清楚的揭示這些類的目的。沒有統一的模式。  

早在2011年,我開始使用命名模式,這讓我很快的理解了DOM片段節點之間外在的關系,這比嘗試通過來回移動HTML,CSS和JS文件來拼湊整個網站的結構要來得快很多。在要點中的標記的方式主要是受BEM系統的命名方式所影響,但被我改變成了我認為容易使用的方式。

自從我開始寫這篇文章,其他的幾支團隊和框架(譯者加:作者)采用了這種方法。MontageJS修改了符號變成另外一個風格,我更偏愛的并且目前正使用的是SUIT 工具包:
  1. /* Utility */
  2. .u-utilityName {}
  3.  
  4. /* State-utility */
  5. .u-isStateName {}
  6.  
  7. /* Component */
  8. .ComponentName {}
  9.  
  10. /* Component modifier */
  11. .ComponentName--modifierName {}
  12.  
  13. /* Component descendant */
  14. .ComponentName-descendant {}
  15.  
  16. /* Component descendant modifier */
  17. .ComponentName-descendant--modifierName {}
  18.  
  19. /* Component state (scoped to component) */
  20. .ComponentName.is-stateOfComponent {}
  21.  
  22. /* Component mixin (ancestor style dependencies) */
  23. .with-ComponentName {}
復制代碼

這只是我此刻發現有用的一個命名模式,它可以采取任何形式。但好處在于消除 僅僅依賴(單)連字符或下劃線,或者駝峰式大小寫的類名的歧義。


注意原文件大小和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煉金術。

 

上一篇:解析微信公眾平臺信息推送的相關技巧 下一篇:高端網站建設與中低端網站建設的區別
三肖中特期期准免费丨