本文由白牙根據Heydon Pickering的《Semantic CSS With Intelligent Selectors》所譯,整個譯文帶有我本身的理解與思想,若是譯得很差或不對之處還請同行朋友指點。如需轉載此譯文,需註明英文出處:http://coding.smashingmagazine.com/2013/08/20/semantic-css-with-intelligent-selectors/,以及做者相關信息javascript
——做者:Heydon Pickeringcss
——譯者:白牙html
「結構永遠服從於功能,這是不變的法則」,建築工程師「摩天大樓之父」Louis Sullivan如是說。由於工程師不但願讓無辜的人們被碾壓在巨大的建築物下,這種大拇指式的規則是至關有用的。在設計中你應該老是以功能爲重,而後讓結構在結果中呈現。若是你以結構爲重,雖然這可以建造出一棟漂亮的摩天大樓,但代價是埋下了許多至關危險的種子。前端
這些都是關於建築師的,那麼對前端架構師或者「非真正的架構師」來講呢?咱們須要遵照這個法則仍是忽略它?java
隨着面向對象的CSS(OOCSS)的出現,愈來愈多人趨向於「把呈現的語義從文檔語義中脫離出來」。藉助於類(classes)的非特指含義,咱們可以以分離的方式來管理一個文檔和一個文檔的外貌。git
在這篇文章當中,咱們會探索多種爲Web文檔添加樣式的方法,他們能把文檔語義與視覺設計相結合在一塊兒。經過「聰明的」選擇器的使用,咱們經過這種方法給你講解怎樣去查詢語義化的HTML文檔現有的功能特性,以此做爲對那些格式良好的標記的一個獎勵。若是你的代碼是正確的,你必定會獲得你所指望設計出來的東西。github
我想,若是你和我同樣同時在開發幾個不一樣的項目,我但願經過這些方法會簡化你的工做流程和並能更輕鬆地穿梭在這些項目當中。另外,在最後的部分咱們會講解一個更被動的方法:咱們會製做一個包含屬性選擇器的CSS書籤來測試那些寫得很糟糕的HTML文檔並使用僞元素來反饋錯誤。web
樣式表的發明使咱們可以將那些美化HTML文檔的代碼從HTML文檔中分離出來。但它對於咱們書寫標準的HTML文檔方面所帶來的幫助並不像遙控器那樣爲電視機帶來了更高質量的電視節目。它只不過把工做變得更加簡單。由於咱們可以使用一個選擇器來爲多個元素添加樣式。(例如 p 可做用於全部的段落元素),頁面的一致性和可維護性也不像之前那樣那麼使人畏懼。bootstrap
p 選擇器最簡單的形式就是智能選擇器的一個表明。由於 p 選擇器在語義分類方面具備先天的基礎。不用開發者多作額外的事情它已經知道怎樣確認一個段落以及什麼時候爲他們添加樣式,很是簡單而有效,特別是你想爲所見即所得編輯器產生的全部的段落元素添加樣式的時候。windows
但若是說它是智能的選擇器,那非智能的選擇器又是哪些呢?全部須要開發者介入並更改文檔從而引發樣式上的變化的選擇器都被稱之爲非智能的選擇器。class 即是一個經典的非智能選擇器由於它不是做爲語義約定的一部分出現的。你能夠靈活地命名和組織類,但須要必定的思考;除非你在文檔上應用它們,不然它們不會自動地執行任何事情。
使用非智能選擇器是很消耗開發時間的,由於咱們須要手動地爲每個選擇器添加對應的不一樣的樣式並把類名複製到每個須要應用此類的元素。若是咱們沒有 p 標籤,咱們不得不使用非智能選擇器來管理段落,例如在每個段落元素中使用一個 .paragraph
類來指明。這樣作的其中一個缺點是這些樣式表不是可移植的,由於你不能再沒有爲HTML文檔的標籤指定相應的類名的狀況下而應用這些樣式到所須要的元素當中。
非智能選擇器有時候仍是有必要的,而且咱們不多人會徹底依賴智能選擇器。然而,一些非智能選擇器可能會由於在文檔的結構和表現之間搭配不當而變成「愚蠢的」選擇器。我將會談論.button
這個使用頻率極高的「愚蠢」的選擇器。
智能選擇器並不限制於HTML規範中所提供給咱們的基礎元素。想要構建複雜的智能選擇器,你能夠聽從上下文和功能屬性的組合來區分基礎元素。一些元素,例如<a>
,提供了大量的功能差別給開發者考慮和利用。其餘的元素,例如<p>
元素,任何情景中在明確的功能上沒什麼差別,但也會根據上下文來承擔輕微不一樣的角色。
1 header p { 2 /* styles for prologic paragraphs */ 3 } 4 5 footer p { 6 /* styles for epilogic paragraphs */ 7 }
像這樣的簡單後代選擇器是很是有用的,由於它們讓咱們可以從視覺上看出一個元素的不一樣類型而無需從物理上更改底層的文檔。這是整個樣式表發明的緣由:既促進物理上的分離而又無需破壞那些存在於文檔和設計之間的概念上的相互關係。
不可避免的,一些OOCSS的粉絲們對這樣的後代選擇器是有點不太認同的,它們更喜歡像下面這個例子那樣來作標記,這是從BEM的「定義」文檔中找到的。
1 <ul class="menu"> 2 <li class="menu__item">…</li> 3 <li class="menu__item">…</li> 4 </ul>
我不會再對後代選擇器做進一步的討論,由於我肯定你天天都在使用它們,除非你偏好於上面這種過量的概述。換言之,咱們接下來會集中於屬性選擇器和屬性中描述的功能所帶來的差別。
即便是那些CSS和HTML之間的概念分離的擁護者也樂於認可一些屬性——除了類和自定義數據屬性之外的大多數的屬性,實際上和文檔的內部工做的有重要關係的。沒有href
屬性你的超連接不會連接到任何東西。沒有type
屬性,瀏覽器沒法知道渲染哪個類型的input元素。沒有title
屬性,你的abbr
元素則可能表明任何東西。
像這樣的屬性有助於改善文檔細節的語義化,不然你須要去確認主題元素是否正確被渲染以及運做。若是它們不存在,那麼它們應該被創造,若是它們已經存在了,那爲何不適用它們呢?你不可以只寫CSS而不寫HTML吧。
REL屬性
rel
屬性是連接關係的一個標準屬性,是一個描述連接的具體的用途的一個方法。並非全部的連接的功能都是相同的。得益於衆多的WordPress的使用者,rel="prev"
和rel="next"
成爲兩個最普遍採用的值,並有助於描述分頁博客內容的每一個單獨頁面之間的關係。從語義上來講,一個擁有rel
屬性的a標籤仍然是一個a
標籤,但咱們已經能更加具體地表現它了。這和類不相同,這種具體是從語義上間接表現的。
rel
屬性應該只被用在合適的地方,由於它們是被HTML的功能規範所維護的,並能所以被不一樣的用戶代理採用從而提升用戶體驗和搜索引擎的精確度。那麼,你曾像下面這樣爲連接添加過樣式嗎?使用簡單的屬性選擇器,如:
1 [rel="prev"] { 2 /* styling for "previous links" */ 3 } 4 5 [rel="next"] { 6 /* styling for "next" links */ 7 }
屬性選擇器被全部的瀏覽器所支持除了最古老和落後的瀏覽器(IE6),所以只要這個屬性存在於標籤中的時候沒有任何理由不去使用它們。在它的優先級方面,它和類具備相同的權重值。然而,我記得它被建議,咱們應該將文檔和表現語義分離。我不想浪費這個rel
屬性,因此我最好元素設置一個毫無心義的屬性並經過它來進行樣式的添加。
1 <a href="/previous-article-snippet/" rel="prev" class="prev">previous page</a>
此處首先要注意的第一件事情是,上面元素中惟一沒有對文檔的語義有幫助的是類這個屬性。換句話說,類在上面的文檔中式惟一的沒有起到什麼功能上的做用的東西。在實際中,這意味着類是惟一的打破了分離定律的並被解釋爲:它實際存在於文檔中卻又沒對文檔的結構有任何幫助。
好了,說了這麼多抽象的概念,但它的可維護性方面如何?你們都接受使用class
做爲樣式鉤子,讓咱們看看當經過編輯或重構時移除了一些屬性的時候會發生什麼事情。假設咱們使用了僞元素來爲[rel="prev"]
連接的文字前面添加一個左指箭頭:
1 .prev:before { 2 content: '\2190'; /* encoding for a left-pointing arrow ("←") */ 3 }
移除類的同時也會同時移除了僞元素,反過來講這個舉動會將箭頭所移除。但沒有了這個箭頭,將沒有其餘的東西能告訴咱們連接現存的prev
關係。出於一樣的緣由,移除rel
屬性也會致使箭頭的不完整:由於雖然class
會繼續讓這個箭頭得以顯示,卻老是使文檔的狀態關係丟失。只有直接的經過語義的屬性來給出樣式並應用,你才能讓你的代碼和你本身保持真實。只要是文檔中存在的真實的功能,你就要讓它被看見。
我能夠想象你正在想什麼:「這頗有趣,但在超連接中有多少個這樣的語義樣式鉤子?我仍是會不得不依賴類來應用樣式。」那麼請你看看下面不一樣的連接功能的不徹底的列表吧,全部都是以a
元素爲基礎的:
這就是連接功能上的差別,全部的類型均可以被用戶代理所識別。如今讓咱們思考一個問題,爲了讓全部的這些具體連接類型都執行不一樣的功能,它們必需要有不一樣的屬性。也就是說,爲了執行不一樣的功能,連接的書寫形式是須要有所變化的;而且,若是它們書寫形式不一樣,它們就能夠經過這個來添加不一樣的樣式。
在準備這篇文章的時候,我對一個構思做了一個檢驗,命名爲Auticons。Auticons是一個圖標字體和樣式表,用於自動地爲連接添加樣式。裏面的全部選擇器都是屬性選擇器而沒有一個類,爲格式良好的超連接來調用樣式。
在許多的案例中,Auticons 對href
值的一個子集進行了查詢來肯定超連接的功能。經過的它們的屬性值的開頭或結尾來對相應的元素添加樣式,又或者是根據它們屬性值是否包含了一個指定的字串來查找對應元素也是可能的。下面是一些常普通的例子。
安全協議 每個格式良好的URL(例如:絕對地址的URL)會以一個URI scheme 加一個冒號開始。在網絡中咱們最多見的就是http:
,可是mailTo:
(用於簡單郵件傳輸協議SMTP)和tel:
(用於電話號碼)也是很經常使用的。若是咱們能夠知道超連接的href
的值會如何開始,咱們能夠利用這個約定來做爲樣式鉤子。在下面的用於安全頁面的例子,咱們使用^=
比較器,意思爲「以...開始」。
1 [href^="https:"] { 2 /* style properties exclusive to secure pages */ 3 }
在Auticons 中,根據一個特定的用於識別href
屬性的語義模式,連到安全頁面的連接用一把鎖來作裝飾。這樣作的優勢是:
http
協議同時用做比喻的掛鎖也會消失。當應用於動態內容的時候,這個選擇器顯得至關地智能。由於安全連接具備它特定的URI scheme,因此屬性選擇器可以預料到它的調用:一旦編輯器鍵入一些包含安全連接的內容,連接便會自動應用樣式來給予用戶一個它是一個安全連接的感受。由於不須要什麼類以及對HTML進行編輯,因此簡單的Markdown 中的連接是這樣的:
[Link to secure page](https://payment.example.com/)
但要注意的是使用 [href^="https:"]
也不是永遠正確的,由於也不是全部的 HTTPS 真正安全的。不過,這僅僅是當瀏覽器自己不太可靠的狀況下。專業的瀏覽器都會在顯示 HTTPS 的時候在地址欄渲染一個掛鎖。
文件類型
正如我說過的,你也能夠經過 href
屬性以什麼結尾來爲超連接添加樣式。在實踐中,這意味着你可使用CSS來指出連接所指向的文件類型。Auticons 支持.txt
, .pdf
, .doc
, .exe
和其餘的一些格式,下面是.zip
格式的一個例子,使用$=
來決定href
以什麼結尾:
1 [href$=".zip"]:before, 2 [href$=".gz"]:before { 3 content: '\E004'; /* unicode for the zip folder icon */ 4 }
組合
你知道如何在一個元素中添加多個類的方法來創建樣式吧?很好,其實你能夠用屬性選擇器來幫你自動完成這些工做。讓咱們來對比一下:
1 /* The CSS for the class approach */ 2 3 .new-window-icon:after { 4 content: '[new window icon]'; 5 } 6 7 .twitter-icon:before { 8 content: '[twitter icon]'; 9 } 10 11 /* The CSS for the attribute selector approach */ 12 13 [target="_blank"]:after { 14 content: '[new window icon]'; 15 } 16 17 [href*="twitter.com/"]:before { 18 content: '[twitter icon]'; 19 }
(注意,*=
比較器的意思是「內容」,若是href
的值包含字串twitter.com/
,那麼樣式便會應該到該元素上)
1 <!-- The HTML for the class approach --> 2 3 <a href="http://twitter.com/heydonworks" target="_blank" class="new-window-icon twitter-icon">@heydonworks</a> 4 5 <!-- The HTML for the attribute selector approach --> 6 7 <a href="http://twitter.com/heydonworks" target="_blank">@heydonworks</a>
任何負責添加一個到Twitter 頁面的超連接的內容編輯器,如今只須要知道兩件事:URL和如何在新標籤中打開。由於屬性選擇器能幫助他們找到對應的超連接。
繼承
還有一些沒有考慮到的地方是:若是有一個不匹配任何屬性選擇器的連接呢?若是這個超連接是一個普通的舊超連接呢?這個選擇器是一個很容易被記住的而且追求性能極致的人會很樂意聽到這種話「已經沒有別的比它還要更簡練了」。
層疊的屬性選擇器的繼承性與和類層疊在一塊兒的時候是同樣的。首先,它會對你的a
添加樣式 —— 假設是一個 text-decoration: underline
規則來提升連接的可訪問性;而後使用你所提供的屬性選擇器來爲相應的a
元素進一步添加層疊的樣式。像IE7 這樣的瀏覽器並不徹底支持僞元素。但由於繼承的關係,連接仍是會應用a
選擇器中的樣式。
1 a { 2 color: blue; 3 text-decoration: underline; 4 } 5 6 a[rel="external"]:after { 7 content: '[icon for external links]'; 8 }
在下面的部分,咱們會詳述咱們這個CSS書籤的結構來說解代碼上的錯誤。在作這件事前,首先讓咱們來看看可能會有什麼糟糕的選擇器潛入咱們的工做流程中。
OOCSS的信徒們仍然堅持使用類由於它們是可重用的,就像組件同樣。所以,.button
比#button
更好。不過,我能想到更好的按鈕樣式的選擇器。它的名字也很容易記住。
The <buttonelement represents a button. – W3C Wiki
Topcoat是一個OOCSS的基於BEM的UI框架,來自Adobe。Topcoat中的各類各樣的按鈕樣式代碼超過了450行,若是把註釋塊也加進去的話。裏面的註釋塊建議咱們用相似這個例子的方式來應用按鈕的樣式。
1 <a class="topcoat-button">Button</a>
這個不是一個button。由於,若是它是一個按鈕,應該是使用<button>
來作標籤。實際上,在每個咱們已知的瀏覽器中,若是使用<button>
來表現一個按鈕而不添加任何樣式,它默認看起來也會像一個按鈕。但上面這個例子不是的,由於它用的是<a>
標籤,本應該是表明一個超連接,實際上,它缺乏一個href
,這意味着它甚至不算是一個超連接。在技術上,它只是一個佔位符,一個沒有完成的不完整的超連接。
一隻穿着鯊魚服裝的小狗並非鯊魚
Topcoat的CSS中的示例僅僅是一個範例,但前提是類定義了元素而且HTML不是欺騙性的(你應該使用button標籤而不是a標籤來描述按鈕)。再多的「有意義的斷字」的類名添加也不能彌補你這樣醜陋地使用非智能選擇器和犯下的代碼上的錯誤。
更新:由於寫了這篇文章,Topcoat.io 已經使用<button>
標籤來取代上面那個例子。這簡直太棒了!然而,我對它們使用.is-disabled
類來指明這個按鈕是禁用的而忽略了disabled
屬性持保留意見。你能夠在評論區看到我和Topcoat 的表明在這方面的討論。對與促進OOCSS 所帶來的WEB標準的災難,你能夠在 semantic-ui.com中自行發現,它們示例中的「標準按鈕」竟然是一個包含空的<i>
標籤的<div>
標籤。
看見是麼就是什麼
「若是它看起來像只鴨,游泳時也像只鴨,叫聲也像只鴨,那麼它多是一隻鴨。」
一個裝飾得像按鈕同樣的連接,而且還能觸發像點擊按鈕那樣的Javascript 事件,對不少人來講,它是一個按鈕。然而,這隻意味着它已經經過了前兩個階段的「鴨測試」。爲了讓全部的用戶可以運用概括推理和辨別按鈕,它也必須像這樣。由於它仍然是一個連接,儘可能避免這種沒必要要的混淆,由於這種輔助技術的使用者沒有追求一個完美語義但這又剛好是咱們應當承擔的職責。
儘管如此,有些人仍是堅持用a
做爲按鈕的標籤。超連接是比較容易徹底從新地樣式化的一個元素。若是選擇a
標籤做爲元素,那麼只有一個辦法讓它接近真正的按鈕。你猜對了:你必須使用WAI ARIA role 屬性值來指明它的含義。能夠僅僅經過下列的屬性選擇器來確認一個超連接由於某些緣由看起來像是一個按鈕。
1 [role="button"] { 2 /* semantic CSS for modified elements that are announced as 「button」 in assistive technologies */ 3 }
「CSS給予了class 屬性強大的力量,做者能夠基於那些沒有任何表現的元素(例如DIV和SPAN)在想象中設計他們的「文檔語言」,並經過class 屬性來賦予他們樣式信息。做者應該避免這種行爲即便這種文檔語言的結構元素常常獲得你們承認和接受它們的意義。」 – 「選擇器,」 CSS Level 2, W3C
咱們具備a
和 button
兩個元素的緣由是爲了在語義上劃分兩種徹底不一樣的功能交互。超連接表明着你將會去到的某個位置的符號,而按鈕是做爲事件或者動做的觸發源。一個是關於位置移動的,另外一個則是側重於轉換的。一個是促進脫離的,另外一個是促進結合的。
爲了確保咱們不會作什麼愚蠢的事情來讓咱們的按鈕和超連接產生混淆。咱們會建立一個使用智能屬性選擇器的CSS書籤並來測試兩個元素各自的有效性和質量。
受到Eric Meyer的文章的一點啓發以及從DiagnostiCSS 中獲取了一些線索,這個樣式表會結合屬性選擇器和:not
選擇器(或者非僞類) 來在HTML 中把問題高亮出來。與其餘的兩種實現不一樣,它會使用僞元素來將錯誤打印到屏幕上。每個錯誤都會採用漫畫字體以及粉紅色的背景來顯示。
經過把功能和表單鏈接起來,咱們能夠看到醜陋的HTML 會間接地致使醜陋的 CSS。這是設計師濫用文檔帶來的後果。嘗試一下把revenge.css
保存到你的CSS書籤中,並單擊這個書籤以在任何你喜歡的頁面觸發它。注意:它不會在服務在https協議上的頁面中起做用。
規則1
若是它是個超連接,那它就應該有
href
屬性。
1 a:not([href]):after { 2 content: 'Do you mean for this to be a link or a button, because it does not link to anything!'; 3 display: block !important; 4 background: pink !important; 5 padding: 0.5em !important; 6 font-family: 'comic sans ms', cursive !important; 7 color: #000 !important; 8 font-size: 16px !important; 9 }
注意:在這個例子中我並非要測試屬性的值,而是測試這個屬性是否有被設置,也就是說,[href]
匹配的是任何含有href
屬性的元素。這個測試僅僅適用於超連接。這個測試能夠這樣來理解,「對於每個不具備href
屬性的元素,爲其添加一個僞元素並在僞元素中報告錯誤提示。」
規則2
「若是這個超連接具備
href
屬性,那這個屬性應該具備值。」
1 a[href=""]:after, a[href$="#"]:after, a[href^="javascript"]:after { 2 content: 'Do you mean for this link to be a button, because it does not go anywhere!'; 3 /*... ugly styles ...*/ 4 }
注意:若是這個href
屬性的值爲空或者以# 結尾又或者是使用Javascript,那麼它應該是被用做了非<button>
標籤實現的按鈕。注意我使用的是「以javascript
開始」,這樣能夠避免其使用的是javascript:void(0)
這樣的值。但咱們也不能期望它老是以這種方式書寫。
規則3
「若是它使用了button 類,那它理應是一個按鈕,至少在可訪問性層上。」
1 .button:not(button):not([role="button"]):not([type="button"]):not([type="submit"]):not([type="reset"]):after, 2 .btn:not(button):not([role="button"]):not([type="button"]):not([type="submit"]):not([type="reset"]):after, 3 a[class*="button"]:not([role="button"]):after { 4 content: 'If you are going to make it look like a button, make it a button, damn it!'; 5 /*... ugly styles ...*/ 6 }
注意:這個例子中,咱們爲你展現了,當測試屬性值的時候,你能夠怎樣來使用鏈式的否認。每個選擇器能夠像這樣理解:「若是一個元素具備一個類指明它是一個按鈕,但它卻不是一個按鈕元素,而且沒有一個正確的role 值來使它在可訪問性層爲一個按鈕,並且它也不是一個按鈕類型的input
元素,那好吧。。。你在說謊。」我不得不使用[class*="button"]
來捕獲Topcoat 裏面沒有使用role
來成爲實際按鈕的超連接中應用的不一樣的類(多達62種!)。我注意到有一些開發者在按鈕的父元素上使用button-container
和其餘類似的類名,這就是爲何a
修飾符被包含在裏面的緣由。你能夠注意到在Twitter Bootstrap 中使用了.btn
類,(若是你仔細閱讀了它的組件文檔)你會知道這沒法肯定是否使用連接仍是按鈕來做爲按鈕。
規則4
若是一個元素具備
role="button"
,那麼即便沒有Javascript它也應該能連接到某個地方。
1 a[role="button"]:not([href*="/"]):not([href*="."]):not([href*="?"]):after { 2 content: 'Either use a link fallback, or just use a button element.'; 3 /*... ugly styles ...*/ 4 }
注意:咱們能夠至關地肯定不包含/
,.
(一般存在於文件拓展名的前面)或?
(查詢字符串的開端)其中之一的href
應該是假的。使連接表現地像按鈕而且當javascript開啓並return: false
的時候是很好的。緣由是,當javascript關閉時它也可以連接到某個地方。實際上,這僅僅是我可以想出來的不使用<button>
的一個合理的理由。
規則5
「你不可以禁用一個超連接。」
1 a.button[class*="disabled"]:after, 2 a.btn.disabled:after, 3 a[class*="button"][class*="disabled"]:after { 4 content: 'You cannot disable a hyperlink. Use a button element with disabled="disabled".'; 5 /*... ugly styles ...*/ 6 }
注意:甚至連很古老的用戶代理也能識別disabled
屬性,所以咱們能夠恰當地把使用在一些合適的元素中。上面的例子能夠看出,你能夠鏈接屬性選擇器,就好像你鏈接多個類同樣:在最後的三個選擇器,咱們聲明,「若是一個超連接的類中包含button
字串和disabled
字串,就會爲其打印錯誤信息。」Twitter Bootstrap 使用第二種形式,.btn.disabled
,在它的樣式表中,但並不包含a
前綴。若是是用在超連接中咱們只會認爲它是一個錯誤。
規則6
「在表單中的按鈕應該具備明確的類型。」
1 form button:not([type]):after { 2 content: 'Is this a submit button, a reset button or what? Use type="submit", type="reset" or type="button"'; 3 }
注意:咱們須要肯定表單中的按鈕是否具備明確的類型,由於一些瀏覽器會把全部沒有明確類型的button
元素設置爲type="submit"
。若是咱們表單中的按鈕具備其它的母的,咱們必須絕對保證該按鈕的類型不是submit
。
規則7
「不管是按鈕仍是超連接都應該具備一些內容在裏面或者是具備ARIA label。」
1 a:empty:not([aria-label]):not([aria-labelledby]):after, 2 button:empty:not([aria-label]):not([aria-labelledby]):after, 3 button:not([aria-label]):not([aria-labelledby]) img:only-child:not([alt]):after, 4 a:not([aria-label]):not([aria-labelledby]) img:only-child:not([alt]):after { 5 content: 'All buttons and links should have text content, an image with alt text or an ARIA label'; 6 /*... ugly styles ...*/ 7 }
注意:按鈕和連接並無什麼明確的用途 —— 在文本和圖像的形式上 —— 是至關假的。最後的兩個選擇器是我寫過的最複雜的選擇器了。對於超連接的版本,這個選擇器應該是這樣理解的,「若是一個超連接不具備aria-label
屬性或aria-labelledby
屬性,而且它只包含一個圖片元素做爲內容,但這個圖片又不具備alt
屬性,那就會打印相關的錯誤信息。」另外,注意這個「:empty
選擇器」。存在爭論的是,那些非自動閉合的元素永遠不應被置爲空。
在上面的例子中我所用來描述的這些選擇器和模式並非想嘗試一些不一樣的而寫一些東西。屬性選擇器也不是什麼新鮮事物。IE 6是惟一的不支持它的瀏覽器。我使用它們的緣由是我沒有時間和精力在CSS上寫了一遍選擇器還要在徹底地在HTML在寫一遍。我在個人頁面的頭部使用[role="banner"]
而不使用.page-header
是由於這是我惟一知道的方法 —— 基於能看到預期的視覺效果 —— 並可以把導航標誌放在正確的位置。
沒有所謂的語義的CSS,只存在語義的HTML 和它的可見形式。在這篇文章中我已經展現了這些東西,經過將web頁面的功能和構成直接地結合,你能夠創建獎勵和懲罰的機制。一方面,你能夠設置選擇器對那些被正確使用的標籤來添加可見的圖案;另外一方面,你能夠找到那些醜陋的錯誤的方式應用的標籤結構並在頁面上打印它們的錯誤。
老實的說,並非全部的樣式鉤子都是徹底語義的和智能的。類被描述爲一些須要應用的元素以及還沒有成爲標準的屬性的填充物。所以你能夠發現 .footer
變成了 <footer>
以及 type="text"
(經過javascript來驗證url)變爲能夠直接使用type="url"
來驗證url 。其餘時候,它在作非語義的佈局基於網格框架的腳手架時是很是有用的。
然而,當你決定給予CSS本身徹底獨立的邏輯時,在功能和結構之間必定會產生沒必要要的爭執。在這種狀況下,你只有提升本身的警戒才能讓它們不會難以理解和失去效果。更糟糕的是,追求寫徹底語義化的類的時候每每會讓你陷入「什麼是語義化的類」的沒完沒了的討論當中。你會開始用更少的時間來用遙控器操做電視機而變得花費更多時間站在前面,思考如何使用你的遙控器。
生命很短,請珍惜時間。
譯者手語:整個翻譯依照原文線路進行,並在翻譯過程略加了我的對技術的理解。若是翻譯有不對之處,還煩請同行朋友指點。謝謝!
白牙
互聯網開發者,關注Web應用開發,前端交互設計。多多交流,願與你們共同進步。
如需轉載煩請註明出處:
英文原文:http://coding.smashingmagazine.com/2013/08/20/semantic-css-with-intelligent-selectors/