摘要:引言雖然現(xiàn)在與更流行,但使用它們會導致過分依賴濫用做唯一定位,違背了選擇器的初衷。本期精讀的文章是,帶你重新理解強大的選擇器。討論地址是精讀使用屬性選擇器如果你想?yún)⑴c討論,請點擊這里,每周都有新的主題,周末或周一發(fā)布。
1 引言
雖然現(xiàn)在 Css Module 與 Css-in-js 更流行,但使用它們會導致過分依賴 濫用 class 做唯一定位,違背了 Css 選擇器的初衷。
本期精讀的文章是:attribute-selectors-splicing-html-dna-css,帶你重新理解強大的 Css 選擇器。
2 概要Css Module 與 Css-in-js 大部分場景使用 className 作為選擇器,那么本文以選擇器為重點,看看選擇器有哪些實用的用法。
屬性選擇器如果你想選擇包含 title 屬性的 div:
div[title]
選擇包含 title 屬性的子元素,只需要加個空格:
div [title]
選擇 title 內容是 dna 的元素:
div[title="dna"]
選擇 title 屬性包含 dna 單詞的元素:
注意 dna 需要是單詞,也就是用空格分割,比如 “my beautiful dna” 或 “mutating dna is fun!”
div[title~="dna"]
和正則類似,選擇 title 屬性中,以 dna 結尾的元素:
div[title$="dna"]
以 dna 開頭:
div[title^="dna"]
如果希望選擇 dna 或 dna-zh,但不希望匹配 dnaer,可以:
這種場景一般用在國際化,比如 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 狀態(tài)時,在文字尾部顯示其 title 屬性:
.joke:hover:after { content: "Answer:" attr(title); display: block; }其它用法
本文還介紹了一些實用技巧,比如
根據(jù)輸入框類型設置樣式
input[type="email"] { color: papayawhip; } input[type="tel"] { color: thistle; }
改變下載標簽的 icon
a[download][href$="pdf"]:after { content: url(pdf-icon.svg); }
當然也可以選中一些老代碼進行樣式重寫,比如:
Old, holey genes
div[bgcolor="#000000"] { /*override*/ background-color: #222222 !important; }
不過這種用法要謹慎,寫的越多越難以維護。
結合一些新標簽功能
比如 details 標簽是 html 原生的手風琴折疊組件:
List of Genes
Roddenberry Hackman
我們可以使用屬性選擇器,定義其打開時的樣式:
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 事件著色,比如觸發(fā)的鼠標事件可以作為選擇器:
[OnMouseOver] { color: burlywood; } [OnMouseOver]:after { content: "JS: " attr(OnMouseOver); }
選中隱藏元素:
[hidden], [type="hidden"] { display: block; }
還有更多就不一一列舉了,感興趣的讀者可以跳轉到原文繼續(xù)閱讀。大部分內容其實都寫在了 w3school 選擇器參考手冊,只是結合一篇文章來讀,可以理解得更深刻,同時文章里確實有一些新鮮的選擇器,比如 JS 事件選擇器,HTML5 屬性標簽選擇器等等。
3 精讀這篇文章確實說明了 Css 選擇器的強大性,但回到 css module 或者 css-in-js 的工程代碼里,我們往往難以做太多的實踐,有如下幾個原因:
一直在擔心的 DOM 結構變動業(yè)務開發(fā)中,大量需求涌入,也許過了一周,DOM 結構就已經(jīng)面目全非了,而且就算是一個普通的圣杯布局,可能老版本用 Table 布局,后面進來一個年輕小伙子直接用 div + flex 重構了,你會擔心之前寫的 table 選擇器在某一天全部失效。
也許今天的 div 選擇器,明天因為語義化改造就換成了 article 標簽。
最大原因是 一種視覺界面對應的實現(xiàn)方式太多,不僅標簽可以各異,css 屬性還有 table、block、flex、grid 可選,同時 grid 屬性還會導致視覺結構與 DOM 結構不完全對應。
如果你今天用 css 選擇器做了一套完全貼合現(xiàn)在 DOM 結構的 css 文件,這個 css 文件也許是后面 dom 結構改動的噩夢。
你敢做全局樣式覆蓋嗎我們排除標簽,僅對屬性做全局覆蓋,的確可以部分繞開 DOM 結構的限制,但是這樣的全局樣式覆蓋,不同的人有不同看法。
小明的團隊非常懂得 css 運用,他們每天都會花一個小時討論項目的 css 架構,并對通用需求樣式做了抽象,并且每個人都很認可這個方案,在他們的團隊,一個非常酷炫的按鈕與動畫效果,通過 就可以完成,頁面間交互非常流暢,用戶體驗統(tǒng)一,前端代碼也非常簡潔和優(yōu)雅。
小白的團隊水平參差不齊,有人永遠只使用 table 布局,有人卻總想將一些試驗階段 css 屬性用在生產(chǎn)環(huán)境,小白自己抽象了一個全局樣式 css 文件,可團隊沒什么時間溝通,甚至有人私下也注入了不少全局 css 樣式,總有人抱怨自己的樣式被全局覆蓋了,最后小白甚至不得不在自己頁面入口處寫上 *: unset 清空各種奇怪的全局樣式干擾,他想清空那該死的全局 css 樣式文件,但他知道這樣做帶來的是更大的災難。
可以看到,并不是每個團隊都適合做全局樣式覆蓋。
JS 模塊化思維的影響為什么一個項目安裝了幾百個 npm 三方包,卻依然可以正常運行?因為好的三方包都是遵守模塊化的,同時也不產(chǎn)生副作用,這樣被使用時的效果就可以被預期,試想一下幾百個 npm 包里同時定義了不同規(guī)范的全局 css 覆蓋,你的項目會成為什么樣。
當然 js 與 css 是不適合放在一起比較的,css 大多是業(yè)務級別的,也就是能寫 css 只有做業(yè)務的你,第三方包一般是不會提供 css 定義干擾你的項目的。
然而大部分 UI 組件庫是自帶樣式的,他們有自己的設計哲學,但為什么現(xiàn)在你會反感,而當初使用 Bootstrap 不會?
使用 Bootstrap 的時代,Bootstrap 一般是作為項目第一個依賴安裝的,我們明確知道它會注入全局樣式。我們會泡在他的官方文檔目錄,一條條理解他做的全局樣式規(guī)則,他提供的各種 class。
然而現(xiàn)在是一個 Css-in-js 的時代,或者至少是 css-in-npm 的時代,什么都用 npm 裝,什么都是模塊化的,很多時候我們用一個 UI 組件僅僅是為了在某一處地方使用,而不想接受他帶來的全局樣式污染,視覺設計哲學,更不想看他的 css 文檔。所以好的組件庫往往 css 使用的很收斂,盡量不要對用戶項目環(huán)境造成影響。
如果你項目的樣式已經(jīng)被不得不安裝的第三方包全局覆蓋得面目全非,每一次對全局樣式修改都如履薄冰,可能你會比較反感 css 選擇器,你會推崇更安全的 css modules,或甚至是 css-in-js,讓每個組件的 className 都唯一,做到標簽粒度的隔離。
4 總結筆者認為,在一個確定的環(huán)境中,比如一個組件,一個獨立負責的模塊,是比較適合用 css 選擇器的,這樣可以讓樣式代碼更易讀,DOM 結構更清爽。但請一定注意作用域,如果不是大家一起達成的共識,最好不要放到全局樣式中。
就算項目的風格非常明確,a 標簽一定要用紅色,在把這條規(guī)則放到全局樣式之前,請思考一下,這樣會不會破壞了某個用 a 標簽模擬按鈕的組件庫的樣式?
css 屬性選擇器的強大功能,需要有良好的項目管理做支撐,或者通過技術手段比如 shadow dom 做支撐。不過 shadow dom 的支持程度 現(xiàn)在仍然很低,所以使用編譯工具做的隔離,在某種程度上模擬了 Css 選擇器,承擔了 Css 選擇器 + shadow dom 的功能。
一切樣式都用 className 控制,也許是 shadow dom 出來前的一種妥協(xié)方案,這篇文章更多是在描述 Css 選擇器設計之美,但需要我們理性去使用。
討論地址是:精讀《使用 CSS 屬性選擇器》 · Issue #113 · dt-fe/weekly
如果你想?yún)⑴c討論,請點擊這里,每周都有新的主題,周末或周一發(fā)布。前端精讀 - 幫你篩選靠譜的內容。
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://m.hztianpu.com/yun/99387.html
摘要:前言有過面試經(jīng)驗的同學應該都被問過瀏覽器兼容性的問題,對于面試官的問題,常常猝不及防,因為通常他們都是這么問的。來談談瀏覽器兼容的問題吧,你對瀏覽器的兼容性有了解過嗎,那么如何才是我們正確回答這個問題的姿勢呢。 前言 有過面試經(jīng)驗的同學應該都被問過瀏覽器兼容性的問題,對于面試官的問題,常常猝不及防,因為通常他們都是這么問的。來談談瀏覽器兼容的問題吧,你對瀏覽器的兼容性有了解過嗎,那么如...
摘要:前言有過面試經(jīng)驗的同學應該都被問過瀏覽器兼容性的問題,對于面試官的問題,常常猝不及防,因為通常他們都是這么問的。來談談瀏覽器兼容的問題吧,你對瀏覽器的兼容性有了解過嗎,那么如何才是我們正確回答這個問題的姿勢呢。 前言 有過面試經(jīng)驗的同學應該都被問過瀏覽器兼容性的問題,對于面試官的問題,常常猝不及防,因為通常他們都是這么問的。來談談瀏覽器兼容的問題吧,你對瀏覽器的兼容性有了解過嗎,那么如...
摘要:概述的解釋器優(yōu)化器代碼可能在字節(jié)碼或者優(yōu)化后的機器碼狀態(tài)下執(zhí)行,而生成字節(jié)碼速度很快,而生成機器碼就要慢一些了。比如有一個函數(shù),從獲取值引擎生成的字節(jié)碼結構是這樣的指令是獲取參數(shù)指向的對象,并存儲在,第二步則返回。 1 引言 本期精讀的文章是:JS 引擎基礎之 Shapes and Inline Caches 一起了解下 JS 引擎是如何運作的吧! JS 的運作機制可以分為 AST 分...
摘要:經(jīng)過連續(xù)幾期的介紹,手寫編譯器系列進入了智能提示模塊,前幾期從詞法到文法語法,再到構造語法樹,錯誤提示等等,都是為智能提示做準備。 1 引言 詞法、語法、語義分析概念都屬于編譯原理的前端領域,而這次的目的是做 具備完善語法提示的 SQL 編輯器,只需用到編譯原理的前端部分。 經(jīng)過連續(xù)幾期的介紹,《手寫 SQL 編譯器》系列進入了 智能提示 模塊,前幾期從 詞法到文法、語法,再到構造語法...
閱讀 706·2021-10-13 09:39
閱讀 1529·2021-09-09 11:53
閱讀 2729·2019-08-29 13:55
閱讀 775·2019-08-28 18:08
閱讀 2666·2019-08-26 13:54
閱讀 2477·2019-08-26 11:44
閱讀 1895·2019-08-26 11:41
閱讀 3931·2019-08-26 10:15