什么是語(yǔ)義化:語(yǔ)義化Web具備讓數(shù)據(jù)跨終端共享/重用的能力。
對(duì)于HTML體系而言,Web語(yǔ)義化是指使用語(yǔ)義恰當(dāng)?shù)臉?biāo)簽,使頁(yè)面有良好的結(jié)構(gòu),頁(yè)面元素有含義,能夠讓人和機(jī)器都容易理解。
語(yǔ)義化說(shuō)起來(lái)好像都懂,但是實(shí)際情況并不是那么樂(lè)觀。
再談各種所謂的CSS設(shè)計(jì)模式
OOCSS (Object Oriented CSS)
目標(biāo):
- 減少對(duì)HTML結(jié)構(gòu)的依賴
- 增加CSS class重復(fù)性的使用
<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>
SMACSS(Scalable and Modular Architecture for CSS):一種css架構(gòu)風(fēng)格。
<div class=“container”>
<div class=“container-header”>
<div class=“container-header__title”>
<h1 class=“container-header__title--home”>
BEM(Block,Element,Modular):與SMACSS類似。
<ul class="menu">
<li class="menu__item">...</li>
<li class="menu__item_state_current">...</li>
<li class="menu__item">...</li>
</ul>
METACSS | ATOMCSS (原子CSS)
<div class="fl mr10 red">
<span class="blue fl"></span>
</div>
為什么會(huì)有這么多層出不窮(千奇百怪)的CSS設(shè)計(jì)模式
1.CSS本身的不足,不具備邏輯表達(dá)能力 & 抽象能力
2.We had to maintain a shit。。。所以我們需要更有效的去減少讓自己惡心的成本。。
但這些都只是部分客觀原因,主要原因在于我們對(duì)于Web語(yǔ)義化的理解度不夠以及非正確的工作流。
以表現(xiàn)為中心(面向UI) VS 以信息為中心(面向語(yǔ)義)
以表現(xiàn)為中心的工作流: 需求原型 --> UI設(shè)計(jì)稿 --> 以HTML/CSS實(shí)現(xiàn)設(shè)計(jì)稿
以信息為中心的工作流: 需求原型 --> 分析需求并以HTML描述 --> UI設(shè)計(jì)稿 --> 分析樣式并以CSS實(shí)現(xiàn)
兩者最大的區(qū)別在于,對(duì)于面向UI的工作流而言,HTML/CSS只是實(shí)現(xiàn)UI的手段,而對(duì)于純正的Web開(kāi)發(fā)(面向語(yǔ)義的工作流)而言,我們應(yīng)該是以信息為中心的,即首先考慮信息的本質(zhì)(語(yǔ)義),并以合適的標(biāo)簽來(lái)標(biāo)記,最后再考慮樣式和行為(UI)。
之所以會(huì)有那么多層出不窮(不知所謂)的CSS設(shè)計(jì)模式,是因?yàn)樗鼈兇蠖际且员憩F(xiàn)為中心提出的“最佳實(shí)踐”,而這兩種方法論本身又是不適配的。
為什么說(shuō)面向語(yǔ)義(以信息為中心)才是純正的Web開(kāi)發(fā)
1.Web誕生的目的是用于在網(wǎng)絡(luò)上傳遞資源跟信息的。HTML設(shè)計(jì)之初是用來(lái)作為互聯(lián)網(wǎng)上主要的內(nèi)容載體,其本身是用來(lái)描述信息的。在最早期的Web時(shí)代,HTML作為一種通用的描述語(yǔ)言用來(lái)表述在互聯(lián)網(wǎng)上傳輸/共享的文檔的信息。
Web 萬(wàn)維網(wǎng)
HTML 作為一種對(duì)計(jì)算機(jī)而言通用易懂的母語(yǔ)
2.Web領(lǐng)域的一套基礎(chǔ)架構(gòu)跟技術(shù)(包括HTTP、REST、HTML等),是按照語(yǔ)義中心的方式設(shè)計(jì)出來(lái)的。如果采用UI中心的方法論,必然導(dǎo)致阻抗不匹配。
3.w3c官方也在致力于推廣Web語(yǔ)義化
- 各種表現(xiàn)型標(biāo)簽/屬性在HTML5中被廢棄/不推薦使用(center、big、width等)
- HTML5中新增的各種語(yǔ)義化標(biāo)簽(header、nav等),而這些標(biāo)簽在表現(xiàn)上跟div無(wú)二。
CSS語(yǔ)義化?
通常意義上我們說(shuō)的CSS語(yǔ)義指的是class的語(yǔ)義。class作為HTML與CSS之間的主要鉤子,卻是被我們誤解最深的一個(gè)東西。
class屬性本意是用來(lái)描述元素內(nèi)容的,而不是描述元素展現(xiàn)的。其典型‘反模式’代表就是METACSS。
看看這兩段代碼,哪一個(gè)更容易理解?
<!-- 以表現(xiàn)為中心 -->
<div class="fl mr10">
<span>userName:Kuitos</span>
<div>
<!-- 以信息為中心 -->
<div class="user-info">
<span>userName:Kuitos</span>
<div>
class作為HTML描述屬性集的一部分,本身是用來(lái)細(xì)化內(nèi)容語(yǔ)義的,所謂的CSS語(yǔ)義化本質(zhì)上就是HTML語(yǔ)義化。
符合標(biāo)準(zhǔn)的最佳實(shí)踐
在CSS領(lǐng)域發(fā)展的初期,嚴(yán)格意義上的“最佳實(shí)踐”都是不存在的,這主要受制于CSS的支持度,大部分瀏覽器的CSS的支持不夠好,所以也導(dǎo)致我們很難在表現(xiàn)及語(yǔ)義之間做平衡。所以我們?cè)诜碒TML標(biāo)簽的時(shí)候會(huì)看到諸如<b><center>這類純樣式的歷史性標(biāo)簽(這些標(biāo)簽已經(jīng)不被HTML5 spec推薦使用)。
但是為什么到了CSS已經(jīng)如此強(qiáng)大(且瀏覽器支持度也都挺好)的年代,依然會(huì)出現(xiàn)那么多實(shí)質(zhì)還是以表現(xiàn)為中心提出的所謂“最佳實(shí)踐”?其實(shí),這歸結(jié)起來(lái),源于我們對(duì)于CSS復(fù)用的這種剛性需求。
以O(shè)OCSS為例,我們寫一組按鈕可能會(huì)這么寫:
<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;
...
}
我不能每寫一個(gè)button都重復(fù)一遍寬高啊,要復(fù)用,所以我們可能會(huì)把公共部分提取出來(lái)。
<button class="button button-primary"></button>
<button class="button button-error"></button>
.button {
width: 80px;
height: 40px;
}
如果你秉承這個(gè)思路,當(dāng)哪天產(chǎn)品要求第一個(gè)按鈕要左排第二個(gè)要右排的時(shí)候,我估摸著你會(huì)很自然的這么去寫:
<button class="button button-primary float-left"></button>
<button class="button button-error float-right"></button>
.float-left {
float: left;
}
.float-right {
float: right;
}
更甚者,哪天產(chǎn)品要求第二個(gè)按鈕跟右邊隔10像素,你會(huì)不會(huì)這么寫?
<button class="button button-error float-right mr10"></button>
css我就不寫了mr10什么意思我猜你已經(jīng)知道了。。
且不說(shuō)<button class="button button-primary"></button>
這種寫法中button本身就是一種冗余信息(我當(dāng)沒(méi)看見(jiàn)也罷),mr10
則基本上無(wú)法忍受了,仔細(xì)想想這跟直接寫inline-style有什么差別?相反我寫inline-style更符合標(biāo)準(zhǔn),至少我是掛載在專門用于描述表現(xiàn)的style屬性上面,而不是用來(lái)描述內(nèi)容的class上面。
基于這樣的一連串演進(jìn),最后大概會(huì)誕生出兩個(gè)癥狀:
1.樣式類 即一系列諸如 mr10 fl之類的class
2.多class癥 即幾乎每個(gè)元素上都要掛載至少一個(gè)class。
原因在于,如果我們需要達(dá)到復(fù)用的效果,最后必定會(huì)魔障出一條理念:樣式需具備獨(dú)立性與上下文無(wú)關(guān),同時(shí)粒度需要夠小(樣式類/通用原子類)。
其中也有一個(gè)主要原因是我們對(duì)CSS的誤解。
css = 層疊樣式表,其關(guān)鍵詞在層疊
“復(fù)用”需求最后一定會(huì)導(dǎo)致我們樣式退化到平級(jí)的單class規(guī)則定義,因?yàn)檫@樣才能足夠無(wú)狀態(tài)。但實(shí)際上CSS最獨(dú)特的地方在于層疊,你避開(kāi)這種機(jī)制從而來(lái)滿足復(fù)用需求,最后不單單喪失了CSS的能力,反而會(huì)催生出一系列不符合語(yǔ)義化標(biāo)準(zhǔn)的反模式。
但是我也說(shuō)過(guò),復(fù)用是剛需,而CSS又不具備抽象能力,所以我們只能眼睜睜的看著一坨坨屎流行么?
好在我們有預(yù)處理器
最佳實(shí)踐 Sass/Less
Sass/Less我這里就不一一贅述了,時(shí)至今日相比大家都很熟悉。為什么說(shuō)最佳實(shí)踐是Sass/Less呢?簡(jiǎn)單來(lái)說(shuō),就是這類預(yù)處理器在提供一定的抽象能力的同時(shí),也不會(huì)破壞css自身的特性。拿上面的例子來(lái)看,如果我們使用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;
}
如果我們?cè)陧?xiàng)目級(jí)別需要統(tǒng)一的配色,可以做進(jìn)一步的抽象
$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。
我們可以將我們需要復(fù)用的“樣式類”抽象成placeholder/mixin(對(duì)于“通用原子類”這樣的需求我推薦用placeholder),然后使用語(yǔ)義化的 class/屬性 作為鉤子,來(lái)組裝這些“原子類”(但實(shí)際上這些“原子類”對(duì)CSS而言是不可見(jiàn)的)。比如我們用a標(biāo)簽來(lái)模擬一個(gè)提交按鈕,我們應(yīng)該這樣寫:
<a href="#" role="submit-button">提交</a>
a[role="submit-button"] {
@include .button-success;
}
所以css的最佳實(shí)踐應(yīng)該是: Sass + OOCSS/BEM/METACSS
這里有一個(gè)關(guān)鍵點(diǎn)在于,我們?cè)谑褂眠@些css抽象方法論來(lái)寫sass的時(shí)候,切記不要把中間變量暴露給css。什么意思呢,button那個(gè)例子我這樣來(lái)寫
.button{
width: 80px;
height: 40px;
}
.button-primary {
@extend .button;
}
此時(shí)button對(duì)于css而言是可見(jiàn)的。對(duì)于button這類抽象產(chǎn)物,我們應(yīng)該用placeholder和mixin代替,確保其對(duì)css的不可見(jiàn)從而保證web的“純度”。(這也是我不推薦Less的原因,Less最大的失誤在于沒(méi)有placeholder的設(shè)計(jì))
到這里估計(jì)思考過(guò)的同學(xué)會(huì)有疑問(wèn):很多場(chǎng)景可能并沒(méi)那么容易語(yǔ)義化,比如我要第一個(gè)元素左浮動(dòng),第二個(gè)元素右浮動(dòng),第三個(gè)又左浮動(dòng),第四個(gè)右浮動(dòng)。。。
這里需要提到另一個(gè)經(jīng)常被誤解的點(diǎn):selector。selector作為HTML與CSS的結(jié)合點(diǎn),實(shí)質(zhì)上也是需要語(yǔ)義化的。tag跟id是天生帶語(yǔ)義的,主要問(wèn)題還是出在class上。我們總是嘗試在class上掛載一些表現(xiàn)型的“名稱”。這里面有一小部分確實(shí)是由于CSS本身的不完美(比如layout這種場(chǎng)景細(xì)則就比較難語(yǔ)義)導(dǎo)致的,但是過(guò)多的則歸咎于我們語(yǔ)義化動(dòng)力不足及對(duì)selector的認(rèn)知不夠。語(yǔ)義化動(dòng)力不足完全是主觀因素這里不贅述,對(duì)selector認(rèn)知不夠則是最普遍存在的情況。推薦閱讀:為后代選擇器及id選擇器辯護(hù) 結(jié)合智能選擇器的語(yǔ)義化的CSS。
為什么一定要按標(biāo)準(zhǔn)來(lái)?
其實(shí)我不太想回答這種問(wèn)題。。。我更想反問(wèn):為什么不按標(biāo)準(zhǔn)來(lái)?!!
一定要說(shuō)的話:
推行標(biāo)準(zhǔn)的目的是為技術(shù)交流構(gòu)建一個(gè)統(tǒng)一的上下文語(yǔ)境平臺(tái),提高溝通效率,避免雞同鴨講。
同時(shí)標(biāo)準(zhǔn)跟規(guī)范的制定是經(jīng)過(guò)一群 資深開(kāi)發(fā)者/科學(xué)家 經(jīng)過(guò)仔細(xì)研究及社區(qū)討論的,一套完整的一致的基礎(chǔ)架構(gòu)系統(tǒng)是推進(jìn)生態(tài)發(fā)展的必要條件。
就Web語(yǔ)義化這件事情而言,如果你的HTML是基于標(biāo)準(zhǔn)來(lái)編寫的,意味著你的頁(yè)面具備更多的可能性。比如搜索引擎友好,多終端適配(不是響應(yīng)式。。是指兼容各種閱讀設(shè)備、讀屏軟件等。參見(jiàn)microformats),更智能的風(fēng)格查錯(cuò)能力。
在前端開(kāi)發(fā)體系里,能體系專業(yè)性的地方不多。。拿程序復(fù)雜度而言,它跟大型后端系統(tǒng)差不止一個(gè)量級(jí)(前端的難度在于工程上)。。好不容易有一個(gè)能體現(xiàn)專業(yè)素養(yǎng)的領(lǐng)域(語(yǔ)義化Web),為什么我們不抓住機(jī)會(huì)為自己正名呢。。
推薦閱讀:
http://hax.iteye.com/blog/497338
http://hax.iteye.com/blog/500015
http://hax.iteye.com/blog/849826