CSS一個(gè)主要的優(yōu)勢(shì)就是對(duì)所有同類型的元素批量設(shè)置樣式。覺得沒啥了不起的么促王?試想一下犀盟,通過編輯一行CSS,你可以修改所有標(biāo)題的顏色蝇狼。隨心所欲修改任何你想要的樣式阅畴,這讓你專注在設(shè)計(jì)上而不是繁重的工作,下一次別人讓你修改下標(biāo)題迅耘,你只需簡(jiǎn)單的編輯然后重新加載贱枣,馬上就可以看到結(jié)果,所見即所得颤专。
當(dāng)然啦纽哥,CSS不能解決所有問題,你不能通過設(shè)置CSS來改變PNG圖片的colorspace栖秕,不過它可以提供一些全局的修改春塌。讓我們從選擇器和結(jié)構(gòu)開始吧。
基本的樣式規(guī)則
Grouping聚合
Class和ID選擇器
屬性選擇器
上面提到的class和ID的選擇器簇捍,其本質(zhì)還是元素屬性的選擇只壳。上面兩個(gè)小結(jié)中的語法主要是基于HTML,XHTML暑塑,SVG和MathML等這些標(biāo)記語言的吼句。而在其他的標(biāo)記語言中這些class和ID的選擇器就沒法用了。為了解決這個(gè)問題事格,CSS2中引入了屬性選擇器惕艳,方便用戶直接選擇標(biāo)簽的屬性及其對(duì)應(yīng)的值搞隐。按照不同的用法可以分為以下4中屬性選擇器:
- 簡(jiǎn)單屬性選擇器(simple attribute selectors)
- 精準(zhǔn)屬性值選擇器(exact attribute value selectors)
- 部分匹配屬性值選擇器(partial-match attribute selectors)
- 首部值屬性選擇器(leading-value attribute selectors)
簡(jiǎn)單屬性選擇器(simple attribute selectors)
如果你想要選擇某個(gè)特定的屬性,不管屬性的值远搪,那么你可以使用簡(jiǎn)單屬性選擇器劣纲。例如,要選擇所有h1元素中包含class屬性的那些终娃,改變其文本顏色為silver味廊,則可以這樣寫:
h1[class] {color: silver;}
<h1 class="hoopla">Hello</h1>
<h1>Serenity</h1>
<h1 class="fancy">Fooling</h1>
這一策略針對(duì)XML文檔很有效果,因?yàn)閄ML總是有一堆的元素和對(duì)應(yīng)的屬性名稱來描述事物的特征棠耕。
舉例來說余佛,對(duì)于一個(gè)想要太陽系行星的XML文檔,想要搜索行星邊上(標(biāo)記為pml-planet)有類似月球這種小行星(moons)的情況窍荧,可以像下面這樣查詢:
pml-planet[moons] {font-weight: bold;}
<pml-planet>Venus</pml-planet>
<pml-planet moons="1">Earth</pml-planet>
<pml-planet moons="2">Mars</pml-planet>
回到HTML中辉巡,這一特性可以用在很多地方,例如想要選擇所有帶有alt屬性的images蕊退,可以:
img[alt] {border: 3px solid red;}
再來一個(gè)例子郊楣,如果想要設(shè)置所有元素中包含title的元素
*[title] {font-weight: bold;}
另外一次性選擇多個(gè)屬性也是可以的,可以直接挨個(gè)寫下去瓤荔,例如:
a[href][title] {font-weight: bold;}
<a title="W3C Home">W3C</a><br />
<a >Standards Info</a><br />
<a title="Not a link">dead.letter</a>
結(jié)果是只有第一個(gè)W3C的元素被選中净蚤,可見多個(gè)[]之間是并集的關(guān)系。
針對(duì)某個(gè)特定的值做選擇
如果想把屬性的值限定為某個(gè)具體值來做更精確的查詢输硝,怎可以這樣:
a[] {font-weight: bold;}
有意思的是今瀑,任何對(duì)值得改變,比如上面鏈接http://www.css-discuss.org/about.html中的協(xié)議http到https点把,或是www沒有都會(huì)使該匹配消失橘荠。
屬性的匹配對(duì)元素element和attribute沒有任何限制,如果沒找到匹配的項(xiàng)郎逃,那么選擇器會(huì)直接忽略而不是再做模糊匹配等操作哥童。下面例子中只會(huì)匹配制定的第2個(gè)earth元素:
planet[moons="1"] {font-weight: bold;}
<planet>Venus</planet>
<planet moons="1">Earth</planet>
<planet moons="2">Mars</planet>
跟之前的簡(jiǎn)單匹配一樣,屬性也可以為多個(gè):
a[W3C Home"] {font-size: 200%;}
<a title="W3C Home">W3C</a><br />
<a
title="Web Standards Organization">Standards Info</a>
<br />
<a title="W3C Home">dead.link</a>
結(jié)果如下圖所示:
值得注意的是褒翰,很多人會(huì)認(rèn)為下面兩個(gè)是一樣的:
h1#page-title
h1[id="page-title"].
而事實(shí)上他們是有區(qū)別的贮懈,將會(huì)在后面的章節(jié)中介紹。
屬性值的部分匹配查詢
有些時(shí)候你希望能夠執(zhí)行部分屬性值得匹配优训,那么CSS中也提供了對(duì)應(yīng)的下面這些子字符串的匹配方式:
匹配類型 | 描述 |
---|---|
[foo~="bar"] | 查詢foo屬性中是否包含空格分隔的bar字符串 |
[foo*="bar"] | 查詢foo屬性中是否包含bar字符串 |
[foo^="bar"] | 查詢foo屬性中是否以bar字符串開頭 |
[foo$="bar"] | 查詢foo屬性中是否以bar字符串結(jié)尾 |
[foo|="bar"] | 查詢foo屬性中是否就是bar或是跟著一個(gè)橫杠(U+002D) |
一個(gè)特定的屬性選擇類型
可能上面最不好理解的就是|=這個(gè)了朵你,下面舉個(gè)例子:
*[lang|="en"] {color: white;}
<h1 lang="en">Hello!</h1>
<p lang="en-us">Greetings!</p>
<div lang="en-au">G'day!</div>
<p lang="fr">Bonjour!</p>
<h4 lang="cy-en">Jrooana!</h4>
因?yàn)閨=匹配字符本身(en)和以en-開頭的字符,所以上面的5個(gè)元素中前3個(gè)被選中型宙,后兩個(gè)落選。
~=的用法
~=最常出現(xiàn)的使用場(chǎng)景是在class的匹配中:
<p class="urgent warning">When handling plutonium, care must be taken to avoid the formation of a critical mass.</p>
p[class~="warning"] {font-weight: bold;}
另外值得一提的是上面的匹配和p.warning是等價(jià)的伦吠。
*=的用法
有時(shí)候你需要匹配屬性值中包含的某個(gè)部分妆兑,這是后*=就派上用場(chǎng)了魂拦。
span[class*="cloud"] {font-style: italic;}
<span class="barren rocky">Mercury</span>
<span class="cloudy barren">Venus</span>
<span class="life-bearing cloudy">Earth</span>
上面這個(gè)例子中,span的后面2個(gè)包含cloudy的元素被選中搁嗓。匹配必須是準(zhǔn)確的芯勘,如果在選擇器中包含空白,那么屬性值中也必須包含腺逛。而且屬性的名稱和值都是大小寫敏感的荷愕,Class名稱,標(biāo)題棍矛,URL和ID的值都是大小寫敏感的安疗,但是HTML的自身屬性值卻不是,因此下面的例子中仍然可以匹配到:
input[type="CHeckBoX"] {margin-right: 10px;}
<input type="checkbox" name="rightmargin" value="10px">
^=的用法
^=用于匹配以某個(gè)值開頭的屬性够委,例如:
a[href^="https:"] {font-weight: bold;}
a[href^="mailto:"] {font-style: italic;}
下面的例子匹配圖片的alt屬性以Figure開頭的元素:
img[alt^="Figure"] {border: 2px solid gray; display: block; margin: 2em auto;}
$=的用法
與上面^=類似荐类,只不過$=是判斷以某個(gè)字符串結(jié)尾的元素:
a[href$=".pdf"] {font-weight: bold;}
大小寫不敏感標(biāo)識(shí)符
CSS 選擇器 level 4中針對(duì)屬性選擇器引入了大小寫敏感選項(xiàng)-i,只要在屬性右方括號(hào)前加上i茁帽,就可以忽略大小寫玉罐,無視文檔語言的規(guī)則。
a[href$='.PDF' i]
匹配.pdf, .PDF, .Pdf等所有的pdf后綴字符潘拨。這一標(biāo)識(shí)符適用所有的屬性選擇器
使用Document結(jié)構(gòu)
css之所以強(qiáng)大是因?yàn)榻柚鷇ocument本身的結(jié)構(gòu)來實(shí)現(xiàn)功能吊输,所以如果要深入了解選擇器的機(jī)制就需要先了解下document的結(jié)構(gòu)。
document結(jié)構(gòu)中的“父子”關(guān)系
我們首先來看下document的結(jié)構(gòu)是如何組織的:
<html>
<head>
<base >
<title>Meerkat Central</title> </head>
<body>
<h1>Meerkat <em>Central</em></h1>
<p>
Welcome to Meerkat <em>Central</em>, the <strong>best meerkat web site on <a href="inet.html">the <em>entire</em> Internet</a></strong>!</p> <ul>
<li>We offer: <ul>
<li><strong>Detailed information</strong> on how to adopt a meerkat</li> <li>Tips for living with a meerkat</li>
<li><em>Fun</em> things to do with a meerkat, including:
<ol>
<li>Playing fetch</li> <li>Digging for food</li> <li>Hide and seek</li>
</ol> </li>
</ul>
</li>
<li>...and so much more!</li>
</ul>
<p>
Questions? <a href="mailto:suricate@meerkat.web">Contact us!</a> </p>
</body>
</html>
很多css的功能就是基于html document中的父元素-子元素形成的樹狀結(jié)構(gòu)铁追。在上面的層級(jí)過程中季蚂,每一個(gè)元素不是父元素就是子元素,來看看對(duì)應(yīng)的樹狀圖:
這里有必要強(qiáng)調(diào)下一個(gè)概念:所謂的parent-child父子關(guān)系和ancestor-descendant祖先-后代關(guān)系脂信,后者屬于更泛的概念癣蟋,一般的父子關(guān)系的層級(jí)限制在一層,而祖先后代的關(guān)系可以跨越多層狰闪,就比如上圖中的body是下面所有元素的祖先元素疯搅,而只是h1,p埋泵,ul幔欧,p這四個(gè)元素的父元素。
body元素是瀏覽器默認(rèn)展示所有內(nèi)容的祖先丽声,而html則是整個(gè)document文檔的祖先礁蔗。正因如此,在一個(gè)HTML或是XHTML文檔中雁社,html元素同樣被稱為root元素(根元素)浴井。
后代選擇器
理解這一模型的第一個(gè)好處就是使用后代選擇器,例如你想要選擇h1下面的所有em元素霉撵,你當(dāng)然可以為每個(gè)滿足條件的em元素設(shè)定一個(gè)class磺浙,然而這往往比較費(fèi)時(shí)費(fèi)力洪囤,使用后代選擇器則非常簡(jiǎn)單:
h1 em {color: gray;}
后代選擇器其實(shí)很強(qiáng)大,能夠?qū)崿F(xiàn)很多HTML種無法實(shí)現(xiàn)的功能撕氧,舉個(gè)例子瘤缩,假定你有個(gè)文檔是左右布局的,左邊側(cè)邊欄(sidebar)伦泥,右邊是主要區(qū)域(main)剥啤。側(cè)邊欄背景藍(lán)色,main區(qū)域背景白色不脯,兩塊區(qū)域都包含很多鏈接府怯,但是因?yàn)槟悴豢赡茏x取側(cè)邊欄中的鏈接,所以你也就不能夠同時(shí)設(shè)置所有的鏈接跨新。而通過后代選擇器給兩個(gè)區(qū)域分別設(shè)置不同的類則非常輕松就實(shí)現(xiàn)了:
.sidebar {background: blue;}
.main {background: white;}
.sidebar a:link {color: white;}
.main a:link {color: blue;}
后代選擇器的另一個(gè)值得注意的特性就是沒有元素的就近原則(element proximity)富腊,換句話說,規(guī)則匹不匹配與元素間的距離(層級(jí)距離)沒啥關(guān)系域帐。舉例說明赘被,
div:not(.help) span {color: gray;}
div.help span {color: red;}
<div class="help">
<div class="aside">
This text contains <span>a span element</span> within.
</div>
</div>
我們來翻譯下上面的兩句css規(guī)則,第一句說的是祖先是div但沒有help類的span子元素的顏色置灰肖揣;第二句的意思是在div為祖先元素民假,且有help類的span子元素的顏色設(shè)置為紅色。那么結(jié)果來了龙优,這兩個(gè)規(guī)則將同時(shí)作用在上面的span元素上面羊异,那到底最終呈現(xiàn)的額是什么顏色呢?答案是紅色彤断,因?yàn)閮蓚€(gè)規(guī)則具有相同的權(quán)重野舶,那么紅色的規(guī)則是最后一個(gè),就會(huì)覆蓋上面一個(gè)宰衙,所以就顯示紅色平道。
選擇子類
有時(shí)候你還不想選擇任意的后代元素,而將選擇范圍限定在子類中供炼,那么就可以使用>(大于號(hào))來指定了:
h1 > strong {color: red;}
規(guī)則只會(huì)作用到下面的第一個(gè)h1元素一屋,第二個(gè)不會(huì),因?yàn)榈诙€(gè)strong還不是h1的直接子元素袋哼,中間隔著一個(gè)em冀墨。
<h1>This is <strong>very</strong> important.</h1>
<h1>This is <em>really <strong>very</strong></em> important.</h1>
注意h1>strong和h1 > strong是一樣的,可以忽略中間的空格涛贯。
選擇臨近的兄弟節(jié)點(diǎn)
兄弟節(jié)點(diǎn)值得是在dom結(jié)構(gòu)中在同一層級(jí)诽嘉,擁有相同父節(jié)點(diǎn)的元素集合。舉個(gè)例子,如果想要在h1后面的p設(shè)置樣式虫腋,可以這樣設(shè)置:
h1 + p {margin-top: 0;}
其中+號(hào)就是兄弟節(jié)點(diǎn)的標(biāo)識(shí)符身冬,為了更形象的理解,看下圖:
如果你寫了一個(gè)li + li {font-weight:bold;}岔乔,那么在下面的列表中只能選第2,第3個(gè)滚躯,第一個(gè)無法選中雏门。
注意坏挠,節(jié)點(diǎn)間的文本內(nèi)容是影響不了相鄰節(jié)點(diǎn)選擇器查詢的象泵,例如:
及時(shí)有文本加載兩個(gè)list中間,我們?nèi)钥梢酝ㄟ^ol + ul來選擇第二個(gè)list确沸。而如果我們將文本封裝在一個(gè)元素里面丧凤,例如p募闲,那么ol+ul就不起作用了,需要變成ol+p+ul才行愿待。
選擇緊接著的兄弟
Level 3的選擇器中引入了一個(gè)新的兄弟標(biāo)識(shí)符浩螺,稱之為通用兄弟選擇器(general sibling combinator),使用波浪號(hào)~來標(biāo)記。
<div>
<h2>Subheadings</h2>
<p>It is the case that not every heading can be a main heading. Some headings must be subheadings. Examples include:</p>
<ol>
<li>Headings that are less important</li>
<li>Headings that are subsidiary to more important headlines</li>
<li>Headings that like to be dominated</li>
</ol>
<p>Let's restate that for the record:</p>
<ol>
<li>Headings that are less important</li>
<li>Headings that are subsidiary to more important headlines</li>
<li>Headings that like to be dominated</li>
</ol>
</div>
針對(duì)上面的dom結(jié)構(gòu)仍侥,如果需求是要將h2并列的所有ol節(jié)點(diǎn)都設(shè)置為斜體要出,就可以這樣寫:
h2 ~ol {font-style: italic;}
來看下結(jié)果吧:
偽類選擇器
結(jié)合的偽類(combining Pseudo-Classes)
偽類是可以一起使用的,即所謂的鏈?zhǔn)椒▌t(chaining)农渊,舉個(gè)例子患蹂,如果想要設(shè)置未訪問的鏈接在hover的時(shí)候變成紅色:
a:link:hover {color: red;}
或者說把已訪問的鏈接在hover的時(shí)候設(shè)置為栗色:
a:visited:hover {color: maroon;}
而且寫的偽類的順序無所謂,再來個(gè)絕的砸紊,把語言偽類也設(shè)置上传于,固定是德語才起效果:
a:link:hover:lang(de) {color: gray;}
a:visited:hover:lang(de) {color: silver;}
不過得記著別用互斥的偽類,類似a:link:visited 這種寫法是非常愚蠢的醉顽,而且還不起作用沼溜。
結(jié)構(gòu)偽類
大多數(shù)的偽類都依賴于dom本身的結(jié)構(gòu),所有的偽類(無一例外)都是以單個(gè)分號(hào)開頭徽鼎,而后跟著一個(gè)具體的單詞盛末。
在開始講偽類之前需要澄清一件事,所有的偽類總是針對(duì)他們綁定的元素(attached)否淤,而不是其他悄但,看起來像是廢話,而其實(shí)對(duì)于一些結(jié)構(gòu)偽類來說石抡,將結(jié)構(gòu)偽類想成綁定后代元素的想法是常見的錯(cuò)誤檐嚣。
為了解釋清楚這個(gè)問題,那自己的真人真事說下更有意思。當(dāng)我的第一個(gè)孩子在2003年出生的時(shí)候嚎京,我把這個(gè)消息發(fā)布到了網(wǎng)上嗡贺。然后當(dāng)然就是一幫人表示祝賀,順帶開開css的玩笑鞍帝,而其中最狠的一個(gè)就是這樣寫的:
#ericmeyer:first-child
而其中除了問題就在于這個(gè)選擇器其實(shí)選擇的是我自己诫睬,而不是我的女兒,而且當(dāng)且僅當(dāng)我是我的父母的第一個(gè)孩子(當(dāng)然確實(shí)是這樣子)帕涌。那究竟如何改呢摄凡?
#ericmeyer > :first-child
這樣講夠形象了吧。所以在下面的章節(jié)中請(qǐng)記住選擇的是偽類綁定的元素蚓曼。
選擇根元素
借助:root可以選擇文檔的根目錄亲澡,不過對(duì)于HTML來說好像沒啥用,因?yàn)榭梢灾苯佑胔tml就可以直接獲取到根目錄了纫版。而其實(shí)床绪,:root在xml語言中將會(huì)非常有用,因?yàn)閤ml中根元素是不固定的其弊,例如RSS2.0中rss是根元素癞己,來看個(gè)例子吧:
:root {border: 10px dotted gray;}
body {border: 10px solid black;}
選擇空元素
通過:empty偽類可以選擇沒有子元素的空節(jié)點(diǎn),也包括文本節(jié)點(diǎn)梭伐。有人會(huì)問這有什么用呢末秃?答案是有些CMS想要將沒有實(shí)際內(nèi)容的元素隱藏掉,所以像p:empty{display:none;}就派上用處啦籽御。
注意练慕,有些情況下要看仔細(xì)了,什么才是真正的空技掏,中間有空格铃将,不算;中間有換行哑梳,也不算劲阎,比如下面這個(gè)例子,只有第1和第4個(gè)才是:
<p></p>
<p> </p>
<p>
</p>
<p><!—-a comment--></p>
為什么說第2個(gè)和第3個(gè)不是呢鸠真,因?yàn)榭崭窈蛽Q行會(huì)被解析為文本節(jié)點(diǎn)悯仙,所以就不為空了,最后一個(gè)中的注釋是不會(huì)被解析為內(nèi)容的吠卷。
看了上面的如果你想要選中頁面上所有的空元素是不是應(yīng)該這樣呢锡垄?*:empty {display:none;},如果真這樣寫就大錯(cuò)特錯(cuò)了祭隔,因?yàn)橄駃mg和input货岭,還有textarea等元素都會(huì)被識(shí)別為空元素而一同消失,img和img:empty效果是一樣的。
選擇唯一的子節(jié)點(diǎn)
如果你想要選中被一個(gè)鏈接包裹的圖片元素千贯,而且是唯一的一個(gè)子元素屯仗,那么就可以使用:only-child這個(gè)偽類。它可以幫助選擇所有歸屬于另一個(gè)節(jié)點(diǎn)的唯一子節(jié)點(diǎn)搔谴。一如既往的舉例說明魁袜,如果說你想要為是唯一子節(jié)點(diǎn)的圖片來添加一個(gè)邊框:
img:only-child {border: 1px solid black;}
假設(shè)在<p>元素中包含一個(gè)<img>,而且img是唯一的元素敦第,那么這個(gè)img也會(huì)被選中慌核,不管它的前后是否有文本內(nèi)容。來個(gè)實(shí)際例子申尼,選擇鏈接里面的圖片:
a[href] img:only-child {border: 2px solid black;}
<a ><img src="w3.png" alt="W3C"></a>
<a ><img src="w3.png" alt=""> The W3C</a>
<a ><img src="w3.png" alt=""> <em>The W3C</em></a>
針對(duì)這個(gè):only-child,需要記住兩件事:
- 你選擇應(yīng)用的元素是唯一的子節(jié)點(diǎn)元素垫桂,而不是對(duì)應(yīng)的父節(jié)點(diǎn)师幕,也就是搞清楚你到底選擇的是哪個(gè)元素;
- 當(dāng)把:only-child應(yīng)用到后代選擇器中時(shí)诬滩,層級(jí)關(guān)系不止限于父子關(guān)系霹粥。比如說a[href] img:only-child,那么這個(gè)img可以不是a的直接子節(jié)點(diǎn)疼鸟,也可以是后代后控。
上面的方案解決了選擇唯一節(jié)點(diǎn)的問題,但如果父節(jié)點(diǎn)中包含多個(gè)子元素空镜,那該如何選擇img呢浩淘?
<a ><b>?</b><img src="w3.png" alt="W3C"></a>
比如上面這個(gè),這時(shí)候就可以使用:only-of-type這個(gè)偽類:
a[href] img:only-of-type {border: 5px solid black;}
<a ><b>?</b><img src="w3.png" alt="W3C"></a>
<a ><span><b>?</b><img src="w3.png" alt="W3C"></span></a>
對(duì)比下這兩個(gè)偽類就會(huì)發(fā)現(xiàn)吴攒,:only-of-type匹配的是所有兄弟節(jié)點(diǎn)中是否包含這一元素张抄,而:only-child關(guān)注的是匹配的元素必須沒有兄弟節(jié)點(diǎn)。
section > h2 {margin: 1em 0 0.33em; font-size: 1.8rem; border-bottom: 1px solid gray;}
section > h2:only-of-type {font-size: 2.4rem;}
上面的例子該如何理解呢洼怔?對(duì)于section下的子階段署惯,如果有且只有1個(gè)h2,那么就會(huì)觸發(fā)第二個(gè)镣隶,不然的話樣式就取第一個(gè)极谊。
再來分析一個(gè)例子:
p.unique:only-of-type {color: red;}
<div>
<p class="unique">This paragraph has a 'unique' class.</p>
<p>This paragraph doesn't have a class at all.</p>
</div>
看看這個(gè)樣式會(huì)匹配哪個(gè)元素呢?答案是兩個(gè)都沒有安岂,因?yàn)樵赿iv下有兩個(gè)p轻猖,而only-of-type只允許有一個(gè)。
選擇第一個(gè)和最后一個(gè)子節(jié)點(diǎn)
想要針對(duì)一系列的子節(jié)點(diǎn)中的第一個(gè)或是最后一個(gè)節(jié)點(diǎn)配置樣式是非常常見的域那,例如導(dǎo)航欄的第一個(gè)tab bar元素蜕依,要是以前的話還必須為每個(gè)元素設(shè)置特殊的class,現(xiàn)在的話,偽類就可以幫我們實(shí)現(xiàn)样眠。
:first-child用于選擇第一個(gè)子節(jié)點(diǎn)
<div>
<p>These are the necessary steps:</p>
<ul>
<li>Insert key</li>
<li>Turn key <strong>clockwise</strong></li>
<li>Push accelerator</li>
</ul>
<p>Do <em>not</em> push the brake at the same time as the accelerator. </p>
</div>
如果css的樣式設(shè)置為下面這樣:
p:first-child {font-weight: bold;}
li:first-child {text-transform: uppercase;}
那么最終顯示的結(jié)果就是:
這里需要強(qiáng)調(diào)的一點(diǎn)就是偽類的翻譯友瘤,其實(shí)按照人的正常邏輯很容易誤以為像p:first-child應(yīng)該解析為p的第一個(gè)子節(jié)點(diǎn),而其實(shí)就像最早提及的檐束,偽類的翻譯更接近于as辫秧,就是p as first-child,作為第一個(gè)子元素的p被丧,這樣來理解就不會(huì)走入這個(gè)誤區(qū)盟戏。
和:first-child對(duì)應(yīng)的就是:last-child,還是拿我們上個(gè)例子來說甥桂,如果都改成last-child會(huì)是怎么樣呢柿究?
p:last-child {font-weight: bold;}
li:last-child {text-transform: uppercase;}
<div>
<p>These are the necessary steps:</p> <ul>
<li>Insert key</li>
<li>Turn key <strong>clockwise</strong></li> <li>Push accelerator</li>
</ul> <p>
Do <em>not</em> push the brake at the same time as the accelerator. </p>
</div>
有意思的是我們可以將兩者結(jié)合起來來實(shí)現(xiàn)一下上面說到的:only-child,其實(shí)看了答案以后就非常簡(jiǎn)單啦:
p:only-child {color: red;}
p:first-child:last-child {background-color: red;}
上面兩個(gè)選取的是同一個(gè)黄选。
選擇第一個(gè)或是最后一個(gè)類型
就像選擇子元素一樣蝇摸,也可以選擇對(duì)應(yīng)的類型。來看個(gè)例子:
table:first-of-type {border-top: 2px solid gray;}
那么針對(duì)下面的結(jié)構(gòu)办陷,藍(lán)色區(qū)域就是被選中的節(jié)點(diǎn):
再來看一個(gè)常用的例子貌夕,在table里面:
td:first-of-type {border-left: 1px solid red;}
<tr>
<th scope="row">Count</th><td>7</td><td>6</td>
<td>11</td>
</tr>
<tr><td>Q</td><td>X</td><td>-</td> </tr>
結(jié)果兩行tr中的第1個(gè)td都可以被選中,不過要是換成了:first-child那么只有第2個(gè)被選中了民镜。
和:first-of-type對(duì)應(yīng)的就是:last-of-type啡专,與之前類似,這里直接上之前例子結(jié)構(gòu)中的選擇結(jié)果:
更之前一樣制圈,下面兩個(gè)是一樣的效果:
table:only-of-type{color: red;}
table:first-of-type:last-of-type {background: red;}
選擇第n個(gè)子節(jié)點(diǎn)
借助:nth-child()偽類们童,在括號(hào)中填充整數(shù)或是簡(jiǎn)單的代數(shù)表達(dá)式,我們可以選擇任意序列的子元素鲸鹦。
不是說可以選擇任意子節(jié)點(diǎn)么病附,首先來試下第一個(gè),也就是:first-child對(duì)應(yīng)的等價(jià)表達(dá)式:
p:nth-child(1) {font-weight: bold;}
li:nth-child(1) {text-transform: uppercase;}
<div>
<p>These are the necessary steps:</p>
<ul>
<li>Insert key</li>
<li>Turn key <strong>clockwise</strong></li>
<li>Push accelerator</li>
</ul>
<p>Do <em>not</em> push the brake at the same time as the accelerator.</p>
</div>
如果我們把數(shù)值從1改成2亥鬓,那么p就沒有匹配的了完沪,而li將會(huì)匹配第二個(gè):
上面是純數(shù)字的例子,而更強(qiáng)大的是括號(hào)里面可以加入簡(jiǎn)單的代數(shù)表達(dá)式嵌戈,形式是固定的:an + b覆积,其中a,b是正整數(shù),而n是代表自增的變量熟呛。當(dāng)然an - b也是可以的宽档。
假定我們要選擇一個(gè)無序列表中的每3個(gè)間隔的列表項(xiàng),則可以這樣寫:
ul > li:nth-child(3n + 1) {text-transform: uppercase;}
代數(shù)表達(dá)式中的n是從0,1,2,3...一直到無窮大的序列庵朝,因此3n+1瀏覽器就解析為1,4,7,10,13吗冤。
注意所有的dom元素的序列序號(hào)是從1開始的又厉,因此如果在nth-child()的表達(dá)式中出現(xiàn)了小于1的值(0和負(fù)數(shù))是無效的,不會(huì)有任何元素被選中椎瘟。
因此一個(gè)常見的推論就是:nth- child(2n)用來選擇偶數(shù)項(xiàng)覆致,而:nth-child(2n+1)或是:nth-child(2n-1)用來選擇奇數(shù)項(xiàng)。當(dāng)然啦肺蔚,如果你嫌麻煩煌妈,也可以用現(xiàn)成的代號(hào):odd代表奇數(shù),even代表偶數(shù)宣羊,來看個(gè)例子吧璧诵。
上面就是選擇奇數(shù)的情況,另外如果你想使用負(fù)號(hào)的話就必須把加號(hào)去掉仇冯,向下面第二種情況之宿,解析器是直接忽略的。
tr:nth-child(4n - 2) {background: silver;}
tr:nth-child(3n + ?2) {background: red;}
如果要選擇第9個(gè)元素開始的所有元素苛坚,那么下面兩種方式都是可以的:
tr:nth-child(n + 9) {background: silver;}
tr:nth-child(8) ~ tr {background: silver;}
有正向搜索就有反向搜索比被,因此和nth-child對(duì)應(yīng)的就是nth-last-child,其中的語法與前者完全一致炕婶,只不過調(diào)整了下檢索的順序從末尾開始。舉個(gè)例子莱预,如果需要實(shí)現(xiàn)從末尾開始的奇數(shù)選擇柠掂,下面兩種都是可以的:
tr:nth-last-child(odd) {background: silver;}
tr:nth-last-child(2n+1) {background: silver;}
更高級(jí)的玩法是將兩者結(jié)合起來來實(shí)現(xiàn)更精確的選擇和需求,就像下面這些,這些規(guī)則的組合其實(shí)是用來彈性布局末尾幾個(gè)元素的寬度:
li:only-child {width: 100%;}
li:nth-child(1):nth-last-child(2),
li:nth-child(2):nth-last-child(1) {width: 50%;}
li:nth-child(1):nth-last-child(3),
li:nth-child(1):nth-last-child(3) ~ li {width: 33.33%;}
li:nth-child(1):nth-last-child(4),
li:nth-child(1):nth-last-child(4) ~ li {width: 25%;}
選擇第n個(gè)子類型
和:nth-child和:nth-last-child對(duì)應(yīng)的就是:nth-of-type() 和:nth-last-of- type().可以忽略其他元素的情況下依沮,針對(duì)某個(gè)類的元素列表做查找涯贞,舉個(gè)例子,想要查找<p>段落內(nèi)部的所有偶數(shù)鏈接的元素危喉,就可以這樣:
動(dòng)態(tài)偽類
上面咱們講完了結(jié)構(gòu)偽類宋渔,可是很多情況下即使頁面渲染完了,還是存在不少的非結(jié)構(gòu)的動(dòng)態(tài)情況辜限,為了應(yīng)付這種類型的樣式選擇皇拣,CSS中引入了動(dòng)態(tài)偽類。覺得太抽象薄嫡?看下我們最常用的鏈接元素<a>(英文中稱為anchor氧急,錨),用戶點(diǎn)擊了哪些鏈接事前是不知道的,而如果要已訪問的和未訪問的做樣式的區(qū)分就需要?jiǎng)討B(tài)偽類的幫忙了毫深。
超鏈接偽類
在CSS2.1中定義了針對(duì)鏈接定義了兩個(gè)偽類吩坝,來看看吧:
名稱 | 描述 |
---|---|
:link | 未訪問的鏈接 |
:visited | 已訪問的鏈接,出于安全考慮哑蔫,能夠應(yīng)用到已訪問鏈接的樣式是受限的 |
那大家就會(huì)說啦钉寝,這個(gè)第一個(gè)的:link好像沒啥用啊弧呐,如果要定義樣式,直接這樣不就行了:
a {color: blue;}
a:visited {color: red;}
沒有訪問的直接用a的樣式來代替嵌纲,但這可以俘枫,但是會(huì)漏掉一種情況,就是a中沒有href屬性疹瘦,比如這樣:
<a>4. The Lives of Meerkats</a>
那么上面是會(huì)匹配到這一情況的崩哩,而a:link就不會(huì),因?yàn)檫@一偽類都需要鏈接是必須有href屬性可跳轉(zhuǎn)的言沐。
使用動(dòng)作偽類
CSS定義了幾個(gè)偽類來應(yīng)對(duì)用戶的活動(dòng)邓嘹,比如激活,移動(dòng)到元素上面等险胰。雖然大多用在鏈接上汹押,實(shí)際它們可以用在更多的元素上面。
名稱 | 描述 |
---|---|
:focus | 節(jié)點(diǎn)獲取到輸入焦點(diǎn)時(shí)觸發(fā)起便,例如獲取鍵盤輸入或其他方式 |
:hover | 鼠標(biāo)指針移動(dòng)到上面是觸發(fā) |
:active | 元素被用戶輸入激活時(shí)觸發(fā)棚贾,一般像用戶點(diǎn)擊一個(gè)鏈接,在用戶點(diǎn)擊鼠標(biāo)還未抬起的這段時(shí)間內(nèi)就是處于active激活狀態(tài) |
適用active的元素其實(shí)還不少榆综,除了鏈接外妙痹,像菜單列表項(xiàng),按鈕等都可以鼻疮。而對(duì)于獲取焦點(diǎn)的focus狀態(tài)怯伊,基本上所有的交互元素,內(nèi)容可編輯的元素都是可以實(shí)現(xiàn)的判沟。
當(dāng)然啦耿芹,上面提到的4個(gè)偽類中應(yīng)用最廣的就是鏈接了,下面是常見的網(wǎng)站鏈接的偽類:
a:link {color: navy;}
a:visited {color: gray;}
a:focus {color: orange;}
a:hover {color: red;}
a:active {color: yellow;}
之前說了動(dòng)態(tài)偽類可以應(yīng)用在任何的元素上面挪哄,這就來個(gè)例子:
input:focus {background: silver; font-weight: bold;}
上面的input在每次獲得焦點(diǎn)時(shí)都會(huì)觸發(fā)樣式變化吧秕。
UI狀態(tài)偽類
更動(dòng)態(tài)偽類息息相關(guān)的就是UI狀態(tài)偽類(user-interface state pseudo-classes),我們將他們統(tǒng)一放到下面的表格中:
名稱 | 描述 |
---|---|
:enabled | UI元素,例如表單元素迹炼,可以輸入狀態(tài) |
:disabled | UI元素禁止使用狀態(tài) |
:checked | 針對(duì)radio單選按鈕或是checkbox被選中的狀態(tài) |
:indeterminate | radio 按鈕或是checkbox的未知狀態(tài)砸彬,既不是checked也不是unchecked,這個(gè)狀態(tài)只能被dom的腳本修改斯入,用戶輸入是改不了的 |
:default | 針對(duì)radio 按鈕拿霉,checkbox或是那些默認(rèn)已選中的元素 |
:valid | 針對(duì)滿足數(shù)據(jù)合理性效驗(yàn)的用戶輸入 |
:invalid | 針對(duì)不滿足數(shù)據(jù)合理性效驗(yàn)的用戶輸入 |
:in-range | 針對(duì)用戶輸入在最小值和最大值之間的元素 |
:out-of-range | 針對(duì)用戶輸入超出范圍的元素 |
:required | 針對(duì)必須有輸入的元素 |
:optional | 針對(duì)不必須有用戶輸入的元素 |
:read-write | 針對(duì)用戶可編輯的元素 |
:read-only | 針對(duì)用戶不可編輯的元素 |
從上面我們可以看到,修改UI元素狀態(tài)的不只是有用戶輸入咱扣,文檔結(jié)構(gòu)或是DOM的腳本也是可以修改的绽淘。
啟用/禁用UI元素
借助DOM腳本和HTML5, 我們是可以將元素設(shè)置為禁用狀態(tài)闹伪,一旦設(shè)置了沪铭,那么元素雖然可以顯示出來壮池,但卻無法激活與編輯選擇。設(shè)置的方式很多杀怠,可以借助dom的腳本實(shí)現(xiàn)椰憋,也可以通過為元素設(shè)置disbled屬性來實(shí)現(xiàn)。
check狀態(tài)
針對(duì)checkbox或是radio赔退,選擇器的Level 3標(biāo)準(zhǔn)定義了:checked偽類橙依,貌似沒有對(duì)應(yīng)的:unchecked,但是不是有:indeterminate這一偽類來確定中間狀態(tài)么硕旗,下面就來看個(gè)實(shí)際的例子:
:checked {background: silver;}
:indeterminate {border: red;}
只有radio按鈕和checkbox才會(huì)有checked窗骑,而其他的元素,包括這兩者的未選中狀態(tài)漆枚,都滿足:not(:checked)创译,至于這個(gè)表達(dá)式具體啥含義,賣個(gè)關(guān)子墙基,因?yàn)楹竺娴姆穸▊晤悤?huì)詳細(xì)介紹软族。
除了咱們常見的check和uncheck狀態(tài),上面不是還有個(gè)indeterminate的模糊狀態(tài)么残制,截止2017年底立砸,這個(gè)狀態(tài)只能通過dom腳本或是user agent用戶代理(指的一般就是瀏覽器)自己設(shè)置。那么問題就來了初茶,為啥要設(shè)置中間狀態(tài)呢颗祝,因?yàn)榫褪且谝曈X上強(qiáng)制用戶來指定元素的狀態(tài),因?yàn)橹虚g狀態(tài)的樣式一般都不同纺蛆,注意上面所說的視覺上這個(gè)詞吐葵,因?yàn)槠鋵?shí)它是完全不影響UI元素本身的狀態(tài)的规揪。
:default 默認(rèn)偽類
:default偽類更多的是在一系列相似元素的集合上桥氏,很適合菜單選項(xiàng)。像在頁面上默認(rèn)checked的radio按鈕和checkbox都能夠匹配default屬性猛铅,下面來看個(gè)例子:
[type="checkbox"]:default + label { font-style: italic; } <input type="checkbox" id="chbx" checked name="foo" value="bar">
<label for="chbx">This was checked on page load</label>
必須/可選項(xiàng)偽類
:required用來匹配那些在表單控制中標(biāo)記為必填的元素字支,而對(duì)應(yīng)的:optional偽類用來匹配那些不必須的,或者是某個(gè)元素的required屬性設(shè)置為false也是可以匹配到的奸忽。
來看個(gè)例子:
input:required { border: 1px solid #f00;}
input:optional { border: 1px solid #ccc;}
<input type="email" placeholder="enter an email address" required>
<input type="email" placeholder="optional email address">
<input type="email" placeholder="optional email address" required="false">
第一個(gè)input匹配required堕伪,后面兩個(gè)匹配optional。同時(shí)別忘了我們也可以用屬性選擇器來代替上面的css樣式栗菜,來看下如何實(shí)現(xiàn)的:
input[required] { border: 1px solid #f00;} input:not([required]) { border: 1px solid #ccc;}
注意如果元素不是表單的input元素的話這兩個(gè)偽類是不起作用的欠雌。
檢驗(yàn)數(shù)據(jù)有效性的偽類
:valid偽類用來匹配所有滿足數(shù)據(jù)合理性的元素,而對(duì)應(yīng)的:invalid用來匹配那些不滿足要求的疙筹。因此這兩個(gè)偽類其實(shí)是有使用限制的富俄,像div這種完全沒有數(shù)據(jù)合理性要求的元素對(duì)這些偽類是無效的禁炒。來看個(gè)email的input元素的使用例子,要求是對(duì)不同的有效性顯示不同的背景圖:
input[type="email"]:focus { background-position: 100% 50%; background-repeat: no-repeat;
}
input[type="email"]:focus:invalid {
background-image: url(warning.jpg); }
input[type="email"]:focus:valid { background-image: url(checkmark.jpg);
}
<input type="email">
范圍偽類
偽類:in-range用來匹配數(shù)值數(shù)據(jù)在合理的范圍內(nèi)霍比,最大值最小值可以通過HTML5中的min和max來設(shè)置幕袱,而對(duì)應(yīng)的偽類:out-of-range就用來匹配那些超出范圍的元素。
同樣舉個(gè)例子說明下悠瞬,我們將范圍設(shè)定為0-1000:
input[type="number"]:focus { background-position: 100% 50%; background-repeat: no-repeat;
}
input[type="number"]:focus:out-of-range {
background-image: url(warning.jpg); }
input[type="number"]:focus:in-range { background-image: url(checkmark.jpg);
}
\<input id="nickels" type="number" min="0" max="1000" />
注意就像上面說的们豌,如果這個(gè)input沒有范圍,例如設(shè)定類型為tel等的話范圍偽類是沒有作用浅妆。
在H5中還有一個(gè)step屬性望迎,就是規(guī)定每步的跳躍大小,在這里就要說明一下如果某個(gè)元素在范圍里面但是卻不是規(guī)定的step要求狂打,那么在匹配的時(shí)候是可以匹配in-range偽類的擂煞,但是在合理性上面匹配invalid偽類。舉例說明趴乡,下面的input就會(huì)同時(shí)匹配到兩個(gè)css屬性:
input[type="number"]:invalid {color: red;} input[type="number"]:in-range {font-weight: bold;}
<input id="by-tens" type="number" min="0" max="1000" step="10" value="23" />
可變的偽類
這里說的可變其實(shí)指的是元素是否可以編輯对省,因此就可以猜得出來這里要說的偽類就是:read-only只讀的偽類,和:read-write可寫的偽類晾捏。
在下面的例子中蒿涎,兩條css規(guī)則都會(huì)匹配到對(duì)應(yīng)的元素,來看下吧:
textarea:read-only { opacity: 0.75;}
pre:read-write:hover {border: 1px dashed green;}
<textarea disabled></textarea>
<pre contenteditable>Type your own code!</pre>
注意這里出現(xiàn)了一個(gè)新的屬性contenteditable惦辛,就是標(biāo)記內(nèi)容是否是可編輯的劳秋,一旦設(shè)定了就是可以編輯的,所以滿足:read-write屬性胖齐。
:target 偽類
:target偽類用來匹配URL后面的段落分隔符(fragment identifier)玻淑,其實(shí)就是用來定位到頁面中的某個(gè)具體段落,如果你對(duì)這個(gè)專用名詞還不熟悉的話呀伙,來看個(gè)具體的url就清楚了:
http://www.w3.org/TR/css3-selectors/#target-pseudo
是不是在很多的url上都看到過补履,這個(gè)段落分隔符就是以#開頭的,那如果打開的頁面中有個(gè)元素的id能夠匹配偽類中的名稱(就是這里的target-pseudo)剿另,那么這個(gè)元素就可以應(yīng)用:target后面的規(guī)則箫锤。來看個(gè)例子:
*:target {border-left: 5px solid gray; background: yellow url(target.png) top right no-repeat;}
不過需要注意:target偽類在下面兩種情況下是不能用的:
- URL后面沒有段落標(biāo)識(shí)符;
- URL后面有段落標(biāo)識(shí)符雨女,但是頁面中完全沒有對(duì)應(yīng)的元素
有人要問了谚攒,如果一個(gè)頁面中有好幾個(gè)id都匹配:target偽類怎么辦?其實(shí)答案很簡(jiǎn)單氛堕,判斷有幾個(gè)id或者強(qiáng)制用戶為元素設(shè)定唯一的id是瀏覽器的事情馏臭,而只要是合理的target都可以匹配這一偽類。
:lang偽類
對(duì)于那些想要基于語言來選擇元素的用戶來說就可以用:lang這個(gè)偽類讼稚。而這一偽類其實(shí)和屬性選擇其中的|=是等價(jià)的括儒,來看個(gè)例子吧:
*:lang(fr) {font-style: italic;}
*[lang|="fr"] {font-style: italic;}
雖然功能上等價(jià)但存在差異浪耘,上面兩者的主要區(qū)別在于語言的信息的來源不同,相較于后者只從lang屬性中獲取屬性塑崖,:lang偽類可以匹配元素的所有后代聲明的語言信息七冲。選擇器的Level 3中是這么講的:
在HTML中,語言信息是由lang屬性规婆,meta中可能的定義和協(xié)議澜躺,例如http頭共同決定的。而在XML中抒蚜,有專門的xml:lang來定義語言屬性掘鄙,而其他的標(biāo)記語言也有不同的定義。
所以根據(jù)上面說的嗡髓,偽類相比屬性更好的能夠獲取到語言信息操漠。
否定偽類
之前我們說的那么多偽類都是按照用戶需求正向應(yīng)用規(guī)則,有正就有反饿这,所以選擇器Level 3中映入了反向或者叫否定偽類:not浊伙。相比于其他的選擇器,使用上還是有不少限制的长捧,我們還是通過例子來理解吧嚣鄙。
如果想要針對(duì)一串li列表中沒有moreinfo類的元素來做匹配,沒有否定偽類之前幾乎是不可能的:
li:not(.moreinfo) {font-style: italic;}
那么來看下:not()偽類是如何工作的把串结,首先偽類顯示匹配你想要的元素(例如上面的li)哑子,然后作用括號(hào)里面的簡(jiǎn)單選擇器,那什么叫簡(jiǎn)單選擇器呢肌割,根據(jù)W3C的定義就是:
類型選擇器卧蜓,通用選擇器,屬性選擇器把敞,類選擇器弥奸,ID選擇器,偽類這幾種屬于簡(jiǎn)單選擇器先巴。
其實(shí)簡(jiǎn)單來理解就是沒有祖先-后代關(guān)系的選擇器其爵。注意這里是有不少限制的冒冬,首先在not的括號(hào)中不能混用上面的幾類簡(jiǎn)單選擇器伸蚯,也不準(zhǔn)有后代選擇器。再回到之前的例子简烤,這次我們要選取的是有moreinfo類但是不屬于li列表項(xiàng)的:
.moreinfo:not(li) {font-style: italic;}
另外從技術(shù)上講p:not(*), p:not(p)等都是可以的剂邮,不過沒有任何意義。再舉個(gè)例子:選擇不在thead中的th元素
*:not(thead) > tr > th
注意否定偽類是不能嵌套的横侦,否則會(huì)被忽略挥萌,例如像p:not(:not(p))是不行的绰姻。但是:not是支持鏈?zhǔn)綄懛ǖ模?/p>
*.link:not(li):not(p) {font-style: italic;}
每個(gè):not之間是and的關(guān)系。有時(shí)候我們需要關(guān)注多個(gè)規(guī)則間的沖突引瀑,來看個(gè)例子:
div:not(.one) p {font-weight: normal;}
div.one p {font-weight: bold;}
<div class="one">
<div class="two">
<p>I'm a paragraph!</p>
</div>
</div>
注意上面兩個(gè)規(guī)則都會(huì)作用到<p>上狂芋,而由于所謂的級(jí)聯(lián)規(guī)則,后者會(huì)覆蓋前者憨栽,因此最終呈現(xiàn)的規(guī)則就是粗體的結(jié)果帜矾。
偽元素選擇器
前面見識(shí)過不少偽類選擇器,而這里我們?cè)賮黻P(guān)注下另一類選擇器-稱為偽元素選擇器(Pseudo-Element Selectors)屑柔,在CSS2中定義了4種偽元素選擇器來幫助我們選擇元素的第一個(gè)字母(::first-letter)屡萤,元素的第一行(::first-line),元素的前后內(nèi)容(::before ::after)掸宛。當(dāng)然還有一些其他的死陆,將在后面的章節(jié)中介紹(eg: ::marker),之所以把這4個(gè)拎出來講唧瘾,是因?yàn)樗鼈兪褂煤芫枚液芫哂写硇浴?/p>
不像偽類只有一個(gè)冒號(hào)措译,偽元素都有兩個(gè)冒號(hào)。這成了它們的主要區(qū)別饰序,而在以前(值得就是CSS2)瞳遍,這兩種類型都是使用一個(gè)冒號(hào),所以瀏覽器考慮到兼容性的話也會(huì)接受單一冒號(hào)作為偽元素選擇器的語法菌羽。不過別想著偷懶掠械,哪天瀏覽器不支持了就涼涼了,所以還是老老實(shí)實(shí)的寫2個(gè)冒號(hào)把注祖。
另一個(gè)需要注意的點(diǎn)是偽元素必須放在選擇器的最后猾蒂,像p::first-line em這種是不行的,因?yàn)閭卧氐慕馕鍪窃谶x擇器之前是晨,換句話說肚菠,每個(gè)選擇器有且只能有一個(gè)偽元素,雖然未來可能會(huì)放開這個(gè)限制罩缴,不過現(xiàn)在(截止2017年底)還不允許蚊逢。
::first-letter
::first-letter用來匹配元素的第一個(gè)字母,下面的例子將每個(gè)段落的首字母標(biāo)記為紅色:
p::first-letter {color: red;}
或者想要將第一個(gè)段落的首字母變大2倍:
p:first-of-type::first-letter {font-size: 200%;}
想知道瀏覽器是怎么處理這個(gè)的么箫章?首先它會(huì)自動(dòng)生成下面的結(jié)構(gòu):
<p><p-first-letter>T</p-first-letter>his is a p element, with a styled first letter</h2>
這其中的<p-first-letter>就是虛構(gòu)的元素烙荷,是由瀏覽器動(dòng)態(tài)生成的,所以說<p-first-letter>就是所謂的偽元素檬寂。記住你自己不需要添加任何標(biāo)簽终抽。
另一個(gè)需要注意的就是樣式作用域打印字母為單元的文本域中,像圖片這種樣式的內(nèi)容是不支持的。針對(duì)不同語言昼伴,首字母是不同的匾旭,不過偽元素會(huì)為我們自動(dòng)指定合適的語言首字母。
::first-line
和上面的類似圃郊,first-line用來設(shè)置第一行文本的樣式价涝,例如:
p::first-line {
font-size: 150%;
color: purple;
}
這里的第一行的內(nèi)容其實(shí)受多種因素的影響,比如字體大小持舆,字母間的空格飒泻,父容器的寬度等等,所以第一行結(jié)束的時(shí)候其實(shí)是很容易出現(xiàn)還處在嵌套元素的情況吏廉,比如em或是超鏈接泞遗,而first-line只會(huì)講樣式作用于第一行的元素中。
::first-letter和::first-line的限制
這兩個(gè)偽元素現(xiàn)在只能作用在{display:block}的塊級(jí)元素上席覆,例如標(biāo)題和段落史辙,而像超鏈接這種inline的內(nèi)聯(lián)元素則不行。而且對(duì)于作用其上的CSS屬性也有限制佩伤,具體參見下表:
::first-letter | ::first-line |
---|---|
所有字體屬性 | 所有字體屬性 |
所有背景屬性 | 所有背景屬性 |
所有文本裝飾屬性text-decoration | 所有的margin屬性 |
所有的內(nèi)聯(lián)typesetting屬性 | 所有的padding屬性 |
所有的內(nèi)聯(lián)layout屬性 | 所有的border屬性 |
所有的border屬性 | 所有的文本裝飾屬性 |
box-shadow | 所有的內(nèi)聯(lián)typesetting屬性 |
color | color |
opacity | opacity |
元素的前置和后置內(nèi)容
如果想要在所有的h2元素之前加一對(duì)方括號(hào)的話聊倔,我們可以這樣:
h2::before {content: "]]"; color: silver;}
CSS中允許你生成想要的內(nèi)容,然后通過偽元素類::before和::after放上去生巡。
具體怎么生成內(nèi)容就是另外一回事了耙蔑,將在后面的第15章講解。
小結(jié)
通過使用基于document語言的選擇器孤荣,開發(fā)人員可以將創(chuàng)建的css規(guī)則應(yīng)用在一大批相似的元素上面甸陌。而將選擇器和規(guī)則聚合的能力讓樣式的使用更加緊實(shí)靈活,這樣就可以使文件更小,下載速度更快。
瀏覽器和開發(fā)者兩邊都需要正確使用選擇器瓜喇,一邊解析必須正確,一邊使用必須正確牲尺,不然都會(huì)導(dǎo)致樣式的缺失。而想要正確使用就必須了解選擇器是如何關(guān)聯(lián)到document以及它們本身的層級(jí)關(guān)系幌蚊,這些因素最終導(dǎo)致了元素的渲染谤碳。