CSS選擇器世界


CSS選擇器世界

CSS選擇器的分類與優先級

css選擇器分為四類:選擇器、選擇符(后代關系的空格、>、+、~、||)、偽類、偽元素(::before、::after、::first-letter等)。

css的優先級:
css的優先級有很多划分方法,所有的方法其實都大同小異。這里將CSS優先級划分為6個等級:

  • 0級:通配選擇器(*)、選擇符(+、>、~、空格、||)、邏輯組合偽類(:not()、:is()等)
  • 1級:標簽選擇器
  • 2級:類選擇器、屬性選擇器、偽類
  • 3級:ID選擇器
  • 4級:style內聯屬性
  • 5級:!important

CSS優先級的計算規則:0級選擇器優先級數值+0,1級選擇器+1,2級選擇器+10,三級選擇器+100

#foo a:not([ref=nofollow]){}     優先級數值:100+1+0+10 = 111

tips1:增加CSS優先級的小技巧
重復自身選擇器,如以下選擇器即提高了優先級,又不會增加耦合:
.foo.foo
或者如下寫法:
.foo[class] 、 #foo[id]
tips2: 實現類似:first-child的效果
有如下場景,我們希望列表除了第一個第一個以外其他的都有margin-top,一般我們會這樣寫:

1:.cs:not(:first-child){margin-top:1em;}
2:.cs{margin-top:1em};
.cs:first-child{margin-top:0}

下面我們利用兄弟選擇器:

.cs+.cs{margin-top1em}

tips3:實現前面兄弟選擇符的效果
如下場景:輸入框聚焦時,前面文字高亮顯示
1:flex布局;
2:float浮動;
3:absolute絕對定位;
4:direction屬性實現,代碼如下:

<div class="cs-direction">
  <input class="cs-input"><label class="cs-label">用戶名:</label>
</div>

.cs-direction{
  direction: rtl
}
.cs-direction .cs-input,.cs-direction .cs-label{
  direction: ltr;
}
.cs-label{
  display:inline-block;
}
:focus + .cs-label{
 color: darkblue;
 text-shadow: 0 0 1px;
}

注意:使用direction屬性時,針對的必須為內聯元素,因此,對於塊級元素需進行轉化為內聯

屬性選擇器

  • [attr]

  • [attr = ''val']

  • [attr ~= 'val']

  • [attr ^= 'val']

  • [attr $= 'val']

  • [attr *= 'val']

用戶行為偽類

1:手型經過偽類:hover(支持所有HTML元素)

一個簡單的應用場景:當鼠標經過a標簽時,'顯示' 文字顯示,因為:hover是即時的,所以通過transition對visibility進行過渡(trantion對display不起作用)起到時延作用。

  <a href class="icon-deletedata-title="顯示">刪除</a>

.icon-delete{

    display: inline-block;
    height: 20px;
    position: relative;
  }
  .icon-delete::before{
    content: attr(data-title);
    position: absolute;
    bottom: 30px;
    left: 0;
  }
  .icon-delete::before,
  .icon-delete::after {
    transition: visibility 00.2s;
    visibility: hidden;
  }
  .icon-delete:hover::before,
  .icon-delete:hover::after {
    visibility: visible;
  }

純hover顯示浮層的體驗問題:純hover顯示浮層確實很方便,但是如果鼠標壞了,或者是觸屏設備通過Tab來切換,如果是一個下拉列表,那么久完全癱瘓了,我們可以通過增加:focus來優化css,上述代碼可以優化為:

<a href class="icon-deletedata-title="刪除">刪除</a>

 .icon-delete{

    display: inline-block;
    height: 20px;
    position: relative;
  }
  .icon-delete::before{
    content: attr(data-title);
    position: absolute;
    bottom: 30px;
    left: 0;
  }
  .icon-delete::before,
  .icon-delete::after {
    transition: visibility 00.2s;
    visibility: hidden;
  }
  .icon-delete:hover::before,
  .icon-delete:hover::after {
    visibility: visible;
  }
.icon-delete:focus::before,
.icon-delete:focus::after {
    visibility: visible;
    transition: none;
}

但是,上述並沒有解決所有的問題,如果浮層的內部有鏈接或者按鈕的話,使用:focus浮層內的連接或者按鈕是無法被點擊的,因為Tab在切換焦點元素的時候,浮層會失焦而迅速隱藏。這時需要另外一個偽類:focus-within來解決,詳細我們在下面討論。


2:激活偽類:active
:active可以用於設置元素激活狀態的樣式,可通過點擊鼠標主鍵,也可以通過手指或者觸控筆點擊觸摸屏觸發激活狀態。具體表現為 點擊按下觸發,點擊抬起取消。:active支持所有HTML元素

:active的不足之處:

  • IE瀏覽器下,:active無法冒泡。即當一個元素與父級都設置:active樣式時,點擊子元素,父元素的:active不會被觸發
  • IE瀏覽器,html、body用:active設置背景后,背景色無法還原;
  • 移動端safari瀏覽器下,:active偽類默認無效

按鈕的通用:active樣式技巧(主要應用移動端)
在桌面端可以通過:hover來反饋狀態變化,移動端只能通過:active來反饋,移動端有很多需求點擊反饋鏈接跟按鈕,有如下通用技巧:

  • 使用box-shadow(兼容IE9,該方法對非對稱閉合標簽無效)
 [href]:active,button:active{
    box-shadow:  0 0 0 999px rgba(0,0,0,.05);
  }
  • 使用linear-gradient線性漸變(兼容IE10以上)
[href]:active,button:active,[type=reset]:active,[type=button]:active,[type=submit]:active{
  background-imagelinear-gradient(rgba(0,0,0,.05),rgba(0,0,0,.05));
}

3:焦點偽類:focus(支持IE8+)
:focus只能匹配特定的元素,包括:

  • 非disabled狀態的表單元素;
  • 包含href的<a>元素
  • <area>、<summary>

那么如何讓普通的元素也可以用:focus偽類呢?
設置HTML tabindex屬性,如下寫法:

 <div tabindex='-1'>內容</div>
 <div tabindex='0'>內容</div>
 <div tabindex='1'>內容</div>

如果期望<div>元素被Tab索引,且被點擊的時候觸發:focus偽類樣式,設置tabindex='0';如果期望不希望被索引,只在點擊的時候觸發:focus,則設置為-1。
如下,實現點擊一個圖標顯示大圖的交互:

<span class="cs-smalltabindex='0'></span><span class="cs-big"></span>

.cs-small{

    display: inline-block;
    width: 10px;
    height: 10px;
    background: green;
  };
  .cs-big{
    display: inline-block;
    width: 50px;
    height: 50px;
    background: green;
    margin-left: 10px;
    display: none;
  };
  :focus + .cs-big{
    display: inline-block;
  }

實際上,使用tabindex也並不是那么完美,在ios safari瀏覽器下,元素處於focus狀態后,除非有其他可聚焦的元素轉移焦點,否則會一直保持聚焦狀態。解決方法只需要再套個父盒子,設置tabindex=‘-1’,同時該復盒子需要取消outline樣式(outline:0 none;)

4:整體焦點偽類:focus-within(移動端以及非IE瀏覽器)

:focus-within功能通:focus類似,但是:focus是對當前元素而言,:focus-within在當前元素或者當前元素的子元素處於聚焦狀態都會匹配。
例::focus-within 實現無障礙訪問的下拉列表,解決上面:focus在浮層里也有鏈接無法Tab切換的問題:

<div class="cs-bar">
        <div class="cs-details">
          <a href='javascript:void(0)' class="cs-summary">我的消息</a >
          <div class="cs-datalist">
            <a href class="cs-datalist-a">我的回答<sup class="cs-datalist-sup">12</sup>
            </a >
            <a href class="cs-datalist-a">我的私信</a >
          </div>
        </div>
      </div>

cs-bar {
    background-color: #e3e4e5;
    color: #888;
    padding-left: 40px;
    margin-bottom: 200px;
  }
  .cs-details {
    display: inline-block;
    text-align: left;
  }
  .cs-summary {
    display: inline-block;
    padding: 5px 28px;
    text-indent: -15px;
    user-select: none;
    position: relative;
    z-index: 1;
  }

  .cs-datalist {
    display: none;
    position: absolute;
    min-width: 100px;
    border: 1px solid #ddd;
    background-color: #fff;
    margin-top: -1px;
  }

  .cs-datalist-a {
    display: block;
    padding: 5px 10px;
    transition: background-color 0.2s, color 0.2s;
    color: inherit;
  }
  .cs-datalist-a:hover {
    background-color: #f5f5f5;
  }
  .cs-datalist-a:active {
    background-color: #f0f0f0;
    color: #555;
  }
  .cs-datalist-sup {
    position: absolute;
    color: #cd0000;
    font-size: 12px;
    margin-top: -0.25em;
    margin-left: 2px;
  }
   .cs-details:focus-within .cs-summary,
   .cs-summary:hover {
     background-color: #fff;
   }
   .cs-details:focus-within .cs-datalist {
     display: block;
   }

URL定位偽類

:link偽類(基本被a標簽取代,不做討論)

:visited偽類(怪癖最多的CSS偽類)

  • 1:支持:visited的CSS屬性有限
    目前僅支持以下CSS: color、background-color、border-color、border-bottom-color、border-top-color、border-left-color、border-right-color、column-rule-color、outline-color。類似::before跟::after也不支持。
    例:實現訪問過的連接文字后面加上一個visited的字樣
<a href=''>文字<small></small></a>

  small{
    color: white;
  }
  small:after{
    content: 'visited';
  }
  a:visited small{
    color: lightskyblue;
  }
  • 2:沒有半透明,該偽類控制顏色時,加透明度無效
  • 3:只能重置,不能憑空設置
    如下:
a{
 color: blue;
}
a:visited{
 color: red;
 background-color: gray;
}

以上代碼設置只會使color生效。

  • 4:無法獲取:visited設置和呈現的色值
    該偽類設置的色值,用js的getComputedStyle()無法獲取。

:any-link偽類(IE9+)
兩大特性:
1.匹配所有設置了href的連接元素,包括<a>、<link>、<area>
2.匹配所有匹配:link偽類或者:visited偽類的元素(:link只匹配沒有訪問過的連接)
目標偽類:target
URL錨點可以跟頁面中元素的id匹配進行錨定,例:

<div>
       <p id='cs-first'>第一行,id:cs-first</p>
       <p id='cs-second'>第二行,id:cs-second</p>
       <p id='cs-last'>第三行,id:cs-last</p>
     </div>

p:target{
    font-size: bold;
    color: skyblue;
  }

通過鏈接的hash值就可以匹配到對應的元素

樹結構偽類

:root偽類
在html中:root等同於html元素;
:empty偽類

  • :empty用來匹配空標簽元素
  • :empty偽類可以匹配前后閉合的替換元素(button、textarea等);
  • :empty偽類匹配非閉合的元素(input、img等)

若元素有注釋或者空格、換行等都是不能匹配到的
::before、::after都可以插入內容,但是不會影響:empty的匹配

:empty的實際應用

  • 隱藏空元素。
    比如像一個動態列表有內容的時候可能會加margin、padding等布局,但是沒有內容的時候就會空出一大塊,這時候就可以用:empty偽類在匹配到空的時候隱藏掉。
  • 字段缺失只能提示
    如在一個動態詳情列表中,如果對應的字段沒有內容,則在后面顯示 '暫無'的字樣,代碼如下:
  <dl>
   <dt>姓名:</dt><dd>張三</dd><br/>
   <dt>年齡:</dt><dd></dd><br/>
   <dt>身高:</dt><dd>178cm</dd>
  <dl>

  dt,dd{
    display: inline-block;
  }
  dd:empty:before{
    content: '暫無';
  }

子索引偽類

:first-child、:last-child
:only-child
:nth-child()偽類和:nth-last-child()偽類

適用於動態匹配場景,可以匹配制定索引序號的元素。參數可以是關鍵字(odd/even),也可以是函數符號。
函數符號形式如下:

  1. An+B: A、B必須為整數,n前面可以有負數,n為從1開始的自然序列(0,1,2…..),第一個子元素匹配序號為1.
  2. 一些示例:
  • tr:nth-child(odd),匹配1、3、5…..行;
  • tr:nth-child(even),匹配2、4、6…..;
  • li:nth-child(1),匹配第一個;
  • li:nth-child(n+4):nth-child(-n+10): 匹配4-10個li
:first-of-type偽類和:last-of-type偽類

表示當前標簽類型元素第一個和最后一個

:only-of-type
:nth-of-type()偽類和:nth-last-of-type偽類

:nth-of-type與:nth-child的不同之處::nth-of-type匹配的是所有相同標簽的兄弟元素,而另一個無視標簽類型。

<div>
  <h3>標題一</h3>
  <p>段落一</p>
  <p>段落二</p>
  <h3>標題二</h3>
  <p>段落三</p>
  <p>段落四</p>
</div>

  p:nth-child(2n+1){
    color: red;
  }
  p:nth-child(4n){
    color: darkblue;
  }
  p:nth-of-type(2n+1){
    color: skyblue;
  }

圖中,第2、5行為淺藍色,第三行為紅色。

邏輯組合偽類

否定偽類:not()
:not()主要的應用場景為重置CSS
例:input:not(:disabled):not(:read-only)()
表示匹配所有不處於禁用,也不是只讀狀態的input

例: 列表一行5個,每個都向右有空隙,每一行的最后一個沒有空隙;

 li:not(:nth-of-type(5n+1)){
   margin-right10px;
 }

任意匹配偽類:is()
例:

  .cs-a img,.cs-b img,.cs-c img,.cs-d img{
    border1px solid skyblue;
  }
  可以簡化為如下:

  :is(.cs-a,.cs-b,.cs-c,.cs-dimg{
    border1px solid skyblue;
  }

:where()、:has()

輸入偽類

輸入控件狀態:

可用狀態與禁用狀態偽類 :enabled和:disabled (IE9+)
  • 對於表單元素來說,:enable跟:disabled是完全對立的。但是有一個例外<a>元素,在chrome瀏覽器下,帶href的a元素是可以匹配:enabled偽類的,但是卻無法匹配:disabled偽類,其他瀏覽器也有各種各樣的問題,不展開討論。
  • 設置tabindex屬性的元素不能匹配:enabled偽類;
  • 元素設置visibility:hidden跟display:none的能夠匹配:enabled偽類跟:disabled偽類。
讀寫特性偽類:read-only和:read-write

readonly與disabled的區別:
設置readonly的輸入框不能輸入內容,但是可以被表單提交;
設置disabled的輸入框不能輸入內容美也不能被表單提交。

占位符顯示偽類:placeholder-shown(除IE)

表示當輸入框的placeholder內容顯示的時候,匹配輸入框
由於其只在內容為空值狀態的時候才顯示,所以我們可以借助placeholder-shown偽類來判斷一個輸入框是否有值。
例: 輸入框沒有值得時候顯示空值提示

input:placeholder-shown + small:before{
  content'尚未輸入驗證碼';
  color: red;
}
默認選項偽類default

輸入值狀態:

選中選項偽類:checked
  1. :checked與[checked]的比較:
  • :checked只能匹配標准的表單控件元素,[checked]可以與任意元素匹配;
  • [checked]是非實時的,因此不建議用此屬性選擇器;
  • 偽類可以從祖先元素繼承;
不確定值偽類:indeterminate

輸入值驗證:

有效驗證偽類:valid和:invalid
范圍驗證偽類:in-range和:out-of-range
可選性偽類:required和:optional

 

參考資料:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM