CSS選擇器有不少種,每次看別人寫的跟背書同樣,沒辦法,種類就那麼多,只能一一羅列,還能玩出什麼花樣?因此重要的就是清楚爲何要這樣用,好處在哪裏了。javascript
若是咱們的網頁只是像老闆吩咐咱們作3件事的清單那樣簡單,作完一件劃掉它,因此一眼能夠看出哪件已作,哪件沒作,而html網頁是有結構的、嵌套的標籤組織起來的文本形式,又多又長,因此須要選擇器來快速定位,以應用咱們添加給它的樣式,所以瞭解選擇器頗有意義。css
1. 標籤選擇器html
在CSS中,有的標籤自己已經具備一些樣式,好比h1,一般會做爲標題,它的字體比通常的大,默認爲粗體,並且是塊級標籤,四周有margin值。標籤選擇器,本質上來講,就是給一個標籤從新定義樣式。仍是h1,由於用它做標題有利於搜索引擎,因此常常用,但它自帶的樣式有時(恐怕是多時)與網頁佈局顯得很不合理,因此咱們徹底能夠重寫它的樣式,改變字體大小,去掉margin等,以達到總體控制的效果。只要重定義了它的樣式,直接用h1將顯示運用了新樣式後的文本內容,這樣更和諧了。前端
h1{font-size:1em;}
2. 類選擇器java
既然是類,更多的是對一個或幾個元素產生影響,爲了減小工做量和精確控制,對相同的類型的一些元素給一個相同的class名,是很不錯的選擇,重點是能夠在一個class中添加多個類名,更加省時。如這裏三個選擇器各添加不一樣的樣式,都會加載到這段文本上。固然CSS樣式是就近原則,後面的覆蓋前面的,優先級高的覆蓋優先級低的,因此假如mr也設置了font-size,它將覆蓋掉ft選擇器中的font-size。css3
.ft{font-size:24px;} .mr{margin:10px;} .fl{float:left;} <p class="ft mr fl ">Hello World</p>
專業的前端一般會同時使用幾個類,一個fl,表示飄浮到頁面左邊,單獨寫一個樣式,須要時就加上,所以它更像一個工具,拆分紅多個類名,擴展性更強。注意類名中能夠出現 - 或 _ ,這是容許的。chrome
3. ID選擇器編程
ID給人一種惟一標識的感受,因此它常常是刻劃網頁上一個特殊的部位,更多的是表示某一部份內容,好比橫幅(banner)、邊欄(sidebar)、主要內容(main)等,如劃分一個大塊時常常這樣像下面這樣,固然若是你說我就喜歡用ID選擇器,我把全部的標籤都加ID,惟一結果就是確定不會有人過去咬你-_-#瀏覽器
#news{ margin-left:10%; font-family:"Times New Roman" } <div id="news"> ........ </div>
關於ID有個重點就是它具備高優先級,好比下面ide
#link{ color:red; } .link{ color:blue; } <a id="link" class="link" href="#">To Somewhere</a>
它是紅色仍是藍色?演示就知道是紅色,由於ID選擇器具備更高的優先級,瀏覽器會根據ID和class(或者組合)計算出一個權重值,誰的大用誰的樣式(理論上是這樣,但用Chrome試過好像也不必定),權重值的計算若是深究也有點麻煩,特別是不僅一個ID、class、標籤糾纏在一塊兒時。如何計算權值網上也有文章分析,固然咱們何須要爲難本身呢,至少我本身(向前端學的)有時作簡單的頁面,只用類選擇器,只在有時用js時爲了快速取到元素才加id,基本不用ID選擇器添加樣式,避免麻煩。
4. 羣選擇器
若是看過專業前端的css代碼,確定在最開頭有相似這樣的:
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li{ margin: 0; padding: 0; }
一開始偶不明白爲什麼弄這樣一大堆標籤,覺得是設計時對樣式從總體到局部的把握,因此先給全部的標籤元素一兩個基本的、總體的樣式,像這裏margin、padding就是讓它們全部的標籤都歸爲0。後來發現,這麼說也不能說全錯,但更重要的是,不少瀏覽器在處理一些自帶樣式的標籤時(如h1~hn),雖然左右是有空白的,但有的使用margin,有的使用padding,不統一可能帶來樣式上的錯亂,爲了讓樣式在更多瀏覽器上顯示一致,因此這裏乾脆去掉它們的margin、padding,當要使用某個標籤時,再給單獨添加margin、padding。這裏的一大堆標籤,以逗號分隔的選擇器,稱爲羣選擇器,表示把它們都設置成一個後面括號中樣式。羣選擇器不限於標籤,class、id也能夠這樣幹:.link, .news, #banner{...}。羣選擇器在設置一大堆具備相一樣式的標籤、類、ID時很方便。關於上面那個一大堆把margin、padding置爲0的、提升顯示一致性設計,有個名字叫CSS Reset,樣式重置,這是偶這種小白日常用不到的。
5. 通用選擇器
羣選擇器一次設置多個很爽,堆在一塊兒用逗號分隔便可,還有更爽的,就是通用選擇器,它就是一個 * ,表明全部選擇器(通用嘛),好比下面
h1, h2, p{font-weight:bold;}
* {font-weight:bold;}
第二個通用選擇器等同於設置了第一個羣選擇器的內容,固然能比它表明更多的東西。
6. 派生選擇器
這應該是專業前端最最經常使用的類型了,也稱後代選擇器。咱們知道html標籤是嵌套的,外面的是父元素,裏面的是子元素,固然父子關係是相對的,這叫作html的族譜,固然它也有根節點,兄弟節點等,這根二叉樹徹底同樣,因此也有相應的父標籤、祖先標籤、兄弟標籤等等。好比像這樣的
<div id="nav"> <ul class="nav"> <li></li> <li></li> </ul> </div>
ul是div的子標籤,li是ul的子標籤,id選擇器在類選擇器nav的標籤的父標籤裏邊,因此定位到<li>標籤的選擇器能夠這樣寫:
#nav .nav li{...}
須要注意的地方就是中間有空格,空格表示子標籤,或者是位於子標籤中的選擇器,即一種父子關係,子孫關係也可,爺孫關係固然也行,總之就是:派生關係。對於派生選擇器,若是不隔一個空格就是徹底另外一種狀況,好比這裏若是寫 div#nav ul{...}(div緊挨着#nav)表示的就是:<div id="nav"><ul>,給id爲nav的div標籤,它的子標籤爲ul設置樣式,是一個限制的而且關係,若是是div #nav ul{...},就是div標籤的id爲nav的子標籤,它的子標籤爲 li 時的狀況。空格很重要!
看看專業前端的代碼,派生選擇器會佔到百分之八九十,並且風格比較統一,派生時儘量用class,固然最後會有一些標籤選擇器,但風格真的很好,不是一下子類選擇器,又夾個ID選擇器,再來個標籤選擇器,最後再搞個ID選擇器,這樣看起來十分紊亂,一點也不絲滑,專業人士寫的就是有種和諧的美感。
除了一會ID選擇器一下子類選擇器很差看以外,有個很大的緣由是:頗有可能你設計的這個樣式根本沒有運用到指定的地方,雖然很但願是它用到你指定的地方。好比
<div id="id_wrap" class="cl_wrap"> <p id="id_seg" class="cl_seg"> Hello World </p> </div> 1 div p {...} 2 #id_wrap #id_seg{...} 3 .cl_wrap .cl_seg{...} 4 .cl_wrap #id_seg{...} 5 div #id_seg{...} 6 div .cl_seg{...} 6 .cl_wrap p{...} 7 #id_wrap p{...}
8 div.cl_wrap p{...}
9 #id_wrap p.cl_seg{...} ... ...
這9個樣式均可以運用到Hello World上(單獨寫的話),繼續組合下去,還有,若是把這些都寫出來,最後哪個會真正加載到文本內容上呢?這裏就有一個權重值的問題,前面說過,就權值來講,ID選擇器最大(在選擇器中),看過一本書上說:標籤選擇器1分,類選擇器10分,ID選擇器100分,內建樣式1000分。內建樣式便是相似<div style="width:100px;">這樣的,直接在標籤上給style。而後將用到的選擇器權值按類型不一樣相加(如div p 是2分,.cl_wrap #id_seg 是110分,div.cl_wrap p是12分),結果最大的最終運用到指定內容上,可是貌似也不許確...不知道我測的對不對。計算完了,還要結合就近原則,看看哪些屬性被覆蓋了,哪些是繼承了父元素的(如font-size,若是父元素是16px,子元素的font-size若是寫的是100%就是16px,若是父元素是24px,子元素設置150%就是36px),還要看看哪些是永遠保留的樣式(下面,就近原則也覆蓋不了)等等,這麼搞下去怕早晚要瘋掉...
/* !important表示這個屬性將永遠不會被覆蓋 */
.seg{ font-style:bold !import; }
有文章對這個權值進行計算分析,偶就仍是懶惰的逃避了...因此專業前端的用類選擇器是沒有錯的,只要定位得夠精確,遵循統一規範,不臨時變道加個ID選擇器之類的,基本不會出錯。
使用派生選擇器的另外一大優勢就是節省工做量。一個劃分好佈局的網頁上,一塊塊的div中風格老是儘可能的保持統一,從父元素到子元素總有不少屬性相同,而css的樣式是能夠繼承的,好比父元素的字體時16px,若是子元素不設置font-size,子元素中的字體大小將也是16px,固然也不是全部的樣式均可以繼承(有專門列表),如line-height行間距,這是合理的,若是父元素16px的字體大小行間距是16px,若是如今子元素的字體爲54px額行間距還是16px,就可能使得子元素中的字體行之間很緊湊甚至發生重疊,由於字體大小增大了不少行間距沒變,試試能夠看到效果。正式因爲樣式的可繼承性,致使派生選擇器更好用了。
7. 子選擇器
根據html中標籤結構的父子之分而來,形式 A > B,尖括號表示父子關係,注意說B是A的子節點,不必定是直接後代,多是多是孫子、曾孫、曾曾孫,編程中的父子結構相信你知道。但在這裏,div > p{...}表示div標籤中的全部直接子標籤p,而div p表示的是div的全部直接或間接的後代節點中的p標籤。
8. 同胞選擇器
對共一個父元素的標籤而言,它們是兄弟(或者姊妹?)關係,在css中叫同胞,而在位置上緊挨着的是臨近同胞,因此css針對這種結構有一種稱爲臨近同胞選擇器,如
<div> <h1>head</h1> <p>Hello</p> </div> /******/ h1 + p {...}
h1和p是臨近同胞(兄弟),h1 + p 則表示選則了緊挨在h1後面,與h1共父元素的標籤p。
9. 通用同胞選擇器
它是對同胞選擇器的延伸,h1 + p只能對具備兄弟關係,且緊挨在h1後面的p元素起做用,那麼 h1 ~ p就表示選中了具備兄弟關係的,h1後面的全部p標籤。
<div> <h1>Hello</h1> <strong>Hello</strong> <p>我被選中</p> <em>Hello</em> <p>我被選中</p> </div>
10. 僞類
僞類選擇器有不少,有時咱們匹配的不是單個元素,而是某種狀態,某種特殊的結構(簡單的兄弟選擇器表達不出來),或者某個動做的瞬間,好比鼠標滑過連接時,無序列表中的奇數列,這種狀況的選擇器,css給了個名字:僞類。
捕捉動做的,最多見的是連接,,a:link,a:visited,a:hover,a:active,分別表示未訪問前,已訪問過,滑過期,鼠標點擊的一瞬間,a與:之間沒有空格。這四個僞類的設置是有順序的,就是這裏所列出的,若是hover放到了link的前面(以下),鼠標滑過期會發現連接仍是綠色的,由於他們的權重都相同,按照就近原則,後邊的樣式覆蓋前邊的(樣式衝突),鼠標滑過應用的將是a:link的樣式,因此要按順序來,某書介紹了一種記法 LoVe, HAte。 在有些選擇器上,hover不只是連接的專利,好比p:hover,滑過段落時改變樣式,固然只是一些瀏覽器、一些高版本的能夠,得看具體狀況。僞類的書寫不必定前面就是標籤,<a id="lnk">能夠是#lnk:hover,css不少地方均是同理,不要理解的很死板。
a:hover{color:red;}
a:link{color:green;}
:focus捕捉當得到焦點時的響應,如文本框變背景色。
匹配目標,:target,若是一個url中帶有#aaa,剛好html中有帶有id爲aaa的標籤,則匹配的是它,它用在頁面內的錨點,以下,點擊跳到頁面內跳到錨點處能夠發現它的樣式已經改了(不知道br夠不夠)
div :target{background-color:red;} <p><a href="#goto">跳到頁面內goto</a></p> <br/><br/><br/><br/><br/><br/><br/> <br/><br/><br/><br/><br/><br/><br/> <br/><br/><br/><br/><br/><br/><br/> <br/><br/><br/><br/><br/><br/><br/> <br/><br/><br/><br/><br/><br/><br/> <br/><br/><br/><br/><br/><br/><br/> <div> <p name="goto" id="goto">錨點goto</p> </div>
捕捉根節點,:root,html頁面就是html節點了。
捕捉特殊子節點的,:first-child、:last-child、:first-of-type、:last-of-type等。字面義可看出是第一個子節點,或第一個子類型。值得注意的是p:first-child與p :first-child徹底不一樣(後者兩個之間有空格),前一個很容易覺得,它是指p標籤的第一個子節點,但實際上第二個纔是這樣的正確寫法,而p:first-child指的是,p做爲其餘標籤的第一個子標籤,它匹配的應該是這樣的
<div> <p>匹配了這裏</p> <span><p>也匹配了這裏</p></span> </div>
同理,p:first-of-type,指的是,做爲其餘元素的子元素,匹配的第一個出現的標籤爲p的元素,即首先,p是其餘元素的子元素,第二,匹配的是子元素中第一個出現的p標籤,前面有其餘的類型子標籤沒關係,只要不是p就行,即便它後邊還有相同的p兄弟標籤,由於不是第一個出現的,也不符合。
這種有點麻煩的狀況,就要問問,它是它的子元素嗎?它是它下面第一個出現的x標籤嗎?符合就是對的,如
<div> <h1>標題</h1> <span> <p>我是span的子標籤中第一個出現的p</p> </span> <p>我是div的子標籤中第一個出現的p</p> </div>
而 p :first-of-type(有空格),是指p標籤下的第一個子元素,由於沒指定類型,因此只要是p標籤下邊的第一個子類型,就會匹配到,等同於p :first-child,若是是p span:first-of-type,就是指p標籤下,第一個類型爲span的子標籤。
匹配只有一個子元素的,:only-child,如p:only-child(沒有空格),匹配以p做爲子元素,且它的父元素只有它這一個子元素的狀況。
按必定規律的匹配子元素,以:nth-child爲例,從字面意義可知是第n個子元素,形式很是靈活。好比如今有一個無序列表欄目,以它爲例
<ul class="nav"> <li>A</li> <li>B</li> <li>C</li> <li>D</li> <li>E</li> </ul>
第一種,直接給一個數值,.nav li:nth-child(2)表示:li是類名爲nav的子標籤,且匹配第2個這樣的標籤,這裏li都是ul的子標籤,匹配其中第二個就是B了。
第二種,匹配奇偶項,如.nav li:nth-child(odd),表示匹配列表中奇數項列表,括號裏的odd是個參數,表示尋找奇數列(單詞也表此意),A是第1列(從1開始計數),C是第3列,包括第5列E都符合,同理有偶數匹配,.nav li:nth-child(even)。
第三種,使用表達式,好比.nav li:nth-child(2n+3),css不只本身知道第一條列表的n值是1,第二條是2,並且在計算2n+3是幾的時候,從0開始取天然數,因此2n+3就是對應着第3條、第5條、第7條...這種帶n的表達式更加靈活。
ok,相似於:nth-child,還有:nth-of-type(n)、:nth-last-child(n)(倒數第幾個)、:nth-last-of-type(n)(倒數第幾個類型)等等就很好理解了。
僞類中還有匹配某種狀態的,以下,好比哪些文本框不可用(設置了disable屬性),單選框是否被選中等
.txt:checked
.txt:enabled
.txt:disabled
11.僞元素
匹配某個元素的特殊位置,起了個名字叫僞元素。以下,如字面義,:before匹配p標籤文本內容的開始地方,:after匹配其結束的地方,content的內容規定在文本開始加上Start,結束時加上End~。first-letter匹配首字母,first-line匹配首行。
p:before{content:'Start";}
p:after{content:"End~"}
p:first-letter{color:red;}
p:first-line{color:green;}
12.屬性元素
屬性元素很是經常使用,特別在js中,怎麼能少的了。屬性選擇器固然跟標籤帶有的屬性相關,就是根據這些標籤帶有的某些屬性來作的匹配
第一種,如A[attr],匹配帶有attr屬性的A標籤,以下,匹配帶有target屬性的a標籤,所以捕捉到第2個<a>
a[target]{color:green;} <a href="http://www.css.org/">to css</a> <a href="www.example.com" target="_blank">to example</a>
第二種,A[attr=value],匹配帶有attr屬性且屬性值爲value的元素,那麼上例的匹配能夠這樣寫,a[target=_blank]{...},將_blank加引號也可。
第三種,A[attr~=letter],匹配帶有attr標籤,且標籤的屬性值中帶有letter單詞的A元素,如
p[class~=news]{color:red;} <p class="wrap news"></p>
第四種,A[attr|=value],匹配帶有attr屬性,且屬性值以value開頭或者value-開頭,最適合的就是規定元素語言屬性的時候,在html頁面中可告知瀏覽器,這裏用什麼語言,有個lang屬性,以下,匹配的是第一個。
p[lang|=en]{color:red;} <p lang="en-us">I am CSS</p> <p lang="zh-cn">層疊樣式表</p>
第五種,使用通配符*,A[attr*=value],只要A標籤帶有attr屬性,且屬性值中包含字符串value即匹配
最後兩種,檢測屬性值的開頭和結尾,分別是A[attr^=value]:匹配帶attr屬性,且屬性值以value開頭的A元素,如檢查連接a[href^=http],而A[attr$=value]則匹配以value結尾的attr屬性值的A,如某些下載連接檢測a[href$='.zip']。
最後屬性選擇器徹底能夠混用,好比在某個表單中,用jQuery選中元素對象時
<div> <input type="radio" name="type" value="big" />big<br/> <input type="radio" name="type" value="medium" checked />medium<br/> <input type="radio" name="type" value="small" />small<br/> </div> <!--須要引入jQuery文件--> <script type="text/javascript"> alert($("input[type=radio][name=type][checked]").val()); </script>
其中input[type=radio][name=type][checked],就是對多個屬性的同時使用,本例想打印type屬性爲radio、name屬性爲type、有checked屬性(被選中)的元素的value值,須要引入jQuery文件。這個好像不用寫得這麼麻煩,忽然忘了。
---------------------------------------------------------------------------------------------------------
在上面的$("input[type=radio][name=type][checked]")在某些瀏覽器上卻取不到對象,好比chrome,也是醉了...,能夠這麼幹:$("input[type=radio][name=type]:checked")或者$("input:radio[name=type]:checked"),這樣更通用。對於select下拉框也是這樣,好比
<select name="scheme"> <option value="1" selected>1</option> <option value="2" selected>2</option> <option value="3" selected>3</option> </select>
能夠這麼取:$("select[name=scheme] option:selected"),而$("select[name=scheme] option[selected]")要麼取不到對象,要麼沒法動態獲取對象,它獲取的可能永遠是指定了selected的選項,此處有坑。
這些有的屬於css2,有的是css3,並且不必定各個瀏覽器通用,偶只是知道有這麼回事,沒去分個類,原諒我白癡=_=