精讀《使用 CSS 屬性選擇器》

1 引言

雖然如今 Css Module 與 Css-in-js 更流行,但使用它們會致使過度依賴 濫用 class 作惟必定位,違背了 Css 選擇器的初衷。css

本期精讀的文章是:attribute-selectors-splicing-html-dna-css,帶你從新理解強大的 Css 選擇器。html

2 概要

Css Module 與 Css-in-js 大部分場景使用 className 做爲選擇器,那麼本文以選擇器爲重點,看看選擇器有哪些實用的用法。前端

屬性選擇器

若是你想選擇包含 title 屬性的 divgit

div[title]

選擇包含 title 屬性的子元素,只須要加個空格:github

div [title]

選擇 title 內容是 dna 的元素:npm

div[title="dna"]

選擇 title 屬性包含 dna 單詞的元素:安全

注意 dna 須要是單詞,也就是用空格分割,好比 「my beautiful dna」 或 「mutating dna is fun!」
div[title~="dna"]

和正則相似,選擇 title 屬性中,以 dna 結尾的元素:架構

div[title$="dna"]

dna 開頭:dom

div[title^="dna"]

若是但願選擇 dnadna-zh,但不但願匹配 dnaer,能夠:async

這種場景通常用在國際化,好比 en en-us 就能夠用 |="en"
div[title|="dna"]

只要包含 dna 這三個字符就選中:

div[title*="dna"]

真的很像正則,你能夠用 i 標識匹配時大小寫不敏感:

div[title*="dna" i]

若是你想找到一個 a 標籤,擁有 title 屬性而且 className 以 genes 結尾,能夠這樣:

a[title][class$="genes"]

獲取標籤的值

能夠用 attr 標識符拿到當前選擇器選中元素的屬性,好比當 hover 狀態時,在文字尾部顯示其 title 屬性:

.joke:hover:after {
  content: "Answer:" attr(title);
  display: block;
}

其它用法

本文還介紹了一些實用技巧,好比

根據輸入框類型設置樣式

input[type="email"] {
  color: papayawhip;
}
input[type="tel"] {
  color: thistle;
}

改變下載標籤的 icon

a[download][href$="pdf"]:after {
  content: url(pdf-icon.svg);
}

固然也能夠選中一些老代碼進行樣式重寫,好比:

<div bgcolor="#000000" color="#FFFFFF">Old, holey genes</div>
div[bgcolor="#000000"] {
  /*override*/
  background-color: #222222 !important;
}

不過這種用法要謹慎,寫的越多越難以維護。

結合一些新標籤功能

好比 details 標籤是 html 原生的手風琴摺疊組件:

<details> <summary>List of Genes</summary> Roddenberry Hackman </details>

咱們可使用屬性選擇器,定義其打開時的樣式:

details[open] {
  background-color: hotpink;
}

爲沒有 async 標記的 script 標籤着色,算是友情提示哪兒有錯誤:

script[src]:not([async]) {
  display: block;
  width: 100%;
  height: 1em;
  background-color: red;
}
script:after {
  content: attr(src);
}

爲 JS 事件着色,好比觸發的鼠標事件能夠做爲選擇器:

[OnMouseOver] {
  color: burlywood;
}
[OnMouseOver]:after {
  content: "JS: " attr(OnMouseOver);
}

選中隱藏元素:

[hidden],
[type="hidden"] {
  display: block;
}

還有更多就不一一列舉了,感興趣的讀者能夠跳轉到原文繼續閱讀。大部份內容其實都寫在了 w3school 選擇器參考手冊,只是結合一篇文章來讀,能夠理解得更深入,同時文章裏確實有一些新鮮的選擇器,好比 JS 事件選擇器,HTML5 屬性標籤選擇器等等。

3 精讀

這篇文章確實說明了 Css 選擇器的強大性,但回到 css module 或者 css-in-js 的工程代碼裏,咱們每每難以作太多的實踐,有以下幾個緣由:

一直在擔憂的 DOM 結構變更

業務開發中,大量需求涌入,也許過了一週,DOM 結構就已經面目全非了,並且就算是一個普通的聖盃佈局,可能老版本用 Table 佈局,後面進來一個年輕小夥子直接用 div + flex 重構了,你會擔憂以前寫的 table 選擇器在某一天所有失效。

也許今天的 div 選擇器,明天由於語義化改造就換成了 article 標籤。

最大緣由是 一種視覺界面對應的實現方式太多,不只標籤能夠各異,css 屬性還有 table、block、flex、grid 可選,同時 grid 屬性還會致使視覺結構與 DOM 結構不徹底對應。

若是你今天用 css 選擇器作了一套徹底貼合如今 DOM 結構的 css 文件,這個 css 文件也許是後面 dom 結構改動的噩夢。

你敢作全局樣式覆蓋嗎

咱們排除標籤,僅對屬性作全局覆蓋,的確能夠部分繞開 DOM 結構的限制,可是這樣的全局樣式覆蓋,不一樣的人有不一樣見解。

小明的團隊很是懂得 css 運用,他們天天都會花一個小時討論項目的 css 架構,並對通用需求樣式作了抽象,而且每一個人都很承認這個方案,在他們的團隊,一個很是酷炫的按鈕與動畫效果,經過 <button animate /> 就能夠完成,頁面間交互很是流暢,用戶體驗統一,前端代碼也很是簡潔和優雅。

小白的團隊水平良莠不齊,有人永遠只使用 table 佈局,有人卻總想將一些試驗階段 css 屬性用在生產環境,小白本身抽象了一個全局樣式 css 文件,可團隊沒什麼時間溝通,甚至有人私下也注入了很多全局 css 樣式,總有人抱怨本身的樣式被全局覆蓋了,最後小白甚至不得不在本身頁面入口處寫上 *: unset 清空各類奇怪的全局樣式干擾,他想清空那該死的全局 css 樣式文件,但他知道這樣作帶來的是更大的災難。

能夠看到,並非每一個團隊都適合作全局樣式覆蓋。

JS 模塊化思惟的影響

爲何一個項目安裝了幾百個 npm 三方包,卻依然能夠正常運行?由於好的三方包都是遵照模塊化的,同時也不產生反作用,這樣被使用時的效果就能夠被預期,試想一下幾百個 npm 包裏同時定義了不一樣規範的全局 css 覆蓋,你的項目會成爲何樣。

固然 js 與 css 是不適合放在一塊兒比較的,css 大可能是業務級別的,也就是能寫 css 只有作業務的你,第三方包通常是不會提供 css 定義干擾你的項目的。

然而大部分 UI 組件庫是自帶樣式的,他們有本身的設計哲學,但爲何如今你會反感,而當初使用 Bootstrap 不會?

使用 Bootstrap 的時代,Bootstrap 通常是做爲項目第一個依賴安裝的,咱們明確知道它會注入全局樣式。咱們會泡在他的官方文檔目錄,一條條理解他作的全局樣式規則,他提供的各類 class。

然而如今是一個 Css-in-js 的時代,或者至少是 css-in-npm 的時代,什麼都用 npm 裝,什麼都是模塊化的,不少時候咱們用一個 UI 組件僅僅是爲了在某一處地方使用,而不想接受他帶來的全局樣式污染,視覺設計哲學,更不想看他的 css 文檔。因此好的組件庫每每 css 使用的很收斂,儘可能不要對用戶項目環境形成影響。

若是你項目的樣式已經被不得不安裝的第三方包全局覆蓋得面目全非,每一次對全局樣式修改都如履薄冰,可能你會比較反感 css 選擇器,你會推崇更安全的 css modules,或甚至是 css-in-js,讓每一個組件的 className 都惟一,作到標籤粒度的隔離。

4 總結

筆者認爲,在一個肯定的環境中,好比一個組件,一個獨立負責的模塊,是比較適合用 css 選擇器的,這樣可讓樣式代碼更易讀,DOM 結構更清爽。但請必定注意做用域,若是不是你們一塊兒達成的共識,最好不要放到全局樣式中。

就算項目的風格很是明確,a 標籤必定要用紅色,在把這條規則放到全局樣式以前,請思考一下,這樣會不會破壞了某個用 a 標籤模擬按鈕的組件庫的樣式?

css 屬性選擇器的強大功能,須要有良好的項目管理作支撐,或者經過技術手段好比 shadow dom 作支撐。不過 shadow dom 的支持程度 如今仍然很低,因此使用編譯工具作的隔離,在某種程度上模擬了 Css 選擇器,承擔了 Css 選擇器 + shadow dom 的功能。

一切樣式都用 className 控制,也許是 shadow dom 出來前的一種妥協方案,這篇文章更可能是在描述 Css 選擇器設計之美,但須要咱們理性去使用。

討論地址是: 精讀《使用 CSS 屬性選擇器》 · Issue #113 · dt-fe/weekly

若是你想參與討論,請點擊這裏,每週都有新的主題,週末或週一發佈。前端精讀 - 幫你篩選靠譜的內容。

相關文章
相關標籤/搜索