原文:https://github.com/kuitos/kuitos.github.io/issues/33css
15年年底寫了篇關於BEM方法論(實踐上內容並非原BEM)的文章,文末給本身挖了個坑說要聊聊web語義化,跳票至今?。16年第一篇用來填坑好了!html
The Semantic Web provides a common framework that allows data to be shared and reused across application, enterprise, and community boundaries. --Wikipedia前端
語義化Web具有讓數據跨終端共享/重用的能力。git
對於HTML體系而言,Web語義化是指使用語義恰當的標籤,使頁面有良好的結構,頁面元素有含義,可以讓人和機器都容易理解。github
語義化提及來好像都懂,可是實際狀況並非那麼樂觀。web
OOCSS (Object Oriented CSS)後端
...a CSS 「object」 is a repeating visual pattern, that can be abstracted into an independent snippet of HTML, CSS, and possibly JavaScript. That object can then be reused throughout a site. — Nicole Sullivan設計模式
<div class="item"> <ul class="item-list"> <li class="item-list--item"> <h3 class="item-heading">... <button class="button button-primary">primary</button> <button class="button button-info">info</button>
目標:瀏覽器
減小對HTML結構的依賴sass
增長CSS class重複性的使用
SMACSS(Scalable and Modular Architecture for CSS)
...an attempt to document a consistent approach to site development when using CSS. — SMACSS
<div class=「container」> <div class=「container-header」> <div class=「container-header__title」> <h1 class=「container-header__title--home」>
一種css架構風格
BEM(Block,Element,Modular)
The BEM approach ensures that everyone participating in the development of a website is working with the same codebase and using the same terminology — BEM Methodology
<ul class="menu"> <li class="menu__item">...</li> <li class="menu__item_state_current">...</li> <li class="menu__item">...</li> </ul>
與SMACSS相似
METACSS | ATOMCSS (原子CSS)
<div class="fl mr10 red"> <span class="blue fl"></span> </div>
WTFSS
Cascading Style Sheets (CSS) are a stylesheet language used to describe the presentation of a document written in HTML or XML (including XML dialects like SVG or XHTML). CSS describes how elements should be rendered on screen, on paper, in speech, or on other media. --MDN
CSS自己的不足,不具有邏輯表達能力 & 抽象能力
We had to maintain a shit。。。因此咱們須要更有效的去減小讓本身噁心的成本。。
但這些都只是部分客觀緣由,主要緣由在於咱們對於Web語義化的理解度不夠以及非正確的工做流。
以表現爲中心的工做流: 需求原型 --> UI設計稿 --> 以HTML/CSS實現設計稿
以信息爲中心的工做流: 需求原型 --> 分析需求並以HTML描述 --> UI設計稿 --> 分析樣式並以CSS實現
二者最大的區別在於,對於面向UI的工做流而言,HTML/CSS只是實現UI的手段,而對於純正的Web開發(面向語義的工做流)而言,咱們應該是以信息爲中心的,即首先考慮信息的本質(語義),並以合適的標籤來標記,最後再考慮樣式和行爲(UI)。
之因此會有那麼多層出不窮(不知所謂)的CSS設計模式,是由於它們大都是以表現爲中心提出的「最佳實踐」,而這兩種方法論自己又是不適配的。
Web誕生的目的是用於在網絡上傳遞資源跟信息的。HTML設計之初是用來做爲互聯網上主要的內容載體,其自己是用來描述信息的。在最先期的Web時代,HTML做爲一種通用的描述語言用來表述在互聯網上傳輸/共享的文檔的信息。
Web 萬維網
The World Wide Web (WWW) is an open source information space where documents and other web resources are identified by URLs, interlinked by hypertext links, and can be accessed via the Internet.
HTML 做爲一種對計算機而言通用易懂的母語
To publish information for global distribution, one needs a universally understood language, a kind of publishing mother tongue that all computers may potentially understand.
Web領域的一套基礎架構跟技術(包括HTTP、REST、HTML等),是按照語義中心的方式設計出來的。若是採用UI中心的方法論,必然致使阻抗不匹配。
w3c官方也在致力於推廣Web語義化
各類表現型標籤/屬性在HTML5中被廢棄/不推薦使用(center、big、width等)
HTML5中新增的各類語義化標籤(header、nav等),而這些標籤在表現上跟div無二。
一般意義上咱們說的CSS語義指的是class的語義。class做爲HTML與CSS之間的主要鉤子,倒是被咱們誤解最深的一個東西。
There are no additional restrictions on the tokens authors can use in the class attribute, but authors are encouraged to use values that describe the nature of the content, rather than values that describe the desired presentation of the content. --w3c
class屬性本意是用來描述元素內容的,而不是描述元素展示的。其典型‘反模式’表明就是METACSS。
看看這兩段代碼,哪個更容易理解?
<!-- 以表現爲中心 --> <div class="fl mr10"> <span>userName:Kuitos</span> <div> <!-- 以信息爲中心 --> <div class="user-info"> <span>userName:Kuitos</span> <div>
class做爲HTML描述屬性集的一部分,自己是用來細化內容語義的,所謂的CSS語義化本質上就是HTML語義化。
在CSS領域發展的初期,嚴格意義上的「最佳實踐」都是不存在的,這主要受制於CSS的支持度,大部分瀏覽器的CSS的支持不夠好,因此也致使咱們很難在表現及語義之間作平衡。因此咱們在翻看HTML標籤的時候會看到諸如<b><center>
這類純樣式的歷史性標籤(這些標籤已經不被HTML5 spec推薦使用)。
可是爲何到了CSS已經如此強大(且瀏覽器支持度也都挺好)的年代,依然會出現那麼多實質仍是以表現爲中心提出的所謂「最佳實踐」?其實,這歸結起來,源於咱們對於CSS複用的這種剛性需求。
以OOCSS爲例,咱們寫一組按鈕可能會這麼寫:
<button class="button-primary"></button> <button class="button-error"></button>
.button-primary { width: 80px; height: 40px; background-color: green; ... } .button-error { width: 80px; height: 40px; background-color: red; ... }
我不能每寫一個button都重複一遍寬高啊,要複用,因此咱們可能會把公共部分提取出來
<button class="button button-primary"></button> <button class="button button-error"></button>
.button { width: 80px; height: 40px; }
若是你秉承這個思路,當哪天產品要求第一個按鈕要左排第二個要右排的時候,我估摸着你會很天然的這麼去寫:
<button class="button button-primary float-left"></button> <button class="button button-error float-right"></button>
.float-left { float: left; } .float-right { float: right; }
更甚者,哪天產品要求第二個按鈕跟右邊隔10像素,你會不會這麼寫?
<button class="button button-error float-right mr10"></button>
css我就不寫了mr10什麼意思我猜你已經知道了。。
且不說<button class="button button-primary"></button>
這種寫法中button自己就是一種冗餘信息(我當沒看見也罷),mr10
則基本上沒法忍受了,仔細想一想這跟直接寫inline-style有什麼差異?相反我寫inline-style更符合標準,至少我是掛載在專門用於描述表現的style屬性上面,而不是用來描述內容的class上面。
基於這樣的一連串演進,最後大概會誕生出兩個症狀:
樣式類 即一系列諸如 mr10 fl之類的class
多class症 即幾乎每一個元素上都要掛載至少一個class。
緣由在於,若是咱們須要達到複用的效果,最後一定會魔障出一條理念:樣式需具有獨立性與上下文無關,同時粒度須要夠小(樣式類/通用原子類)。
其中也有一個主要緣由是咱們對CSS的誤解
css = 層疊樣式表,其關鍵詞在層疊
「複用」需求最後必定會致使咱們樣式退化到平級的單class規則定義,由於這樣才能足夠無狀態。但實際上CSS最獨特的地方在於層疊,你避開這種機制從而來知足複用需求,最後不僅僅喪失了CSS的能力,反而會催生出一系列不符合語義化標準的反模式。
可是我也說過,複用是剛需,而CSS又不具有抽象能力,因此咱們只能眼睜睜的看着一坨坨屎流行麼?
好在咱們有預處理器
Sass/Less我這裏就不一一贅述了,時至今日相比你們都很熟悉。爲何說最佳實踐是Sass/Less呢?簡單來講,就是這類預處理器在提供必定的抽象能力的同時,也不會破壞css自身的特性。拿上面的例子來看,若是咱們使用Sass/Less的寫法:
%button { width:80px; height:40px; } .button-primary { @extend %button; background-color: white; } .button-success { @extend %button; background-color: green; } .button-error { @extend %button; background-color: red; }
若是咱們在項目級別須要統一的配色,能夠作進一步的抽象
$primary-bgc: white; $success-bgc: green; $error-bgc: red; .button-primary { @extend %button; background-color: $primary-bgc; } .button-success { @extend %button; background-color: $success-bgc; } .button-error { @extend %button; background-color: $error-bgc; }
一樣的手段還有mixin。
咱們能夠將咱們須要複用的「樣式類」抽象成placeholder/mixin(對於「通用原子類」這樣的需求我推薦用placeholder),而後使用語義化的 class/屬性 做爲鉤子,來組裝這些「原子類」(但實際上這些「原子類」對CSS而言是不可見的)。好比咱們用a標籤來模擬一個提交按鈕,咱們應該這樣寫:
<a href="#" role="submit-button">提交</a>
a[role="submit-button"] { @include .button-success; }
因此css的最佳實踐應該是: Sass + OOCSS/BEM/METACSS
這裏有一個關鍵點在於,咱們在使用這些css抽象方法論來寫sass的時候,切記不要把中間變量暴露給css。什麼意思呢,button那個例子我這樣來寫
.button{ width: 80px; height: 40px; } .button-primary { @extend .button; }
此時button對於css而言是可見的。對於button這類抽象產物,咱們應該用placeholder和mixin代替,確保其對css的不可見從而保證web的「純度」。(這也是我不推薦Less的緣由,Less最大的失誤在於沒有placeholder的設計)
到這裏估計思考過的同窗會有疑問:不少場景可能並沒那麼容易語義化,好比我要第一個元素左浮動,第二個元素右浮動,第三個又左浮動,第四個右浮動。。。
這裏須要提到另外一個常常被誤解的點:selector。selector做爲HTML與CSS的結合點,實質上也是須要語義化的。tag跟id是天生帶語義的,主要問題仍是出在class上。咱們老是嘗試在class上掛載一些表現型的「名稱」。這裏面有一小部分確實是因爲CSS自己的不完美(好比layout這種場景細則就比較難語義)致使的,可是過多的則歸咎於咱們語義化動力不足及對selector的認知不夠。語義化動力不足徹底是主觀因素這裏不贅述,對selector認知不夠則是最廣泛存在的狀況。推薦閱讀:爲後代選擇器及id選擇器辯護 結合智能選擇器的語義化的CSS
綜上所述,若是要秉持純粹的Web開發,最佳實踐是:
合適的語義化標籤 + 語義化selector + Sass
其實我不太想回答這種問題。。。我更想反問:爲何不按標準來?!!
必定要說的話:
推行標準的目的是爲技術交流構建一個統一的上下文語境平臺,提升溝通效率,避免雞同鴨講。
同時標準跟規範的制定是通過一羣 資深開發者/科學家 通過仔細研究及社區討論的,一套完整的一致的基礎架構系統是推動生態發展的必要條件。
就Web語義化這件事情而言,若是你的HTML是基於標準來編寫的,意味着你的頁面具有更多的可能性。好比搜索引擎友好,多終端適配(不是響應式。。是指兼容各類閱讀設備、讀屏軟件等。參見microformats),更智能的風格查錯能力。
在前端開發體系裏,能體系專業性的地方很少。。拿程序複雜度而言,它跟大型後端系統差不止一個量級(前端的難度在於工程上)。。好不容易有一個能體現專業素養的領域(語義化Web),爲何咱們不抓住機會爲本身正名呢。。
推薦閱讀: