CSS偽類偽元素

CSS選擇器大致可以分成5類:基本選擇器,層次選擇器,屬性選擇器,偽類,偽元素。基本,層次,屬性選擇器比較容易理解,畢竟它們選擇的對象都屬于DOM中看得見摸得著的元素。但偽類和偽元素相對比較抽象,稍微有一點點理解上的難度。本篇就是我對偽類和偽元素的理解。

先介紹一下偽類和偽元素有什么區別?其實這是個純概念上的問題,就算不理解也不影響實際的使用。但作為一個CSSer,概念這種東西有時候就像地基,地基越牢固,將來大廈也越堅挺。

偽類就是給既存的元素模擬新添加一個類來實現某種效果。偽元素就是模擬新添加一個元素來實現某種效果。不明白?舉個例子就明白了。

用偽類:first-child將第一個p設成紅色:

p:first-child {color: red}

<div>
  <p>第一個段落</p>    //我將變成紅色
  <p>第二個段落</p>
</div>

等價于手動給DOM元素添加類:

.first-child {color: red}

<div>
  <p class="first-child">第一個段落</p>
  <p>第二個段落</p>
</div>

那偽元素呢?用偽元素::first-letter給第一個字設成紅色:

p::first-letter {color: red}

<div>
  <p>第一個段落</p>
  <p>第二個段落</p>
</div>

如果不用偽元素,你需要多加一個元素(如span)這樣來實現:

.first-letter {color: red}

<div>
  <p><span class="first-letter">第</span>一個段落</p>
  <p>第二個段落</p>
</div>

再回過頭感受一下:偽類就是給既存的元素模擬新添加一個類來實現某種效果。偽元素就是模擬新添加一個元素來實現某種效果。現在我們來看看具體有哪些偽類和偽元素。

偽類:

可細分6類:動態,UI元素狀態,目標,語言,結構,否定

動態偽類選擇器::link:visited:hover:active:focus。非常常用,從名字就能開出用途(事實上所有偽類選擇器從名字上都能看出用途),具體就不贅述了。太基礎的東西還是自行參考W3C吧

UI元素狀態偽類選擇器::checked:enabled:disabled。常用且簡單,不贅述。

目標偽類選擇器::target用來獲取錨點#部分。頁面實現跳轉定位很多都是使用a標簽的錨點來來定位。其實背后的原理是a標簽的href屬性能改變瀏覽器的location.hash,讓頁面在有滾動條的前提下實現頁面內跳轉。:target的作用就是獲取跳轉的目標元素,如下可以獲取到id為logo的div:

<div id="logo">
  …
</div>
<a href="#logo">jump to logo</a>

語言偽類選擇器::lang根據lang屬性匹配元素,如

<html lang="en">    //可在html標簽上設,也可以<body lang="en">標簽里設
:lang(en) { …… }    //根據頁面的不同的語言(如英語和法語)對不同DOM元素進行處理
:lang(fr) { …… }

結構偽類選擇器::first-child:last-child:nth-child(n):nth-last-child(n):nth-of-type(n):nth-last-of-type(n):first-of-type:last-of-type:only-child:only-of-type:root:empty

:first-child看名字就知道了,第一個孩子。等同于:nth-child(1)。

:last-child看名字就知道了,最后一個孩子。等同于:nth-last-child(1)。

:nth-child(n)該標簽是某類型,并且是父標簽里第n個孩子。反之:nth-last-child(n)就是倒數第n個孩子。

:nth-of-type(n)父標簽里第n個某類型的孩子。反之:nth-last-of-type(n)父標簽里倒數第n個某類型的孩子。

:nth-child(n)和:nth-of-type(n)這兩個偽類的參數n從0開始,你可以寫出任意喜歡(奇葩)的公式,如n+4,-n+6,3n-2等,當結果值等于或小于0時直接被無視掉。當然最常用的還是奇數2n+1和偶數2n,因此有兩個關鍵詞odd和even。那它倆的差異在哪里呢?

例如div下有兩個p,我們想將第二個p變成紅色,用p:nth-child(2) { color: red; }和p:nth-of-type(2) { color: red; }都可以。但意義是不同的,前者表示該標簽是p且是父標簽里第二個孩子。后者表示父標簽里第二個p。

現在把DOM結構變一下:div下依次有一個a,兩個p。我們想將第二個p成紅色,用p:nth-child(2) { color: red; }就不對了,會將第一個p(因為該標簽是p且是父元素的第二個孩子)設成紅色。用p:nth-of-type(2) { color: red; }才能將第二個p設成紅色。

:first-of-type:last-of-type同理可知就是父標簽里第一個/最后一個某類型的孩子。等同于:nth-of-type(1),:nth-last-of-type(1)。

:only-child父標簽里僅有一個孩子。

:only-of-type父標簽里唯一一個該類型的孩子。有什么用呢?例如當div里只有一張img時不浮動。當div里有多張img時,讓它們從左至右依次浮動顯示。你可以用div > img:only-of-type {…}來控制當div里只有一張圖片和不止一張圖片時采用不同的布局

:root匹配根元素,HTML中根元素始終是html,等同于基本選擇器html

:empty表示當元素里面什么都沒有的時候(包括空格、標簽內換行)應用相關樣式,常用于高亮提示用戶搜索的結果為空。例如.xx:empty { background-color: red; },div里無內容時背景色成紅色。div里有內容時無背景色。但要注意偽元素不算內容,如.xx::after { content: 'hello'; },此時div里顯示字但背景色仍舊是紅色。想想也知道::before::after是偽元素,不是真實元素,因此不會影響:empty判斷。而且因為偽元素不在DOM樹內,你無法取得::before, ::after偽元素生成的content。

否定偽類選擇器::not,例如不hover時顯示某效果li:not(:hover)。

偽類結合起來用能發揮更強大的作用。例如常見的漸進式需求,當列表項少于5項時用顯示預覽行文字,當列表項多于5項時用不顯示預覽行文字。這樣條目少時,增加預覽行文字便于用戶預覽,且讓頁面不顯得非常空。條目多時,不顯示預覽行,讓用戶更多地關注條目名,便于用戶選取。你如何處理呢?

先無腦對li應用上顯示預覽行的式樣。然后用li:nth-child(5),可惜它只能選中第5項,而我們想要的是當數量>=5時,所有li都應用隱藏預覽行文字的式樣。就算改成li:nth-child(5) ~ li也不對,它將第5個及之后的li應用上了新式樣,前4個仍舊是舊的式樣,等同于li:nth-child(n+5)。由于沒有“回頭看”的方式,你可能放棄CSS而用JS來處理。

其實CSS是有技巧能實現“回頭看”的。當列表項數量為5時是臨界點。因此當數量正好為5時,取第1項,再選中第1項之后的所有項即可:

li:first-child:nth-last-child(5),
li:first-child:nth-last-child(5) ~ li { 
    ... 
}

如果沒明白,再解釋一下上面的代碼。第一行表示第一個元素是從后往前數的第5個元素。第二行是當數量逐漸增加到5時,選中從第一個元素之后的所有元素。

偽元素

用于定位文檔中包含的文本,但無法在DOM樹中定位。有::first-line::first-letter::before::after::selection(CSS3之前是一個冒號,CSS3后變成兩個冒號,用于和偽類區分開)

::first-line::first-letter分別是首行和首字母

::before::after相當于在元素內部插入兩個額外的標簽,最適合也是最推薦的應用就是圖形生成

::selection用于匹配選中的文本(注意Firefox下是::-moz-selection)。該偽元素只接受兩個屬性background和color

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,002評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,400評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,136評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,452評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,818評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,997評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,552評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,292評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,510評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,721評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,235評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,480評論 2 379

推薦閱讀更多精彩內容