一.lvha
實際上應該是lvfha,即:瀏覽器
a:link {/* 未訪問過的超連接的樣式 */} a:visited {/* 訪問過的超連接的樣式 */} a:focus {/* 擁有焦點的超連接的樣式 */} a:hover {/* 鼠標懸停的超連接的樣式 */} a:active {/* 被用戶輸入激活的超連接的樣式 */}
這5個都是僞類,表示5種狀態,其中link與visited是超連接專用的,能夠分類到連接僞類,而focus,hover和active除了用於超連接還適用於其它元素,稱爲動態僞類ide
lvfha原則是說對超連接(帶href屬性的a標籤)應用上面的5個僞類時,應該遵照這種固定的順序代理
二.僞類與僞元素
僞類像類同樣,用來選擇DOM樹上本就存在的某個元素。選擇條件有兩種:code
狀態:元素是否處於某種特定狀態,例如用戶曾訪問過(link/visited),此刻擁有焦點(focus),處於某種語言環境(lang)事件
結構:元素是否知足某種DOM結構方面的要求,例如身爲長子的元素(first-child),以及CSS3新增的身爲根元素的元素(root)和一大堆的結構化僞類(nth-,-of-type等等)文檔
僞元素更像元素一些,用來選擇DOM樹上本不存在的元素(或某個元素的一部分)。比起僞類的繁榮你們族,僞元素就顯得有些伶仃了,到目前(2017/11/4)爲止,CSS3規範中仍然只有4個僞元素(CSS2.1就是4個):it
首字母:選擇元素包含的文本內容的首字母(文本內容包含來自子元素的,也就是說能夠跨標籤層級選擇文本)io
首行:選擇元素包含的文本內容的首行(同上)class
before:用於內容生成,在指定元素內容開頭的位置生成一個元素(生成的內容位於元素內容區裏)表單
after:用於內容生成,在指定元素內容結尾的位置生成一個元素(同上)
僞類與僞元素最大的區別是要選擇的目標內容是否存在於DOM上,存在就是僞類,不存在就屬於僞元素。換個角度看,想要爲文檔的某部份內容指定樣式,那麼先要(經過選擇器)選中這部份內容,此時會遇到兩種狀況:
目標內容剛好被某個標籤包起來了,對這整個標籤設置樣式就能達到目的
目標內容先後沒有標籤圈定範圍,沒法直接設置樣式,須要插入一個臨時標籤把目標內容圈起來,再對這個臨時標籤設置樣式
第一種狀況經過僞類來處理,用僞類選擇器把處於某種狀態或具備某些結構特徵的現有元素找出來,再應用樣式。第二種狀況要麼手動插入額外標籤,轉化成第一種狀況(有些場景經過添標籤也作不到,好比首行,或者跨標籤層級的場景),要麼經過僞元素來解決,至關於請瀏覽器幫忙插入虛擬標籤圈定目標內容,再應用樣式
P.S.關於CSS3選擇器的更多信息,請查看CSS選擇器分類總結
三.a標籤的6種狀態
lvfha僞類給超連接提供了5種狀態,第6種是指錨點,而不是超連接
link僞類存在的意義之一就是把超連接與錨點區分開,link僞類只匹配具備href的a標籤(即超連接),而非錨點
通常桌面瀏覽器環境下,a標籤的6種狀態及對應的觸發行爲分別是:
a {/* 處於任意狀態的a標籤,不管是超連接仍是錨點 */} a:link {/* 未訪問過的超連接 */} a:visited {/* 訪問過的超連接,點擊超連接再返回當前頁,這個超連接就處於visited狀態 */} a:focus {/* 得到焦點的超連接,tab鍵選中超連接或者長按超連接再移開鼠標 */} a:hover {/* 鼠標懸停的超連接,鼠標通過超連接時或懸停在超連接上時,這個超連接就處於hover狀態 */} a:active {/* 處於激活狀態的超連接,鼠標在超連接上按下時 */}
其中focus, hover, active不太好區分,focus是一種延續性狀態,而hover, active是短暫性狀態,進一步細分hover, active的話,後者是前者的一種特殊狀態(觸摸設備除外),例如:
a:focus {border: 1px solid green;} a:hover {border-color: red;} a:active {border-style: dashed;}
那麼下列連續操做對應的狀態和樣式分別是:
按下tab鍵 -> focus -> 綠色實線邊框 點擊其它空白處 -> a & link | visited -> 對應樣式 鼠標劃過期 -> hover -> 無邊框 鼠標懸停時 -> hover -> 無邊框 鼠標按下 -> focus & hover & active -> 紅色虛線邊框 鼠標移到超連接以外再擡起 -> focus -> 綠色實線邊框 (不點擊其它地方的話,超連接將一直處於focus狀態) 鼠標劃過期 -> focus & hover -> 紅色實線邊框
正由於focus是一種延續性狀態,因此要放在短暫性的hover, active以前,不然最後鼠標劃過期不會表現出hover樣式(根據層疊規則,先聲明的hover會被focus覆蓋掉)
由於focus, hover, active3個狀態有重疊,因此建議保持特定的聲明順序,讓層疊結果符合樣式表編寫者的預期。而link和visited是互斥的,不存在重疊,因此兩者的相對順序並不重要(vlfha也是合理的,「愛恨」順序只是好記)。一樣,因爲link/visited是永久性狀態,爲了讓短暫性狀態和持續性狀態有表現機會,就把focus/hover/active放在後面,讓長狀態的層疊優先級更低一些,因此就有了lvfha原則
另外,規範沒有明確說明focus, hover, active對應的狀態的起止條件:
CSS沒有定義哪些元素能夠處於上面的狀態,以及這些狀態怎樣進入和離開。腳本能夠改變元素是否對用戶事件作出響應,而且不一樣的設備和UA指向和激活元素的方式不一樣
CSS 2.1沒有定義若是一個’:active’或者’:hover’元素的父級是否是也處於這種狀態
(摘自5.11.3 動態僞類: :hover,:active與:focus)
因此不能肯定動態僞類的觸發行爲,也沒法肯定這幾個僞類適用於哪些元素(表單元素、div等可能支持也可能不支持),都取決於用戶代理的實現
四.組合僞類
建議遵循lvfha順序是考慮層疊規則,不然可能會被覆蓋,致使同名規則無效。例如:
a:hover {text-decoration: underline overline;} a:link {text-decoration: none;} a:visited {text-decoration: none;}
hover樣式(小技巧:鼠標劃過期同時顯示上劃線和下劃線)永遠不會生效,由於text-decoration屬性總會被下面兩條之一覆蓋掉
固然,前提條件是樣式規則存在衝突(同名屬性且來源、重要性、特殊性都相同)時,根據聲明順序來解決衝突,此時lvfha順序才真正起做用。換句話說,若是不存在樣式衝突,聲明順序並不重要
也就是說,經過其餘方式避免樣式衝突發生,就不用遵照lvfha順序了,例如經過組合僞類來把狀態展開:
/* 不要求順序 */ :link :visited :link:hover :visited:hover /* 要求順序 位於上2行以後 */ :link:active :visited:active /* 或者替掉上2行 不要求順序 */ :link:hover:active :visited:hover:active
展開以後就沒有重疊狀態了,讓每條規則都變成嚴格互斥的,天然就沒衝突了
P.S.注意:由於IE6-不能正確處理組合僞類,只認最後一個,因此lvha應用更廣(實際上組合僞類的語義更明確,沒有「隱藏的奇怪規則」)
另外,能夠層疊規則來實現特殊效果,例如:
// 用lhva實現只有未訪問的連接纔有hover效果 a:link {} a:hover {} a:visited {} a:active {}
頗有意思的小技巧,至關於:
a:link:hover {}
這就體現了組合僞類語義明確的優點
聯繫ayqy