- 原文地址:Using Feature Queries in CSS
- 原文做者:Jen Simmons
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:Cherry
- 校對者:LeviDing、H2O-2
CSS 中有一個你可能尚未據說過的工具。它很強大。它已經存在一段時間了。而且它極可能會成爲你最喜歡的 CSS 新功能之一。css
這就是 @supports
規則,也被稱爲 Feature Queries。前端
經過使用 @supports
,你能夠在 CSS 中編寫一個小測試,以查看是否支持某個「特性」(CSS 屬性或值),並根據其返回的結果決定是否調用代碼塊。例如:react
@supports (display: grid) {
// 只有在瀏覽器支持 CSS 網格時纔會運行代碼
}複製代碼
若是瀏覽器支持 display: grid
,那麼括號內的全部樣式都將被應用。不然將跳過全部樣式。android
如今,對於特徵查詢的用途,彷佛還不是很清晰。這不是一種分析瀏覽器是否正確地實現了 CSS 屬性的外部驗證,若是你正在尋找這樣的外部驗證,參考這裏。特徵查詢要求瀏覽器對是否支持某個 CSS 屬性/值進行自我報告,並根據其返回的結果決定是否調用代碼塊。若是瀏覽器不正確或不完整地實現了一個特性,@supports
不會對你有幫助。若是瀏覽器誤報了 CSS 支持的狀況,@supports
不會對你有幫助。這不是一個能使瀏覽器漏洞消失的魔法。ios
即使如此,我仍然以爲 @supports
很是有用。若是沒有 @supports
規則的幫助,我對多個 CSS 新規則的使用就會被推遲不少。css3
多年來,開發者都用 Modernizr 作特徵查詢,可是 Modernizr 須要 JavaScript。即便腳本很小,Modernizr 的構建的CSS 須要 JavaScript 文件的下載、執行而且要在應用 CSS 以前完成。涉及 JavaScript 老是比只使用 CSS 慢。若是 JavaScript 打開失敗也就是說若是 JavaScript 不執行會發生什麼?另外,Modernizr 須要一個複雜而且許多項目沒法處理的附加層。特徵查詢速度更快、更健壯、使用起來更加簡單。git
你可能會注意到,特徵查詢的語法與媒體查詢很是類似。我把他們看作堂兄弟。github
@supports (display: grid) {
main {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
}複製代碼
如今大多數狀況下,CSS 中不須要這樣的測試。例如,你在寫下面代碼的時候不用測試其支持狀況:web
aside {
border: 1px solid black;
border-radius: 1em;
}複製代碼
若是瀏覽器支持 border-radius
,那麼它將在 aside
上設置圓角。若是沒有,它將跳過代碼行並繼續前進,使框的邊緣爲正方形。這裏沒有理由運行測試或使用特徵查詢。CSS 就是這樣工做的。這是 architecting solid, progressively-enhanced CSS 中的一個基本原則。瀏覽器只跳過不支持的代碼,不拋出錯誤。後端
border-radius: 1em
如圖片的右邊所示。然而,Internet Explorer 六、7 和 8 不會設置圓角,顯示效果如圖片的左邊所示。看看這個例子
codepen.io/jensimmons/…
那麼,你想何時使用 @supports
?特徵查詢是一種將 CSS 聲明捆綁在一塊兒的工具,以便在必定條件下做爲一個組運行。當你想在新的 CSS 功能被支持的時候,將新的和舊的 CSS 混合使用,那麼請使用特徵查詢。
讓咱們看一下使用 Initial Letter 屬性的示例。這個新屬性 initial-letter
告訴瀏覽器,使元素變得更大 —— 像段首大字。在這裏,一個段落中第一個詞的第一個字母被設置爲四行文字的大小。很是好。但我仍是想把那字母加粗,在右邊留一點空白,讓它變成一個漂亮的橙色。酷。
p::first-letter {
-webkit-initial-letter: 4;
initial-letter: 4;
color: #FE742F;
font-weight: bold;
margin-right: 0.5em;
}複製代碼
initial-letter
的例子在 Safari 9 下的顯示。如今讓咱們看看其餘瀏覽器會發生什麼…
initial-letter
屬性被設置的更大了一些。咱們須要一種方法來測試瀏覽器是否支持
initial-letter
,而且只在顏色、粗細和空白處應用更改。進入特徵查詢。
@supports (initial-letter: 4) or (-webkit-initial-letter: 4) {
p::first-letter {
-webkit-initial-letter: 4;
initial-letter: 4;
color: #FE742F;
font-weight: bold;
margin-right: 0.5em;
}
}複製代碼
注意,您須要測試具備屬性和值的完整字符串。最初這是令我困惑的。爲何我要測試 initial-letter: 4
?值爲 4 重要嗎?若是我傳入的值是 17 呢?它是否須要與後續代碼中的值相匹配?
@supports
規則測試一個包含屬性和值的字符串,由於有時候須要測試的是屬性,有時須要測試的是值。對於 initial-letter
的例子,你傳入的是什麼值並不重要。可是考慮 @supports (display: grid)
,你會看到二者都是須要的。每一個瀏覽器都支持 display
。只有測試版瀏覽器支持 display: grid
(目前來講)。
回到咱們的示例:目前 initial-letter
僅在 Safari 9 中獲得支持,而且它須要前綴。因此我寫了這個前綴,爲了確保包含無前綴的版本我寫了這個測試。是的,能夠在特徵查詢中使用 or
、and
和 not
語句。
這是新的結果。瀏覽器支持 initial-letter
的話就會將其展示爲字體更大、加粗而且是橘色的段首字母。其它瀏覽器表現的像段首字母不存在同樣,但若是這些瀏覽器支持了這個規則,那麼視覺效果將會是同樣的。(順便說一下,目前 Firefox 正在嘗試實現段首字母特性。)
如今,您可能會嘗試使用此工具將代碼分紅兩個分支。「嘿,瀏覽器,若是你支持視口單位,執行這段代碼,若是你不支持他們,執行另外一段代碼。」這感受很好而且很整潔。
@supports (height: 100vh) {
// 使用 viewport height 的佈局
}
@supports not (height: 100vh) {
// 老式瀏覽器另外一種佈局
}
// 咱們但願是這樣,但這個代碼不是很好複製代碼
這不是一個好主意 —— 至少如今來講。你發現是什麼問題了嗎?
然而,不是全部瀏覽器都支持特徵查詢。而且瀏覽器不支持 @supports
將會跳過這部分的所有代碼。這不是很好。
這是否是意味着,除非 100% 的瀏覽器都支持,不然咱們就不能使用特徵查詢了?不是的,咱們能夠,而且當今咱們應該使用特徵查詢。不要像最後一個例子那樣編寫代碼。
那怎麼作纔是正確的呢?這和咱們在 100% 支持媒體查詢前有相同的方法。事實上,在這個過渡時期使用特徵查詢比使用媒體查詢更容易。你只要聰明點就好了。
你但願構建你的代碼,由於最古老的瀏覽器不支持特徵查詢或您正在測試的特性。我來教你怎麼作。
(固然,在未來的某個時候,一旦 100% 的瀏覽器有特徵查詢,咱們就能夠更大程度地使用 @supports not
,並以這種方式組織咱們的代碼。但咱們還要等不少年。
那麼特徵查詢的支持狀況如何呢?
自從 2013 年年中以來,在 Firefox、Chrome、和 Opera 就已經支持 @supports
了。它也適用於 Edge 的每個版本。Safari 在 2015 年秋季將其在Safari 9 中支持。在任何版本的 Internet Explorer、Opera Mini、Blackberry Browser 或 UC 瀏覽器中都不支持特徵查詢。
您可能會認爲 Internet Explore 不支持特徵查詢。實際是並非。我立刻告訴你緣由。我認爲最大的障礙是 Safari 8。咱們須要密切關注這兒發生的事情。
讓咱們來看另外一個例子。假設咱們有一些想要應用的佈局代碼,爲了使操做更加合理須要使用 object-fit: cover
。對於不支持 object-fit
的瀏覽器,咱們但願應用不一樣的佈局 CSS。
咱們開始來編寫代碼:
div {
width: 300px;
background: yellow;
// 老佈局的一些複雜代碼
}
@supports (object-fit: cover) {
img {
object-fit: cover;
}
div {
width: auto;
background: green;
// 新佈局的一些其餘複雜的代碼
}
}複製代碼
那麼會發生什麼呢?特徵查詢要麼支持要麼不支持,新的特性 object-fit: cover
要麼支持要麼不支持。結合這些,咱們有 4 種可能性:
支持特徵查詢嗎? | 支持特性嗎? | 會發生什麼? | 這是咱們想要的嗎? |
---|---|---|---|
支持特徵查詢 | 支持問題中的特性 | ||
支持特徵查詢 | 不支持問題中的特性 | ||
不支持特徵查詢 | 不支持問題中的特性 | ||
不支持特徵查詢 | 支持問題中的特性 |
Firefox、Chrome、Opera 和 Safari 9 都支持 object-fit
和 @supports
,因此這個測試將運行得很好,而且這個塊內的代碼將被應用。咱們的圖像將經過 object-fit: cover
被裁剪,而且咱們 div
的背景將是綠色的。
Edge 不支持 object-fit
,但它支持 @supports
,所以該測試將運行並失敗,防止代碼塊被應用。該圖像將不會有 object-fit
應用,而且 div
有黃色的背景。
這是咱們想要的。
這就是咱們的經典剋星 Internet Explorer 出現的地方。IE 不支持 @supports
,而且也不支持 object-fit
。你可能認爲這意味着咱們不能使用特徵查詢 —— 並非。
想一下咱們想要的結果。咱們想要 IE 跳過整個代碼塊。而且確實是這樣的結果。爲何呢?由於當它執行到 @supports
時,它沒法識別這個語法,而且會跳轉到結尾。
它可能跳過代碼「出於錯誤的緣由」 —— 它跳過代碼是由於它不支持 @supports
,而不是由於它不支持 object-fit
,可是誰在意呢?!咱們仍然獲得咱們想要的結果。
一樣的事情也發生在 Android 的黑莓瀏覽器和 UC 瀏覽器上。他們不支持 object-fit
和 @supports
,因此咱們都準備好了。很成功。
底線是 —— 當你在瀏覽器中使用一個不支的特徵查詢的特徵查詢時,只要讓瀏覽器不支持你正在測試的功能就行了。
仔細思考代碼的邏輯。問問本身,當瀏覽器跳過這個代碼時會發生什麼?若是那是你想要的,你都準備好了。
問題是這第 4 個組合 —— 雖然特徵查詢所包含的測試沒有運行,可是瀏覽器確實支持該特性時,而且應該運行該代碼。
例如,object-fit
由 Safari 7.1(Mac)和 8(Mac和iOS)支持,但這兩個瀏覽器都不支持功能查詢。這一樣適用於 Opera Mini —— 它將支持 object-fit
,但不支持 @supports
。
會發生什麼呢?這些瀏覽器進入這個代碼塊,但並未使用代碼,在圖片上應用 object-fit:cover
,並將這個 div
的背景設置爲綠色,它跳過了整個代碼塊,留下黃色做爲背景顏色。
而且這不是咱們真正想要的。
支持特徵查詢嗎? | 支持特性嗎? | 會發生什麼? | 這是咱們想要的嗎? |
---|---|---|---|
支持特徵查詢 | 支持問題中的特性 | CSS 被應用 | 是的 |
支持特徵查詢 | 不支持問題中的特性 | CSS 沒有被應用 | 是的 |
不支持特徵查詢 | 不支持問題中的特性 | CSS 沒有被應用 | 是的 |
不支持特徵查詢 | 支持問題中的特性 | CSS 沒有被應用 | 不,可能不是 |
固然,這取決於特定的用例。也許這是咱們能夠忍受的一個結果。較老的瀏覽器得到了較老瀏覽器的體驗。網頁仍在工做。
但在大多數狀況下,咱們但願瀏覽器可以使用它支持的任何特性。這就是爲何在涉及特性查詢時,Safari 8 多是最大的問題,而不是 Internet Explorer。Safari 8 支持許多新的特性 —— 好比 Flexbox。您可能不想阻止 Safari 8 上的這些屬性。這就是爲何我不多在 @supports
中使用 Flexbox,或者有時候,我在代碼中至少寫三個分支,一個使用 not
。(這很快就變得複雜了,因此不在這裏解釋了)。
若是您使用的功能在舊版瀏覽器中比功能查詢支持的更好的話,那麼在編寫代碼時要仔細考慮全部的組合。確保不要把你但願這些瀏覽器實現的功能也排除在外了。
同時,能夠很容易的在 @supports
中用最新的 CSS 特性 —— 例如 CSS Grid、首字母。沒有哪一個瀏覽器會在不支持特徵查詢時就支持 CSS Grid 的。咱們沒必要擔憂那個包含新特性時問題多多的第四種組合,在之後這使得功能查詢很是有用的。
全部這一切都意味着IE11 雖然仍會存在不少年,咱們仍是能夠同時使用特徵查詢和 CSS 的最新特性。
如今咱們明白了爲何咱們不能像這樣編寫代碼:
@supports not (display: grid) {
// 較老瀏覽器的代碼 // 不要模仿這個例子
}
@supports (display: grid) {
// 較新瀏覽器的代碼 // 我說這真的很糟糕嗎?
}複製代碼
若是咱們這樣作,咱們將阻止舊的瀏覽器獲取他們須要的代碼。
取而代之的是,像這樣組織你的代碼:
// 較老瀏覽器的回退代碼
@supports (display: grid) {
// 較新瀏覽器的代碼
// 在須要時覆蓋上面的代碼
}複製代碼
這正是咱們在使用媒體查詢的同時支持舊版本 IE 的策略。這個策略就是「移動優先」這個詞的來源。
我預計 CSS Grid 將在 2017 在瀏覽器中被使用,我打賭在實現將來的佈局時咱們將使用大量的特徵查詢。與 JavaScript 相比,它的麻煩要小得多,並且速度要快得多。而且 @supports
能使支持 CSS Grid 的瀏覽器作有趣的和複雜的東西,同時對不支持的瀏覽器提供佈局選項。
自 2013 年年中以來,功能查詢一直存在。隨着 Safari 10 即將發佈,我相信咱們已經到了將 @supports
添加到工具箱的時候了。
Jen Simmons 是在 Mozilla 的一個設計師,而且是 The Web Ahead 的主持人。她正在研究網絡上平面設計的將來,並在全球會議上四處教授 CSS 佈局。
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、React、前端、後端、產品、設計 等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃。