天天看點

CSS中的選擇器整理與選擇器權重

顧名思義。CSS中選擇器的主要作用就是與HTML頁面中的元素實作一對一,一對多或者多對一的控制,而在CSS3中又對選擇器進行了擴充,極大的提高了查找元素的精度及準确性。

CSS選擇器主要可以分為基本選擇器和進階選擇器:

一、基本選擇器

1、通配符選擇器(*)

比對頁面中所有元素,一般用來清除浏覽器的預設樣式

示例:

*{
	margin: 0;
	padding: 0;
}
           

2、元素選擇器

通過标簽名選擇樣式,選擇所有的同标簽名元素

示例:

div {
	margin: 0;
	padding: 0;
}
           

3、class選擇器

通過類名選擇元素,同一個類名在頁面中可以出現多次,不具備唯一性

示例:

.大熊貓的五分褲 {
	color: black;
	border: 2px dashed white;
}
           

4、ID選擇器

通過ID選擇元素,一般編碼規範要求ID命名應具有唯一性。

#大熊貓小偉 {
	color: yellow;
	border: 2px dashed blue;
}
           

二、進階選擇器

1、後代選擇器

(E F):比對到E元素下面的所有的F元素(包括子、孫),空格隔開。

示例:

<!DOCTYPE html>
<html>
<head>
	<title>文本環繞</title>
 	<meta charset=“UTF-8” />
 	<style type="text/css">
  		#container span {
   			border: 1px solid gray;
  		}
 	</style>
</head>
<body>
 	<div id="container">
  		<span>first</span>
  		<span>second</span>
  		<span>third</span>
  		<div>
   			<span>four</span>
   			<span>five</span>
  		</div>
 	</div>
</body>
</html>
           

頁面效果:

CSS中的選擇器整理與選擇器權重

2、多元素選擇器

(E,F):同時比對到E元素和F元素

<style type="text/css">
	#box1, #box2 {
		width: 100px;
		height: 100px;
		border: 1px solid yellow;
	}
</style>
<body>
	<div id="box1">first</div>
	<div id="box2">second</div>
</body>
           

頁面效果:

CSS中的選擇器整理與選擇器權重

3、子元素選擇器

(E>F):選擇E元素的直接子代F元素

示例:

<style type="text/css">
  	.container {
   		width: 150px;
  	}
  	.container>ul {
   		border: 2px solid gray;
  	}
 </style>
 <body>
 	<div class="container">
  		<div id="frameWork">
   			<ul>
    				<li>Angular</li>
    				<li>React</li>
    				<li>Vue</li>
   			</ul>
  		</div>
 	</div>
 	<div class="container">
  		<ul>
   			<li>html</li>
   			<li>CSS</li>
   			<li>javascript</li>
  		</ul>
  	</div>
  </body>
           

頁面效果:

CSS中的選擇器整理與選擇器權重

4、毗鄰選擇器

(E+F):緊接在E元素後面的同級元素F,相鄰兄弟選擇器,有相同的父級。

示例:

<style type="text/css">
   .container {
     	width: 150px;
   }
   .container>ul {
     	border: 2px solid gray;
   }
   #frameWork+div {
      	background-color: yellow;
   }
</style>
<body>
	<div class="container">
		<div id="frameWork">
			<ul>
				<li>Angular</li>
        			<li>React</li>
        			<li>Vue</li>
      			</ul>
    		</div>
    		<div>一位練習一年半的練習生</div>
    		<div>唱、跳、rap</div>
  	</div>
  	 <div class="container">
    		<ul>
      			<li>html</li>
      			<li>CSS</li>
      			<li>javascript</li>
    		</ul>
   	</div>
  </body>
           

頁面效果:

CSS中的選擇器整理與選擇器權重

5、屬性選擇器

E[attr] 比對具有attr屬性的E元素:

示例:

div[title] {
	width:100px;
   	height:100px;
    	margin-top:2px;
    	background:pink;
}  
//比對到下文中的第一個和第三個div元素 因為他們含有title屬性
<div title="sing"></div>
<div></div>
<div title="dance"></div>
           

E[attr=val] 比對具有attr屬性且值為val的的E元素

示例:

div[title="sing"] {
	width: 100px;
      	height:100px;
     	margin-top:2px;
     	background:pink;
}  
//比對到下文中的第一個div元素,因為他含有title屬性且值為sing
<div title="sing"></div>
<div></div>
<div title="dance"></div>
           

E[attr~=val]比對屬性值為attr,并包含這個值的E元素,用于選取屬性值中包含指定詞彙的元素。

示例:

<style type="text/css">
  	div {
   		width: 150px;
   		height: 50px;
   		border: 1px solid gray;
  	}
  	div[title~="sing"] {
   		background: yellow;
 	 }
 </style>
 // 第一個和第三個div會被選中,因為他們的title屬性中都含有sing詞彙
 <body>
 	<div title="sing song"></div>
 	<div title="singsong"></div>
 	<div title="sing"></div>
</body>
           

頁面效果:

CSS中的選擇器整理與選擇器權重

E[attr|=val]比對所有屬性為attr,值為val或者以 var- 開頭的E元素

示例:

<style type="text/css">
   	div {
     		width: 150px;
     		height: 50px;
     		border: 1px solid gray;
   	}
   	div[title|="sing"] {
    	 	background: yellow;
   	}
 </style>
 // 第二個和第三個div會被選中,因為他們的title屬性分别是以"sing-"開頭或者直接為“sing”
 <body>
  	<div title="sing song"></div>
  	<div title="sing-song"></div>
  	<div title="sing"></div>
  	<div title="s-sing"></div>
</body>
           

E[attr^=" val"] attr屬性以val開頭的E元素(CSS3新增)

示例:

div[class^="box"] {
    	width:100px;
	height: 100px;
    	margin-top: 2px;
    	background: #000;
 }  
 //選擇到了前面三個div元素
 <div class="box"></div>
 <div class="boxBlue"></div>
 <div class="box1"></div>
 <div class="anotherBox"></div>
           

E[attr$=“val”] attr以val結尾的E元素(CSS3新增)

示例:

div[class$="Box"] {
	width: 100px;
	height: 100px;
	margin-top: 2px;
	background: #000;
}
// 選擇到前三個元素
<div class="Box"></div>
<div class="redBox"></div>
<div class="yellowBox"></div>
<div class="BoxContainer"> </div>
           

E[attr*=val] 選擇到attr包含值val的E元素(CSS3新增)

示例:

div[class$="box"] {
 	width: 100px;
 	height: 100px;
 	margin-top: 2px;
 	background: #000;
}
// 選擇到前三個元素
<div class="box"></div>
<div class="redbox"></div>
<div class="-box-"></div>
<div class="BoxContainer"> </div>
           

E[attr1][attr2=val]多屬性選擇器,比對屬性attr1和attr2同時滿足要求的E元素

示例:

div[class="box"][title|="container"] {
	width: 100px;
  	height: 100px;
  	margin-top: 2px;
  	background: #000;
}
// 選擇到前兩個元素
<div class="box" title="container"></div>
<div class="box" title="container-Box"<</div>
<div class="box"><div>
<div title="container"></div>
           

6、關聯選擇器(CSS3新增)

E1~E2:相同父元素中,選擇E1後面的元素E2

示例:

div~p {
	width: 100px;
	height: 50px;
	background: yellow;
}
// 選擇到div後面的三個p元素
<div></div>
<p></p>
<p></p>
<p></p>
           

7、僞類選擇器

錨僞類:

在支援 CSS 的浏覽器中,連結的不同狀态都可以不同的方式顯示,這些狀态包括:活動狀态,已被通路狀态,未被通路狀态,和滑鼠懸停狀态。

a:link {color: #FF0000}		/* 未通路的連結 */
a:visited {color: #00FF00}	/* 已通路的連結 */
a:hover {color: #FF00FF}  	/* 滑鼠移動到連結上 */
a:active {color: #0000FF} 	/* 標明的連結 */
           

注意:

  • 在 CSS 定義中,a:hover 必須被置于 a:link 和 a:visited 之後,才是有效的。
  • 在 CSS 定義中,a:active 必須被置于 a:hover 之後,才是有效的。
  • 僞類名稱對大小寫不敏感。
  • 問:既然a{}定義了超連結的屬性,a:link{}定義了超連結點選之前的屬性,那這兩個有啥差別呢?

    答:a{}和a:link{}的差別:a{}定義的樣式針對所有的超連結(包括錨點);a:link{}定義的樣式針對所有寫了href屬性的超連結(不包括錨點)

其他僞類:

first-child:比對第一個元素

示例:

// 比對所有p元素中的第一個i元素
<html>
<head>
	<style type="text/css">
		p>i:first-child {
			font-weight: blod;
		}
	</style>
</head>
<body>
	<p>some <i>text</i> some <i>text</i>.</p>
	<p>some <i>text</i> some <i>text</i>.</p>
</body>
</html>
           

lang僞類:比對帶有指定 lang 屬性的元素

lang 僞類使你有能力為不同的語言定義特殊的規則。

示例:

<html>
<head>
 	<style type="text/css">
		q:lang(no) {
			quotes: "~" "~"
		}
 	</style>
</head>
<body>
	<p>文字<q >段落中的引用文字</q>文字</p>
</body>
</html>
           

first-of-type(CSS3新增)

p:first-of-type:選擇的每個 p 元素是其父元素的第一個 p 元素

示例:

p:first-of-type{
    width:100px;
    height:100px;
    background: #000;
}
//父級下面所有p元素的第一個
<div>
	<p></p>
	<p></p>
	<p></p>
	<p></p>
	<p></p>
</div>
           

last-of-type

p:last-of-type 父級下面所有p元素的最後一個

only-of-type

p:only-of-type 父級下面隻有一個p元素,其他的元素不能是p,如果有其他元素那麼會選不中。

nth-of-type

p:nth-child(n) 選中父級元素中第n個p

nth-last-of-type(n)

p:nth-last-of-type(n) 選擇p,父級元素中倒數第n個p元素

8、僞元素選擇器

first-letter: 為文本第一個字母添加樣式

first-line: 為文本第一行添加樣式

before: 向文本之前添加元素(IE7以下不支援)

after: 向文本之後添加元素(IE7以下不支援)

示例:

<body>
	<p>對于你,我隻能是一顆 無言的星 在深邃的天庭 靜靜地閃爍 閃爍,卻不是為了誘惑 隻為了讓那皎潔
	的光 照亮你也照亮我 照亮一道純淨的小溪 照亮一條清澈的小河</p>
</body>
<style>
	p: first-letter {
		font-size: 50px;
	}
	p: first-line {
		background-color: #dafbef;
	}
/style>
           

頁面效果:

CSS中的選擇器整理與選擇器權重

補充:

(1)除了上面列舉的常用的,僞元素選擇器比較常用的還有

selection:[CSS4]應用于文檔中被使用者高亮的部分(比如使用滑鼠或其他選擇裝置選中的部分)。(IE8及以下不支援)(火狐-moz-selection),但需要注意隻有一小部分CSS屬性可以用于::selection 選擇器: color, background-color, cursor, outline, text-decoration, text-emphasis-color和text-shadow。要特别注意的是,background-image 會如同其他屬性一樣被忽略。

注意:::selection中的text-shadow屬性僅有Chrome, Safari 和 Firefox 17+支援。::selection CSS僞元素選擇器是CSS第3級選擇器的草案,但是在被推薦使用前就被廢棄。它現在在第4級僞元素選擇器草案中。

示例:

<style>
	::-moz-selection {
            	color: gold;
            	background: red;
        }
        ::selection {
            	color: gold;
            	background: red;
        }
        p::selection: {
        	color: white;
        	background: black;
        }
        p::-moz-selection: {
        	color: white;
        	background: black;
        }
</style>
<body>
	<div>我們無法與生活讨價還價,是以隻能拼命努力</div>
	<p>對于你,我隻能是一顆 無言的星 在深邃的天庭 靜靜地閃爍 閃爍,卻不是為了誘惑 隻為了讓那皎潔
 的光 照亮你也照亮我 照亮一道純淨的小溪 照亮一條清澈的小河</p>
</body>
           

頁面效果:

CSS中的選擇器整理與選擇器權重

其他的僞元素選擇器更為不常用且相容性很差,此處不再做介紹。

(2)與僞類一樣, 僞元素添加到選擇器,但不是描述特殊狀态,它們主要作用是為元素的某些部分設定樣式。

(3)有時你會發現僞元素使用了兩個冒号 :: 而不是一個冒号 :,這是CSS3的一部分,并嘗試區分僞類和僞元素. 大多數浏覽器都支援這兩個值。若頁面隻需要相容 webkit、firefox、opera 等浏覽器,建議對于僞元素采用雙冒号的寫法,如果不得不相容 IE 浏覽器,還是用 CSS2 的單冒号寫法比較安全。

(4)僞元素選擇器不會比對任何真實存在的html元素,是以也沒法通過DOM操作直接操作僞元素。

(5)before和after:

::before 建立一個僞元素,其将成為比對選中的元素的第一個子元素。常通過 content 屬性來為一個元素添加修飾性的内容。此元素預設為行内元素。::after類似,是以如果要給插入的内容添加寬高屬性必須通過display轉換,。

注意: 由::before 和::after 生成的僞元素 包含在元素格式框内, 是以能應用在可替換元素上, 比如或

元素。使用::before 和::after生成的僞元素的content不能夠被選擇。

上述内容可以解釋我在我的部落格《CSS中的浮動與清除浮動》中提到的利用before和after僞元素清除浮動。

(6)為什麼input元素不支援before,after僞元素插入内容?

答::before和:after僞元素指定生成的内容的樣式和位置。如其名所示,:before和:after僞元素指定了一個元素文檔樹内容之前和之後的内容。'content’屬性,與這些僞元素聯用,指定了插入的内容。作為DOM元素,僞元素都是在容器内進行渲染的。input無法容納其他元素,是以它不支援僞元素。按鈕也是在其他元素的支援下才由浏覽器呈現出來的。同理,img,iframe等元素都不能包含其他元素,是以不能通過僞元素插入内容。

三、選擇器的權重

在說明CSS選擇器的權重之前我們先一起看一下浏覽器如何實作頁面的解析渲染,我們以Webkit核心為例:

CSS中的選擇器整理與選擇器權重

上圖為Webkit核心渲染DOM的主要流程,我們可以看到其中HTML文檔解析和CSS規則解析是同時進行的,浏覽器有專門的html解析器來解析HTML,并在解析的過程中建構DOM樹,本文中不再對建構DOM樹的過程進行深入探讨及研究,HTML解析完畢後,開始建立呈現樹(又稱渲染樹)RenderTree,這一步的主要工作在于将CSS樣式應用到DOM節點上,通過分析CSS文檔,會生成如下圖所示的CSS規則樹狀圖,CSSRule會保持每個不同元素和對應樣式的映射關系。在渲染樹逐行生成的階段,DOM樹中的節點會在CSS分析樹中根據元素、類、id選擇器來提取與之對應元素的一條或多條CSSRule,進行CSS規則的層疊和權重計算,得到最終生效的樣式CSSRule并添加到DOM渲染樹上,當每個DOM節點提取CSS樣式完成時,用于頁面布局和繪制的DOM渲染樹便形成了。在一個已經形成的DOM渲染樹中,節點的CSS規則可通過document.defaultView.getComputedStyle (element, null)方法來擷取檢視,下圖是CSS解析結構示意圖:

CSS中的選擇器整理與選擇器權重

Webkit核心把進行CSS規則的層疊和權重計算,得到最終生效的樣式CSSRule并添加到DOM渲染樹上這一過程稱為附着,這一過程會涉及到CSS選擇器的權重問題

首先将根據樣式的重要性排序,由低到高依次為:

1> 浏覽器聲明;

2> 使用者普通聲明;

3> 作者普通聲明;

4> 作者重要聲明;

5> 使用者重要聲明;

對于同一重要級别,則是根據CSS選擇符的特指度來判定優先級: 一條樣式聲明的特指度由以下四部分決定: S-I-C-E

1> 聲明來自内聯的style屬性則 S+1;

2> 聲明中含有Id屬性則 I+1;

3> 聲明中含有類、僞類、屬性選擇器則 C+1;

4> 聲明中含有元素選擇器、僞元素選擇器則 E+1;

特指度比較規則如下:

  • 先從高等級進行比較,高等級相同時,再比較低等級的,以此類推;
  • 完全相同的話,就采用 後者優先 原則;

示例:

// 假設下面樣式都作用于同一個節點元素`span`,判斷下面哪個樣式會生效
body#god div.dad span.son {width: 200px;}
body#god span#test {width: 250px;}
           

兩種方式的S都為0,第一種的I為1,第二種為2,是以最終span元素的寬度為150px,即第二個樣式會生效。

注意:在css中,!important的權重相當的高。如果出現了!important,則不管權重如何都取有!important的屬性值。但是寬高有例外情況,由于寬高會被max-width/min-width覆寫,是以!important會失效。

示例:

span { 
	width: 100px!important;
	min-width: 200px;
}
           

上面代碼浏覽器解析後最終賦給元素的寬度為200px