自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

深入探討 CSS 特性檢測

開發(fā) 前端
CSS 特性檢測就是針對不同瀏覽器終端,判斷當(dāng)前瀏覽器對某個(gè)特性是否支持。運(yùn)用 CSS 特性檢測,我們可以在支持當(dāng)前特性的瀏覽器環(huán)境下使用新的技術(shù),而不支持的則做出某些回退機(jī)制。

[[399662]]

什么是 CSS 特性檢測?我們知道,前端技術(shù)日新月異的今天,各種新技術(shù)新屬性層出不窮。在 CSS 層面亦不例外。

一些新屬性能極大提升用戶體驗(yàn)以及減少工程師的工作量,并且在當(dāng)下的前端氛圍下:

  • 很多實(shí)驗(yàn)性功能未成為標(biāo)準(zhǔn)卻被大量使用;
  • 需要兼容多終端,多瀏覽器,而各瀏覽器對某一新功能的實(shí)現(xiàn)表現(xiàn)的天差地別;

所以有了優(yōu)雅降級(jí)和漸進(jìn)增強(qiáng)的說法,在這種背景下,又想使用新的技術(shù)給用戶提供更好的體驗(yàn),又想做好回退機(jī)制保證低版本終端用戶的基本體驗(yàn),CSS 特性檢測就應(yīng)運(yùn)而生了。

CSS 特性檢測就是針對不同瀏覽器終端,判斷當(dāng)前瀏覽器對某個(gè)特性是否支持。運(yùn)用 CSS 特性檢測,我們可以在支持當(dāng)前特性的瀏覽器環(huán)境下使用新的技術(shù),而不支持的則做出某些回退機(jī)制。

本文將主要介紹兩種 CSS 特性檢測的方式:

  1. @supports
  2. modernizr

CSS @supports

傳統(tǒng)的 CSS 特性檢測都是通過 javascript 實(shí)現(xiàn)的,但是未來,原生 CSS 即可實(shí)現(xiàn)。

CSS @supports 通過 CSS 語法來實(shí)現(xiàn)特性檢測,并在內(nèi)部 CSS 區(qū)塊中寫入如果特性檢測通過希望實(shí)現(xiàn)的 CSS 語句。

語法:

  1. @supports <supports_condition> { 
  2.     /* specific rules */ 

舉個(gè)例子:

  1. div { 
  2.  position: fixed; 
  3.  
  4. @supports (position:sticky) { 
  5.     div { 
  6.         position:sticky; 
  7.     } 

上面的例子中,position: sticky 是 position 的一個(gè)新屬性,用于實(shí)現(xiàn)黏性布局,可以輕松實(shí)現(xiàn)一些以往需要 javascript 才能實(shí)現(xiàn)的布局(戳我了解詳情[1]),但是目前只有在 -webkit- 內(nèi)核下才得到支持。

上面的寫法,首先定義了 div 的 position: fixed ,緊接著下面一句 @supports (position:sticky) 則是特性檢測括號(hào)內(nèi)的內(nèi)容,如果當(dāng)前瀏覽器支持 @supports 語法,并且支持 position:sticky 語法,那么 div 的 則會(huì)被設(shè)置為 position:sticky 。

我們可以看到,@supports 語法的核心就在于這一句:@supports (...) { } ,括號(hào)內(nèi)是一個(gè) CSS 表達(dá)式,如果瀏覽器判斷括號(hào)內(nèi)的表達(dá)式合法,那么接下來就會(huì)去渲染括號(hào)內(nèi)的 CSS 表達(dá)式。除了這種最常規(guī)的用法,還可以配合其他幾個(gè)關(guān)鍵字:

@supports not && @supports and && @supports or

@supports not -- 非

not 操作符可以放在任何表達(dá)式的前面來產(chǎn)生一個(gè)新的表達(dá)式,新的表達(dá)式為原表達(dá)式的值的否定。看個(gè)例子:

  1. @supports not (background: linear-gradient(90deg, red, yellow)) { 
  2.     div { 
  3.         background: red; 
  4.     } 

因?yàn)樘砑恿?not 關(guān)鍵字,所以與上面第一個(gè)例子相反,這里如果檢測到瀏覽器不支持線性漸變 background: linear-gradient(90deg, red, yellow) 的語法,則將 div 的顏色設(shè)置為紅色 background: red 。

@supports and -- 與

這個(gè)也好理解,多重判斷,類似 javascript 的 && 運(yùn)算符符。用 and 操作符連接兩個(gè)原始的表達(dá)式。只有兩個(gè)原始表達(dá)式的值都為真,生成的表達(dá)式才為真,反之為假。

當(dāng)然,and 可以連接任意多個(gè)表達(dá)式看個(gè)例子:

  1. p { 
  2.     overflow: hidden; 
  3.     text-overflow: ellipsis; 
  4. @supports (display:-webkit-box) and (-webkit-line-clamp:2) and (-webkit-box-orient:vertical) { 
  5.     p { 
  6.         display: -webkit-box; 
  7.         -webkit-line-clamp: 2; 
  8.         -webkit-box-orient: vertical; 
  9.     } 

上面同時(shí),檢測 @supports (display:-webkit-box) and (-webkit-line-clamp:2) and (-webkit-box-orient:vertical) 了三個(gè)語法,如果同時(shí)支持,則設(shè)定三個(gè) CSS 規(guī)則。這三個(gè)語法必須同時(shí)得到瀏覽器的支持,如果表達(dá)式為真,則可以用于實(shí)現(xiàn)多行省略效果:

Code Demo - @supportAnd[2]

@supports or -- 或

理解了 @supports and,就很好理解 @supports or 了,與 javascript 的 || 運(yùn)算符類似,表達(dá)式中只要有一個(gè)為真,則生成表達(dá)式表達(dá)式為真。

看例子:

  1. @supports (background:-webkit-linear-gradient(0deg, yellow, red)) or (background:linear-gradient(90deg, yellow, red)){ 
  2.     div { 
  3.         background:-webkit-linear-gradient(0deg, yellow, red); 
  4.         background:linear-gradient(90deg, yellow, red) 
  5.     } 

上面的例子中,只有檢測到瀏覽器支持 background:-webkit-linear-gradient(0deg, yellow, red) 或者(or) background:linear-gradient(90deg, yellow, red) 其中一個(gè),則給 div 元素添加漸變。

CodePen Demo -- @supports or[3]

當(dāng)然,關(guān)鍵字 not 還可以和 and 或者 or 混合使用。感興趣的可以嘗試一下。

Can i use?

兼容性來看,先看看 Can i use(更新至 2021/05/13)[4] 吧:

Can i use -- CSS @support

大部分瀏覽器都已經(jīng)支持了,主要需要使用 polyfill 來兼容的是安卓 4.4 以下版本。

我們已經(jīng)可以開始使用起來了,使用 @supports 實(shí)現(xiàn)漸進(jìn)增強(qiáng)的效果。

漸進(jìn)增強(qiáng)(progressive enhancement):針對低版本瀏覽器進(jìn)行構(gòu)建頁面,保證最基本的功能,然后再針對高級(jí)瀏覽器進(jìn)行效果、交互等改進(jìn)和追加功能達(dá)到更好的用戶體驗(yàn):

CSS.supports()

談到了 @supports,就有必要再說說 CSS.supports() 。

它是作為 @supports 的另一種形式出現(xiàn)的,我們可以使用 javascript 的方式來獲得 CSS 屬性的支持情況。

可以打開控制臺(tái),輸入 CSS.supports 試試:

如果沒有自己實(shí)現(xiàn) CSS.supports 這個(gè)方法,輸出上述信息,表示瀏覽器是支持 @supports 語法的,使用如下:

  1. CSS.supports('display''flex')  // true 
  2. CSS.supports('position''sticky')  // true 

 

那它有什么用呢?如果你的頁面需要?jiǎng)討B(tài)添加一些你不確定哪些瀏覽器支持的新的屬性,那它也許會(huì)派上用場。以及,它可以配合我們下文即將要講的 modernizr 。

modernizr

上面介紹了 CSS 方式的特性檢測,在以前,通常是使用 javascript 來進(jìn)行特性檢測的,其中 modernizr 就是其中最為出色的佼佼者。

modernizr(戳我查看 Github[5] )是一個(gè)開源的 javascript 庫。有著將近 2W 的 star ,其優(yōu)秀程度可見一斑。

簡單看看使用方法,假設(shè)頁面已經(jīng)引用了 modernizr ,語法如下:

  1. // Listen to a test, give it a callback 
  2. Modernizr.on('testname'function( result ) { 
  3.   if (result) { 
  4.     console.log('The test passed!'); 
  5.   } 
  6.   else { 
  7.     console.log('The test failed!'); 
  8.   } 
  9. }); 
  10.  
  11. // 或者是類似 CSS.supports() 
  12. Modernizr.testAllProps('background''linear-gradient(90deg, #888, #ccc)');  // true 

舉個(gè)實(shí)際的例子,假設(shè)我們希望對是否支持漸變這個(gè)樣式瀏覽器下的一個(gè) div 區(qū)別對待,有如下 CSS:

  1. div { 
  2.     background: #aaa; 
  3.  
  4. .linear-gradient div{ 
  5.     background: linear-gradient(90deg, #888, #ccc); 

使用 Modernizr 進(jìn)行判斷,如果支持漸變,則在根元素添加一個(gè) .linear-gradient 樣式,方便示例,使用了 jquery 語法:

  1. if (Modernizr.testAllProps('background''linear-gradient(90deg, #888, #ccc)')) { 
  2.     $('html').addClass('linear-gradient'); 

Demo - modernizr[6]

當(dāng)然,Modernizr 還有很多其他的功能,可以去翻翻它的 API 。

特性檢測原理

如果嫌引入整一個(gè) Modernizr 庫太大,頁面又不支持 @supports ,其實(shí)我們自己用簡單的 javascript 實(shí)現(xiàn)也非常方便簡單。

想要知道瀏覽器支持多少 CSS 屬性,可以在調(diào)試窗口試試:

  1. var root = document.documentElement; //HTML 
  2.  
  3. for(var key in root.style) { 
  4.     console.log(key); 

 

上面圖片截取的只是打印出來的一小部分。如果我們要檢測某個(gè)屬性樣式是否被支持,在任意的 element.style 檢測它是否存在即可,即上面代碼示例的 root 可以替換成任意元素。

當(dāng)然,元素可能有 background 屬性,但是不支持具體的 linear-gradinet() 屬性值。這個(gè)時(shí)候該如何檢測呢?只需要將具體的值賦值給某一元素,再查詢這個(gè)屬性值能否被讀取。

  1. var root = document.documentElement; 
  2.  
  3. root.style.backgroundImage = 'linear-gradient(90deg, #888, #ccc)'
  4.  
  5. if(root.style.backgroundImage) { 
  6.   // 支持 
  7. else { 
  8.   // 不支持 

所以上面 Modernizr 的例子里,javascript 代碼可以改成:

  1. var root = document.documentElement; 
  2. root.style.backgroundImage = 'linear-gradient(90deg, #888, #ccc)'
  3.  
  4. if(root.style.backgroundImage) { 
  5.   $('html').addClass('linear-gradient'); 

當(dāng)然,做這種特定屬性值判斷的時(shí)候由于有個(gè) CSS 賦值操作,所以我們選取用于判斷的元素應(yīng)該是一個(gè)隱藏在頁面上的元素。

各種方式間的優(yōu)劣

  • 原生的 @supports 的性能肯定是最好的,而且無需引入外部 javascript ,首推這個(gè),但是無奈兼容問題,目前來看不是最好的選擇。
  • Modernizr 功能強(qiáng)大,兼容性好,但是需要引入外部 javascript,多一個(gè) http 請求,如果只是進(jìn)行幾個(gè)特性檢測,有點(diǎn)殺雞用牛刀的感覺。
  • 針對需要的特性檢測,使用 javascript 實(shí)現(xiàn)一個(gè)簡單的函數(shù),再把上面用到的方法封裝一下:
  1. /** 
  2.  * 用于簡單的 CSS 特性檢測 
  3.  * @param [String] property 需要檢測的 CSS 屬性名 
  4.  * @param [String] value 樣式的具體屬性值 
  5.  * @return [Boolean] 是否通過檢查 
  6.  */ 
  7. function cssTest(property, value) { 
  8.  // 用于測試的元素,隱藏在頁面上 
  9.  var ele = document.getElementById('test-display-none'); 
  10.  
  11.  // 只有一個(gè)參數(shù)的情況 
  12.  if(arguments.length === 1) { 
  13.   if(property in ele.style) { 
  14.    return true
  15.   } 
  16.  // 兩個(gè)參數(shù)的情況 
  17.  }else if(arguments.length === 2){ 
  18.   ele.style[property] = value; 
  19.  
  20.   if(ele.style[property]) { 
  21.    return true
  22.   } 
  23.  } 
  24.  
  25.  return false

 

軟件工程沒有銀彈,所以無論哪種方式,都有適合的場景,我們要做的就是掌握了解它們的原理,根據(jù)不同的場景靈活運(yùn)用即可。

最后

好了,本文到此結(jié)束,希望對你有幫助 :

參考資料

[1]戳我了解詳情:

http://www.cnblogs.com/coco1s/p/6402723.htm

[2]Code Demo - @supportAnd:

http://codepen.io/Chokcoco/pen/EWjbpv?editors=1100

[3]CodePen Demo -- @supports or:

http://codepen.io/Chokcoco/pen/yMNvvZ

[4]Can i use(更新至 2021/05/13):

http://caniuse.com/#search=%40supports

[5]戳我查看 Github:

https://github.com/Modernizr/Modernizr

[6]Demo - modernizr:

http://codepen.io/Chokcoco/pen/oZjNjW

[7]Github -- iCSS:

https://github.com/chokcoco/iCSS

 

責(zé)任編輯:姜華 來源: iCSS前端趣聞
相關(guān)推薦

2009-12-23 16:13:00

WPF Attache

2010-11-22 14:18:32

MySQL鎖機(jī)制

2010-07-21 09:38:15

PHP緩存技術(shù)

2009-11-20 17:17:08

Oracle函數(shù)索引

2009-08-27 11:27:58

foreach語句C# foreach語

2010-03-05 13:44:00

Python序列

2011-02-25 09:23:00

Java類加載器

2010-03-31 14:58:03

云計(jì)算

2015-09-02 08:57:56

JavaHashMap工作原理

2023-01-12 17:18:06

數(shù)據(jù)庫多云

2024-07-11 16:38:54

2024-01-26 06:42:05

Redis數(shù)據(jù)結(jié)構(gòu)

2017-01-03 17:57:46

Android異步精髓Handler

2013-07-11 09:45:48

扁平化扁平化設(shè)計(jì)

2009-10-16 09:17:39

屏蔽布線系統(tǒng)

2009-11-12 13:56:54

2009-12-14 14:40:10

Ruby全局域變量

2009-12-07 13:55:58

PHP array_m

2009-12-07 16:07:03

PHP類的繼承

2012-02-28 14:43:43

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)