玩转CSS选择器(一) 之 使用方法介绍
前言
前幾天整理了CSS一些技術(shù)關(guān)鍵字,但是因為自己的知識過于單薄,覺得考慮的不充分有欠缺,隨后便在sf.gg提出了這個問題《關(guān)于CSS核心技術(shù)關(guān)鍵字都有哪些?》,也是為了讓厲害的人一起參與進來,用他們的經(jīng)驗告知我們CSS中哪一塊的知識點是重要,或者說是不可欠缺的,也或者說是應(yīng)該打好基礎(chǔ)的。
在整理這份CSS技術(shù)關(guān)鍵字的開始,首先想到的是選擇器,它作為最常用的的一個特性,幾乎天天都在使用,但是如果讓你說出20種CSS選擇器,是不是可以脫口而出呢? 哎,或許我們被瀏覽器逼的還停留在CSS2.1那些選擇器把?CSS4規(guī)范都要問世了,我們還在玩那個?
帶著這些疑問,決定梳理一下之前用到的知識點,最終以系列文章的方式說一說我對選擇器的理解,具體包含的內(nèi)容如下:
- 選擇器的基礎(chǔ)使用,主要是CSS3,也會介紹新增CSS4選擇器,包括各瀏覽器對選擇器的支持情況
- 選擇器的使用技巧,使用時常出現(xiàn)的一些問題,扒一扒解決方案,再說一說效率和優(yōu)化的部分
- 選擇器的優(yōu)先級,理一理比較頭疼的權(quán)重問題,如何更輕松的理解它
導(dǎo)圖與源碼
我在寫這篇文章的時候會梳理一份思維導(dǎo)圖,用于更加直觀的查閱所有的CSS選擇器,并且也有編寫示例代碼,更方便理解文章中的示例。
關(guān)于思維導(dǎo)圖和示例代碼,會上傳至Github,當然也會隨著時間的允許,不定義補充和更新
倉庫地址:https://github.com/Alsiso/everyday
思維導(dǎo)圖:https://github.com/Alsiso/everyday/blob/master/codes/css-selectors/css...
示例代碼:https://github.com/Alsiso/everyday/tree/master/codes/css-selectors
關(guān)于everyday是我每天記錄和總結(jié)的地方,這里有代碼,布局方案,移動端適配方案等等,后續(xù)會不斷的補充和更新,歡迎一起聊代碼,玩前端。
基本選擇器
通配符選擇器 *
通配符選擇器用來選擇所有的元素
* {marigin: 0;padding: 0; }在我之的文章中討論過CSS RESET,其中里面的核心代碼就是使用通配符選擇器定義的,來重置瀏覽器所有元素的內(nèi)邊距和外邊距。
其實,通配符選擇器還可以選擇某一個元素下的所有元素
#demo *{margin:0; }不過使用通配符要謹慎,并不是因為通配符會帶來性能問題,而是濫用通配符會造成“繼承失效”或“繼承短路”的問題,這種情況會對開發(fā)造成一定程度的影響。
元素選擇器 E
元素選擇器使用也很簡單,它用于指定HTML文檔中元素的樣式
ul{list-style:none; }▲ 這里使用元素選擇器選擇ul元素并去除列表前面的默認圓點
類選擇器.className
類選擇器是最常用的一種選擇器,使用時需要在HTML文檔元素上定義類名,然后與樣式中的.className相匹配,它一次定義后,在HTML文檔元素中是可以多次復(fù)用的。
CSS
.menu {margin:0 auto; }HTML
<div class="menu"></div>類選擇器還可以結(jié)合元素選擇器來使用,假設(shè)文檔中有兩個元素都使用了.menu類名,但是你只想選擇div元素上類名為.menu的元素
CSS
div.menu {margin:0 auto; }HTML
<div class="menu"></div> <ul class="menu"></ul>類選擇器支持多類名使用,比如.menu.active這個選擇器只對元素中同時包含了menu和active兩個類才會起作用
CSS
.menu {margin:0 auto; } .menu.active {font-weight:bold; }HTML
<div class="menu active"></div>不過多類選擇器.className1.className2在 IE6+以上才支持,關(guān)于瀏覽器對CSS選擇器的支持會下面的內(nèi)容統(tǒng)一整理列出表格。
id選擇器#id
id選擇器與上面的類選擇器使用很相似,通過在HTML文檔中添加ID名稱,然后與樣式中的#id相匹配,不過兩者的最大的區(qū)別在于,ID選擇器是一個頁面中唯一的值,不可多次使用,而class選擇器是可以多次復(fù)用的。
CSS
#menu{margin:0 auto; }HTML
<div id="menu"></div>群組選擇器s1,s2,...,sN
群組選擇器在開發(fā)中也是很常用的,它用于將相同樣式的元素分組在一起,然后用逗號進行分割。
CSS
a:active,a:hover {outline: 0; }▲ 這里統(tǒng)一去掉了a鏈接在點擊和浮動時的虛線焦點框。
后代選擇器E F
后代選擇器是最常使用的選擇器之一,它也被稱作包含選擇器,用于匹配所有被E元素包含的F元素,這里F元素不管是E元素的子元素或者是孫元素或者是更深層次的關(guān)系,都將被選中。
CSS
.menu li{padding:0 ; }HTML
<ul id="menu"><li><ul><li></li></ul></li> </ul>▲ 這里.menu下的li元素和嵌套的ul元素下的li的元素都會被選擇,進行清楚內(nèi)邊距。
子元素選擇器E > F
子元素選擇器只能選擇某元素的子元素,這里的F元素僅僅是E元素的子元素才可以被選中
CSS
.menu > li{padding:0 ; }HTML
<ul id="menu"><li><ul><li></li></ul></li> </ul>▲ 將會對.menu下的li子元素選中,但會忽視內(nèi)部嵌套的li元素
相鄰兄弟元素選擇器E + F
相鄰兄弟選擇器可以選擇緊接在另一元素后的元素,但是他們必須有一個相同的父元素。比如E元素和F元素具有一個相同的父元素,而且F元素在E元素后面,這樣我們就可以使用相鄰兄弟元素選擇器來選擇F元素。
CSS
h1 + p {margin-top:5px; }HTML
<div><h1>標題</h1><p>內(nèi)容</p> </div>▲ 將會選擇h1元素后面的兄弟元素p
通用兄弟選擇器E ~ F
通用兄弟元素選擇器是CSS3新增加一種選擇器,用于選擇某元素后面的所有兄弟元素。它和相鄰兄弟元素選擇器用法相似,但不同于前者只是選擇相鄰的后一個元素,而通用兄弟元素選擇器是選擇所有元素。
CSS
h1 ~ p {margin-top:5px; }HTML
<div><h1>標題</h1><p>內(nèi)容</p><p>內(nèi)容</p><p>內(nèi)容</p> </div>▲ 將會選擇h1元素后面的所有的兄弟元素p
屬性選擇器
| E[attr] | 匹配所有具有attr屬性的E元素 | 2.1 |
| E[attr=value] | 匹配所有attr屬性等于“value”的E元素 | 2.1 |
| E[attr~=value] | 匹配所有attr屬性具有多個空格分隔的值、其中一個值等于“value”的E元素 | 2.1 |
| E[attr^=value] | 匹配所有attr屬性值是以val開頭的E元素 | 2.1 |
| E[attr$=value] | 匹配所有attr屬性值是以val結(jié)束的E元素 | 3 |
| E[attr*=value] | 匹配所有attr屬性值包含有“value”的E元素 | 3 |
E[attr]
E[attr]屬性選擇器是CSS3屬性選擇器最簡單的一種,用于選擇具有att屬性的E元素。
CSS
img[alt] {margin: 10px; }HTML
<img src="url" alt="" /> <img src="url" />▲ 將會選擇到第一張圖片,因為匹配到了alt屬性,你也可以使用多屬性的方式選擇元素
img[src][alt] {margin: 10px; }E[attr=value]
E[attr="value"]是指定了屬性值value,從而縮小了范圍可以更為精確的查找到自己想要的元素。
CSS
input[type="text"] {border: 2px solid #000; }HTML
<input type="text" /> <input type="submit" />▲ 將會選擇到type="text"表單元素。
E[attr~=value]
如果你要根據(jù)屬性值中的詞列表的某個詞來進行選擇元素,那么就需要使用這種屬性選擇器:E[attr~="value"],你會發(fā)現(xiàn)它和E[attr="value"]極為的相似,但是兩者的區(qū)別是,屬性選擇器中有波浪(~)時屬性值有value時就相匹配,沒有波浪(~)時屬性值要完全是value時才匹配。
CSS
div[class~="a"] {border: 2px solid #000; }HTML
<div class="a">1</div> <div class="b">2</div> <div class="a b">3</div>▲ 將會選擇到第1、3個div元素,因為匹配到了class屬性,且屬性值中有一個值為a
E[attr^=value]
E[attr^="value"]屬性選擇器,指的是選擇attr屬性值以“value”開頭的所有元素
CSS
div[class^="a"] {border: 2px solid #000; }HTML
<div class="abc">1</div> <div class="acb">2</div> <div class="bac">3</div>▲ 將會選擇到第1、2個div元素,因為匹配到了class屬性,且屬性值以a開頭
E[attr$=value]
E[attr$="value"]屬性選擇器剛好與E[attr^="value"]選擇器相反,這里是選擇attr屬性值以"value"結(jié)尾的所有元素。
CSS
div[class$="c"] {border: 2px solid #000; }HTML
<div class="abc">1</div> <div class="acb">2</div> <div class="bac">3</div>▲ 將會選擇到第1、3個div元素,因為匹配到了class屬性,且屬性值以c結(jié)尾
E[attr*=value]
E[attr*="value"]屬性選擇器表示的是選擇attr屬性值中包含"value"字符串的所有元素。
CSS
div[class*="b"] {border: 2px solid #000; }HTML
<div class="abc">1</div> <div class="acb">2</div> <div class="bac">3</div>▲ 將會選擇到所有的元素,因為匹配到了class屬性,且屬性值都包含了b
E[attr|="val"]
E[attr|="val"]是屬性選擇器中的最后一種,它被稱作為特定屬性選擇器,這個選擇器會選擇attr屬性值等于value或以value-開頭的所有元素。
CSS
div[class|="a"] {border: 2px solid #000; }HTML
<div class="a-test">1</div> <div class="b-test">2</div> <div class="c-test">3</div>▲ 將會選擇第1個div元素,因為匹配到了class屬性,且屬性值以緊跟著"a-"的開頭
偽類選擇器
動態(tài)偽類
一般動態(tài)偽類是在用戶操作體驗時觸發(fā)的,最常見的就是超鏈接,它擁有訪問前,鼠標懸停,被點擊,已訪問4種偽類效果。
- E:link 設(shè)置超鏈接a在未被訪問前的樣式
- E:visited 設(shè)置超鏈接a已被訪問過時的樣式
- E:hover 設(shè)置元素在其鼠標懸停時的樣式
- E:active 設(shè)置元素在被用戶激活時的樣式
不過在使用時的時候,一定要注意書寫的順序,不然在不同的瀏覽器中會帶來一些意想不到的錯誤。
a:link {} a:visited {} a:hover {} a:active {}最可靠的記憶順序就是遵循愛恨原則:l(link)ov(visited)e h(hover)a(active)te, 即用喜歡(love)和討厭(hate)兩個詞來概括。
還有一個用戶行為的動態(tài)偽類:focus,常用于表單元素(觸發(fā)onfocus事件發(fā)生)時的樣式。
input[type="text"]:focus{border: 2px solid #000; }▲ 當用戶聚焦到輸入框內(nèi),會給輸入框添加一個邊框顏色。
表單狀態(tài)偽類
我們把以下3種狀態(tài)稱作表單狀態(tài)偽類,你會發(fā)現(xiàn)這些關(guān)鍵字就是HTML表單元素的屬性,checked用于type="radio"和type="checkbox"夠選中狀態(tài),disabled用于type="text"禁用的狀態(tài),而enabled這里表示type="text"可用的狀態(tài)。
- E:checked 匹配用戶界面上處于選中狀態(tài)的元素E
- E:enabled 匹配用戶界面上處于可用狀態(tài)的元素E
- E:disabled 匹配用戶界面上處于禁用狀態(tài)的元素E
CSS
input[type="text"]:enabled {background: #fff; } input[type="text"]:disabled{background: #eee; } input:checked + span {background: red; }HTML
<input type="text" value="可用狀態(tài)" /> <input type="text" value="可用狀態(tài)" /> <input type="text" value="禁用狀態(tài)" disabled="disabled" /> <input type="text" value="禁用狀態(tài)" disabled="disabled" /> <label><input type="radio" name="radio" /><span>黑色</span></label>▲ 將會給可用狀態(tài)的文本框設(shè)置為白色(#fff)背景,禁用狀態(tài)設(shè)置為灰色(#eee)背景,如果你選中了radio,它兄弟元素span的文本會變成紅色
結(jié)構(gòu)偽類
- E:first-child 匹配父元素的第一個子元素E
- E:last-child 匹配父元素的最后一個子元素E
- E:nth-child(n) 匹配父元素的第n個子元素E,假設(shè)該子元素不是E,則選擇符無效
- E:nth-last-child(n) 匹配父元素的倒數(shù)第n個子元素E,假設(shè)該子元素不是E,則選擇符無效
- E:first-of-type 匹配同類型中的第一個同級兄弟元素E
- E:last-of-type 匹配同類型中的最后一個同級兄弟元素E
- E:nth-of-type(n) 匹配同類型中的第n個同級兄弟元素E
- E:nth-last-of-type(n) 匹配同類型中的倒數(shù)第n個同級兄弟元素E
- E:only-child 匹配父元素僅有的一個子元素E
- E:only-of-type 匹配同類型中的唯一的一個同級兄弟元素E
- E:empty 匹配沒有任何子元素(包括text節(jié)點)的元素E
E:first-child 和 E:last-child
E:first-child是用來選擇父元素的第一個子元素E,但是它必須為父元素的第一個子元素,不然會失效,舉例說明
CSS
p:first-child {color:red; }HTML
<div><h1>標題</h1><p>段落</p> </div>▲ 你會發(fā)現(xiàn)p元素的字體并沒有變?yōu)榧t色,因為p元素前面還有個h1,它并不是父元素下的第一個子元素。
<div><p>段落</p> </div>▲ 這時需要改變結(jié)構(gòu),效果才會正常。
而E:last-child與E:first-child選擇器的作用類似,不同的是E:last-child選擇是的元素的最后一個子元素。
CSS
p:last-child {color:red; }HTML
<div><h1>標題</h1><p>段落</p> </div>▲ 將p元素的字體設(shè)置為紅色
E:nth-child(n) 和 E:nth-last-child(n)
E:nth-child(n)用于匹配父元素的第n個子元素E,假設(shè)該子元素不是E,則選擇符無效。
該選擇符允許使用一個乘法因子(n)來作為換算方式,如下:
▲ 選擇第幾個標簽,“2可以是你想要的數(shù)字,最小從0開始”
li:nth-child(n+4) { background:#fff}▲ 選擇大于等于4標簽,“n”表示從整數(shù)
li:nth-child(-n+4) { background:#fff}▲ 選擇小于等于4標簽
li:nth-child(2n) { background:#fff} li:nth-child(even) { background:#fff}▲ 選擇偶數(shù)標簽,2n也可以是even
li:nth-child(2n-1) { background:#fff} li:nth-child(odd) { background:#fff}▲ 選擇奇數(shù)標簽,2n-1也可以是odd
li:nth-child(3n+1) { background:#fff}▲ 自定義選擇標簽,3n+1表示“隔二取一”
而E:nth-last-child(n)又要開始反著來了,CSS3選擇器有正就有反
li:nth-last-child(3) { background:#fff}▲ 選擇倒數(shù)第3個標簽
E:first-of-type 和 E:last-of-type
E:first-of-type的使用方法類似于我們上面講過的E:first-child,不過區(qū)別在于該選擇器只會選擇同類型的第一個元素,而不是父元素的第一個元素,舉例說明:
CSS
p:first-of-type {color:red; } p:last-of-type {color:green; }HTML
<div><h1>標題</h1><p>段落</p><p>段落</p><div></div> </div>▲ 你會發(fā)現(xiàn)第一個p元素的字體被設(shè)置為紅色,第二個p元素的字體被設(shè)置為綠色,這就是E:first-of-type和E:first-child不同之處。
E:nth-of-type(n) 和 E:nth-last-of-type(n)
這兩個選擇器的用法類似于:nth-child(n)和E:nth-last-child(n),關(guān)于區(qū)別也是選擇器只會選擇同類型的兄弟元素,舉個栗子
▲ 如果使用:nth-child(3)你會發(fā)現(xiàn)第3個p元素文本并沒有變成紅色。就像我們之前說的,如果第n個子元素不是E,則是無效選擇符,但n會遞增。
p:nth-of-type(3) {color:red; }▲ 但是使用:nth-of-type(3)后會發(fā)現(xiàn)第3個p元素文本被設(shè)置為紅色。
E:only-child 和 E:only-of-type
E:only-child用來匹配父元素僅有的一個子元素E,而E:only-of-type是表示一個元素它有很多個子元素,但是只會匹配其中只有一個子元素的元素,說起來有點繞口,來個栗子
HTML
<div><p>段落</p> </div> <div><div>容器</div><p>段落</p><div>容器</div> </div> p:only-child {color: red; }▲ 將會對第1個div元素下的p元素文本設(shè)置成紅色。
p:only-of-type {color: red; }▲ 不僅會第1個div元素下的p元素文本設(shè)置成紅色,也會對第2個div元素下的p元素文本設(shè)置成紅色,因為它是p元素中唯一的一個同級兄弟元素。
<iframe width="100%" height="300" src="//jsfiddle.net/Alsiso/15h4ozee/embedded/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>E:empty
E:empty是用來選擇沒有任何內(nèi)容的元素,包括text節(jié)點,也就是意味著連一個空格都不能有
HTML
<div><p> </p><p></p> </div>CSS
p:empty {height: 100px; }▲ 將會對第2個空元素p設(shè)置一個高度,為什么第一個會失效呢,因為該容器里面有一個空格。
否定類
E:not(s)用于匹配不含有s選擇符的元素E,說起來不好理解,那么說一個最常用的開發(fā)場景,假如我們要對ul元素下的所有l(wèi)i都加上一個下邊框用于內(nèi)容分割,但是最后一個不需要,如下:
HTML
<ul><li>列表1</li><li>列表2</li><li>列表3</li><li>列表4</li> </ul>CSS
ul li:not(:last-child) {border-bottom: 1px solid #ddd; }▲ 將會對列表中除最后一項外的所有列表項添加一條下邊框
偽元素選擇器
- E:first-letter 選擇文本塊的第一個字母
- E:first-line 選擇元素的第一行
- E:before 在元素前面插入內(nèi)容,配合"content"使用
- E:after 在元素后面插入內(nèi)容,配合"content"使用
以上四個偽元素選擇器在CSS2.1都已經(jīng)被支持,但在CSS3中將偽元素選擇符前面的單個冒號(:)修改為雙冒號(::),如E::first-letter、E::first-line、E::before、E::after,不過之前的單冒號寫法也是有效的。
E::first-letter 和 E::first-line
p::first-letter {font-weight:bold; }▲ 將會對文本塊的第一個字母進行加粗
p::first-line {font-weight:bold; }▲ 將會對段落的第一行文本進行加粗
E::before 和 E::after
E::before和E::after是用來給元素的前面和后面差入內(nèi)容,配合"content"使用,但它必須有值才能生效。
HTML
<div>me</div>CSS
div:before{content:'you before'; color:red; } div:after{content:'you after'; color:green; }▲ 將會在div容器中的文本me加上添加后的內(nèi)容并設(shè)置其顏色
E::placeholder和 E::selection
- E::placeholder 選擇文本塊的第一個字母
- E::selection 選擇文本塊的第一個字母
E::placeholder用于設(shè)置對象文字占位符的樣式,但是每個瀏覽器的CSS選擇器都有所差異,需要針對每個瀏覽器做單獨的設(shè)定,舉個例子看代碼
::-webkit-input-placeholder { /* WebKit browsers */color: #999; } :-moz-placeholder { /* Mozilla Firefox 4 to 18 */color: #999; } ::-moz-placeholder { /* Mozilla Firefox 19+ */color: #999; } :-ms-input-placeholder { /* Internet Explorer 10+ */color: #999; }E::selection用于設(shè)置文本被選擇時的樣式,被定義的樣式屬性有3個,而且使用時需要對火狐瀏覽器單獨設(shè)置。
p::-moz-selection{background:#000;color:#f00;text-shadow:1px 1px rgba(0,0,0,.3); } p::selection{background:#000;color:#f00;text-shadow:1px 1px rgba(0,0,0,.3); }第四代選擇器
發(fā)展歷史
自從哈坤·利提出CSS建議到1996年CSS1.0問世,距離今天已經(jīng)有20個年頭。
不過CSS的發(fā)展一直在持續(xù),1997年組織了專門管CSS的工作組,并在1998年發(fā)布了CSS2.0,之后發(fā)布了修訂版本的CSS2.1。
CSS2.1 是我們一直再用的,也是瀏覽器支持較為完整的一個版本。
CSS3 的開發(fā)工作早在2001年以前就啟動了,不過發(fā)展到今天,大多數(shù)的現(xiàn)代瀏覽器對CSS3屬性和選擇器支持良好,除了一些微軟IE瀏覽器的較老版本。
歷史前進的步伐并不會停止的,新的CSS4也正由W3C編輯團隊研發(fā)中。在CSS4中引進了許多的新變化,不過基本選擇器是不會有變化的,更多的還是添加一些偽類,那么接下來一起看看增加的內(nèi)容。
提醒:目前這些代碼功能可能還在實驗規(guī)范階段,瀏覽器并沒有得到支持,所以并不能投入使用 !
升級內(nèi)容
否定類 E:not(s,s,s..)
E:not其實在選擇器已經(jīng)出現(xiàn)在CSS3了,它用于匹配不含有s選擇符的元素E,上面我們講過它的使用方法,但是它只能用于簡單選擇器,偽類,標簽,id,類和類選擇器參數(shù)。不過在CSS4中得到了升級,具體區(qū)別
▲ CSS3將會對除了.header類以外的文本加粗
p:not(.header, .footer) { font-weight: normal; }▲ CSS4通過傳入一個用逗號,將會對除了.header和.footer類以外的文本加粗
關(guān)聯(lián)類 E:has(s)
這個選擇器通過一個參數(shù)(選擇符),去匹配與某一元素對應(yīng)的任意選擇器,舉個例子
▲ 將會對所有帶有img元素的a元素加個黑色的邊框
匹配任何偽類E:matches
這個偽類選擇器可以規(guī)則運用在所有的選擇器組中,它能幫我們簡寫多組選擇器的規(guī)則,例子說明,
▲ 上面的兩個容器都有一個h1標題元素,如何對容器下的h1`字體進行字體顏色設(shè)置呢
section h1,nav h1{color:red; }:matches(section, nav) h1 {color: red; }▲ 這一種是傳統(tǒng)的方法,第二種就是:matches方法。
位置偽類E:local-link和E:local-link(n)
位置偽類是訪問者在你網(wǎng)站上的位置
- :local-link(0) 代表一個超連接元素,其target和文檔的URL是在同一個源中。
- :local-link(1) 代表一個超連接元素,其target和文檔的URL是在同一個源中。
- :local-link(2) 代表一個超連接元素,其target和文檔的URL是在同一個源中。
表單狀態(tài)偽類 E:indeterminate
checkbox中的indeterminate屬性用于展示半選擇狀態(tài),這個屬性只是改變checkbox的外觀,不對它的checked屬性產(chǎn)生影響,CSS4選擇器中也增加了半選擇狀態(tài)的偽類。
表單狀態(tài)偽類 E:required和 E:optional
required屬性是HTML5新添加的,用于規(guī)定必需在提交之前填寫輸入字段
▲ 第一個設(shè)置了required屬性的表單元素將會設(shè)置一個紅色邊框,而第二個沒有設(shè)置該屬性的,將會設(shè)置一個灰色邊框。
范圍限制偽類E:in-range和E:out-of-range
用于表單字段值范圍的限制,取決于表單的min和max屬性
▲ 如果你輸入的值在設(shè)置的最小和最大值范圍內(nèi),那么表單背景會呈現(xiàn)為綠色,如果超出了限制,那么會呈現(xiàn)為紅色。
關(guān)于更多的CSS4選擇器,可參考這里的 示例介紹。
總結(jié)
以上是生活随笔為你收集整理的玩转CSS选择器(一) 之 使用方法介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SAP MM 采购订单收货被取消了还是不
- 下一篇: [CSS] 眼下最流行的五大CSS框架,