【Hello CSS】第五章-CSS的選擇器與函式

陳大魚頭發表於2019-04-13

在上一篇的HTML的標籤與語意中簡單的介紹了HTML標籤跟其一些屬性,向各位堅持看到這裡的親表示真誠的感謝。本篇主要會分享一些跟 CSS選擇器(CSS Selectors) 相關的內容,有興趣的請繼續往下看。

CSS選擇器(CSS Selectors)

啥叫選擇器?簡單來說就是通過一些定義來選中特定的HTML標籤。biu~

首先我們來看看選擇器的分類:

基本選擇器

  1. 型別選擇器:簡單來說就是直接選擇HTML標籤(不帶<>的那種),例如:html {width: 100%;};

  2. 類選擇器:就是HTML標籤中class屬性的值(但就是給每個值加上了.),例如:.div {width: 100%;};

  3. ID選擇器:就是HTML標籤中id屬性的值(但就是給每個值加上了#,但是要注意,一個文件中的ID應是唯一的,但能不能寫多個?其實也是可以,只是不建議這麼做,至於為什麼,後面的文章會進行講解);

  4. 通用選擇器:寫個 *,啥HTML標籤都選中了。例如:* {width: 100%;}

  5. 屬性選擇器:就是根據HTML標籤裡的屬性選擇,語法大概如下:

    [attr] [attr=value] [attr~=value] [attr|=value] [attr^=value] [attr$=value] [attr*=value]

魚頭注:上面的~|^$跟正規表示式的語法相似,對正規表示式語法不熟的可以看魚頭的github

組合選擇器

  1. 空格:後代選擇器,例如:.a .b。在例子中選中的就是.a裡面的所有帶有.b的節點;
  2. >:子代選擇器,例如:.a > .b。在例子中選中的就是.a裡面的所有帶有.b的子節點;
  3. ~:後繼選擇器,例如:.a ~ .b。在例子中選中的就是在.a後面的.b
  4. +:直接後繼選擇器,例如:.a + .b。在例子中選中的就是在.a後面下一個.b
  5. |: 名稱空間選擇器,例如:.a | .b。在例子中選中的就是屬於.a.b,跟.a .b一樣,屬於Selectors Leve 3的內容。
  6. ||:列選擇器,例如:.a || .b。在例子中選中的就是由.a表示的列的網格/表中的單元格的.b,屬於Selectors Level 4的內容。

偽類與偽元素

  1. 偽類:偽類是新增到選擇器的關鍵字,指定要選擇的元素的特殊狀態。

    // 語法
    selector:pseudo-class {
      property: value;
    }
    複製程式碼
  2. 偽元素:偽元素是一個附加至選擇器末的關鍵詞,允許你對被選擇元素的特定部分修改樣式。一個選擇器中只能使用一個偽元素。

    // 語法
    selector::pseudo-element {
      property: value;
    }
    複製程式碼

其實掌握了CSS的選擇器之後,是可以根據合理的排列組合來實現一些比較有趣的效果的,當然這些效果可能對實際業務邏輯沒什麼幫助,甚至不一定能用,但是也可以給我們在解決問題的時候提供一個方向。就例如以下DEMO:一個用純CSS實現的表單驗證。

原始碼在:codepen,你也可以把以下程式碼複製貼上,在瀏覽器檢視。

<style>
    :root {
      --error-color: red;
    }
    .form > input {
      margin-bottom: 10px;
    }
    .form > .f-tips {
      color: var(--error-color);
      display: none;
    }
    input[type="text"]:invalid ~ input[type="submit"],
    input[type="password"]:invalid ~ input[type="submit"] {
      display: none;
    }
    input[required]:focus:invalid + span {
      display: inline;
    }
    input[required]:empty + span {
      display: none;
    }
    input[required]:invalid:not(:placeholder-shown) + span {
      display: inline;
    }
</style>

  <form class="form" id="form" method="get" action="/api/form">
    賬號:
    <input data-title="賬號" placeholder="請輸入正確的賬號" pattern="\w{6,10}" name="account" type="text" required />
    <span class="f-tips">請輸入正確的賬號</span>
    <br />
    密碼:
    <input data-title="密碼" placeholder="請輸入正確的密碼" pattern="\w{6,10}" name="password" type="password" required />
    <span class="f-tips">請輸入正確的密碼</span>
    <br />
    <input name="button" type="submit" value="提交" />
  </form>

複製程式碼

選擇器的優先順序

選擇器也有優先順序,根據不同的排列組合,標籤的效果是可以超出書寫書寫之外的。

首先我們來看一張經典又通俗易懂的圖。

【Hello CSS】第五章-CSS的選擇器與函式

根據上圖所示,不同的選擇器有不同的權重。

  • 內聯樣式:1000
  • ID:100
  • Class:10
  • HTML標籤:1

魚頭注:根據張鑫旭老師在有趣:256個class選擇器可以幹掉1個id選擇器分享過:256個級聯class選擇器 可以擊敗 1個id選擇器(目前chrome已無此現象)。

【Hello CSS】第五章-CSS的選擇器與函式

魚頭注:Mmmmmm,上圖就是CSS優先順序的不同情況的對比圖,有興趣的親可以一個一個測試。

霸道的!important

當在一個樣式宣告中使用一個!important 規則時,此宣告將覆蓋任何其他宣告。雖然技術上!important與優先順序無關,但它與它直接相關。

使用!important是個壞習慣,能不用就不用。

上面所說的都是對的,但是,真的沒辦法覆蓋!important嗎?

其實也不是,大概可以參考下面的例子:

    <style>
      div[屬性="標籤"] {
        width: 300px !important;
        height: 200px;
        background: #e6e6e6;
        max-width: 200px;
      }
    </style>
    <div 屬性="標籤"></div>
複製程式碼

大家可以建個DEMO看看上面的效果,你們會發現,div的寬度還是200px,其實像max-widthmix-widthmax-heightmin-height等條件屬性是可以覆蓋!important的。只不過這裡會出現另外一個問題。 什麼問題呢? 就是在HTML的屬性裡寫中文的話,很可能會被隊友打屎。

CSS的函式

CSS作為一門使命是服務於標記語言的宣告式語言,很多程式設計師看不起它 (實際上是看不起又學不會的一門語言) 。看不起的原因之一就是CSS沒有邏輯能力跟函式功能,嗯,十年前是這樣,那麼如今呢?

根據MDN所陳列的關鍵字索引,css函式一共有86個。

根據w3cplus中可以劃分為以下幾類:

  • 屬性函式attr()
  • 背景圖片函式linear-gradient()radial-gradient()conic-gradient()repeating-linear-gradient()repeating-radial-gradient()repeating-conic-gradient()image-set()image()url()element()
  • 顏色函式rgb()rgba()hsl()hsla()hwb()color-mod()
  • 圖形函式circle()ellipse()inset()polygon()path()
  • 濾鏡函式blur()brightness()contrast()drop-shadow()grayscale()hue-rotate()invert()opacity()saturate()sepia()
  • 轉換函式matrix()matrix3d()perspective()rotate()rotate3d()rotateX()rotateY()rotateZ()scale()scale3d()scaleX()scaleY()scaleZ()skew()skewX()skewY()translate()translateX()translateY()translateZ()translate3d()
  • 數學函式calc()min()max()mixmax()repeat()
  • 緩動函式cubic-bezier()steps()
  • 其他函式counter()counters()toggle()var()symbols()

這些函式各有各的功能,按需排列組合可以實現很多很酷炫的效果。在這裡一定要安利大漠老師的CSS中的函式以及張鑫旭老師在CSS CONF中的分享,裡面就講了很多關於CSS 函式的應用。當然各位小夥伴也可以大膽發揮想象,創造出各種好玩奇異的效果。

由於函式很多,一篇文章也沒辦法全部介紹完,接下來魚頭會就幾個比較喜歡的函式進行分享,有興趣的親也可以新增魚頭微信“krisChans95”或者關注魚頭的公眾號“魚頭的Web世界”與魚頭一同探討更多的可能。

element()

element()是屬於CSS Image Value and Replaced Content Module Level 4中的背景函式。element()可以將網站中的部分內容當成圖片渲染。

各位使用vue的親,一定對雙向繫結不陌生,對它的實現一定也是瞭然如胸的,那麼如果今天魚頭告訴你,雙向繫結不一定需要JS呢? 首先我們來看個效果圖。

【Hello CSS】第五章-CSS的選擇器與函式

地址在我codepen上,有興趣的可以隨時去看。

以上便是element()的實際效果,用法也很簡單,就是把要複製的物件選擇器寫進去就好。不過目前只能在較新的火狐瀏覽器裡使用。

conic-gradient()

conic-gradient()是屬於css-images-4的一位新成員。就是可以實現不同角度漸變色的一個函式。

【Hello CSS】第五章-CSS的選擇器與函式

這是彩虹圓盤,實現起來也比較簡單,地址在我codepen上,有興趣的可以隨時去看。

還有什麼?

上面就簡單的介紹了一些關於CSS選擇器CSS函式,根據不同的場景,不同的組合,我們可以實現很多意想不到的效果,當然前提是瀏覽器支援以及我們的想象空間支援了。當然能不能用在業務上這就見仁見智了,但總的來說,CSS已經不再是一門簡單的宣告式語言了,或許在大環境下,CSS玩出花也不能撼動JS一點的地位(也不存在撼動一說,本來就是相輔相成的)。但是也能為我們的產品多增添一點亮點不是嗎?

參考資料

快速瞭解CSS新出的列選擇符雙管道(||)

CSS_Selectors

Selectors from level 4 to 1

關於CSS權重(優先順序)的理解

CSS 優先順序規則

你應該知道的一些事情——CSS權重

CSS Specificity: Things You Should Know

優先順序

CSS中的函式

CSS Values and Units Module Level 4

Selectors Level 3

Selectors Level 4

【Hello CSS】系列

【Hello CSS】是以CSS基礎概念為主題的系列文章,旨在幫助大家更深刻地瞭解並且提高CSS在各位開發者心目中的地位。由於魚頭我水平有限,文筆有限,如果各位在文章中發現有任何不合理,不正確的地方,還煩不吝指出,我會非常感謝的;如果通過文章有任何想法或疑問,也希望各位能積極留言,我們互相探討;如果通過本系列文章有所收穫,這就讓魚頭我喜不自勝了!



如果你也喜歡`CSS`,喜歡探討技術,或者對本文,本系列有任何的意見或建議,魚頭非常希望你能加入一個有趣的微信群 — “進擊的CSS”。你可以掃描下方二維碼,新增魚頭微信,新增時註明 “加群”,如果你覺得我的文章有趣,歡迎關注微信公眾號“魚頭的Web海洋”。衷心希望可以遇見你。

【Hello CSS】第五章-CSS的選擇器與函式

下一篇

第六章-文件流與排版

歷史文章傳送門

  1. 序章-起源

  2. 第一章-CSS的語法與工作流

  3. 第二章-CSS的邏輯屬性與盒子模型

  4. 第三章-瀏覽器的檢視與座標

  5. 第四章-HTML的標籤與語意

  6. 第五章-CSS的選擇器與函式