国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當(dāng)前位置: 首頁 - 科技 - 知識百科 - 正文

關(guān)于CSS反射倒影的研究思考

來源:懂視網(wǎng) 責(zé)編:小采 時間:2020-11-27 15:38:13
文檔

關(guān)于CSS反射倒影的研究思考

關(guān)于CSS反射倒影的研究思考:原文地址:https://css-tricks.com/state-css-reflections 譯者:nzbin 友情提示:由于演示demo的兼容性,推薦火狐瀏覽。該文章篇幅較長,內(nèi)容龐雜,有一定難度。而我本人學(xué)識有限,加之時間倉促,所翻譯內(nèi)容可能有不恰當(dāng)及晦澀之處。歡迎大家拍磚指正。
推薦度:
導(dǎo)讀關(guān)于CSS反射倒影的研究思考:原文地址:https://css-tricks.com/state-css-reflections 譯者:nzbin 友情提示:由于演示demo的兼容性,推薦火狐瀏覽。該文章篇幅較長,內(nèi)容龐雜,有一定難度。而我本人學(xué)識有限,加之時間倉促,所翻譯內(nèi)容可能有不恰當(dāng)及晦澀之處。歡迎大家拍磚指正。
原文地址:https://css-tricks.com/state-css-reflections

譯者:nzbin

友情提示:由于演示demo的兼容性,推薦火狐瀏覽。該文章篇幅較長,內(nèi)容龐雜,有一定難度。而我本人學(xué)識有限,加之時間倉促,所翻譯內(nèi)容可能有不恰當(dāng)及晦澀之處。歡迎大家拍磚指正。

我最近在codePen上看到了這個 加載程序,一個純CSS制作的帶有漸變反射的3D旋轉(zhuǎn)豎條。它的制作方法是:為每個豎條創(chuàng)建一個元素,然后通過復(fù)制每一個元素來制作反射倒影,最后在反射倒影上添加漸變背景來制作漸隱的效果。聽上去有點復(fù)雜,而且創(chuàng)建漸隱效果的漸變背景在非純色背景下是無效的。有沒有更好的CSS方法呢?

答案是‘肯定’的,也是‘否定’的。‘肯定’是因為確實有可以做的方法,‘否定’是因為有些方法還不存在。令人遺憾的是,這些代碼只能用預(yù)處理器(主要通過循環(huán)來實現(xiàn)壓縮功能)壓縮一點點。如果我們不想使用canvas并且想兼容主流瀏覽器的當(dāng)前版本,復(fù)制豎條來制作倒影以及通過漸變背景來制作漸隱效果的方法仍然是最好的。

這篇文章主要探索現(xiàn)有的制作反射倒影的方法、舉例說明可能的解決方案、跨瀏覽器問題以及我的一些想法。

Demo的基本設(shè)置

#創(chuàng)建豎條元素

首先我們創(chuàng)建一個 .loader 元素以及在其中創(chuàng)建10個 .bar 元素

HTML

把同樣的事情寫很多遍是一件痛苦的事,所以在該情況下使用一個預(yù)處理器會變得很簡單。我們在這里使用 Haml 模板,當(dāng)然也有人會選擇其他的模板。

Haml
.loader
 - 10.times do
 .bar

我們通過絕對定位把所有元素放到視圖的中間。大多數(shù)情況下,我們使用 top: 50% ,但是現(xiàn)在,使用 bottom: 50% 會使后面的操作更簡單。

CSS
div {
 position: absolute;
 bottom: 50%; left: 50%;
}

我們給豎條設(shè)置 width 和 height ,為了能看到它再設(shè)置一個 background

SCSS
$bar-w: 1.25em;
$bar-h: 5 * $bar-w;

.bar {
 width: $bar-w; 
height: $bar-h; background: currentColor; }

我們希望豎條的底部貼合視圖的水平中心線。設(shè)置 bottom: 50% 已經(jīng)可以了。

現(xiàn)在所有的豎條都重合在一起,它們的左邊貼在垂直中心線上,底部貼在水平中心線上。

See the Pen bar loader 1.1 creating the bars by Zongbin Niu (@nzbin) on CodePen.

為了看清楚豎條的邊界,我們給它一個 box-shadow 。

See the Pen bar loader 1.2 positioning the bars by Zongbin Niu (@nzbin) on CodePen.

#給豎條添加漸變

豎條的背景色是從最左邊的深藍(lán)色( #1e3f57 )過渡到最右邊的淺藍(lán)色( #63a6c1 )。這聽上去很像 the Sass mix() function 所做的。第一個參數(shù)是淺藍(lán)色,第二個參數(shù)是深藍(lán)色,第三個參數(shù)(稱作相對權(quán)重)表示將多少(百分比表示)淺藍(lán)色混合進(jìn)去。

對于第一個豎條,這個數(shù)量就是 0% ( 0% 數(shù)量的淺藍(lán)色),混合結(jié)果就是深藍(lán)色。

對于最后一個豎條,這個數(shù)量是 100% ( 100% 數(shù)量的淺藍(lán)色,也就是 0% 數(shù)量的深藍(lán)色),得到的背景色就是淺藍(lán)色。

對于剩下的豎條,我們需要平均分布的中間值。如果我們有 $n 個豎條,第一個豎條在 0% 的位置,最后一個豎條在 100% 的位置,那么我們需要在兩者之間平分成 $n-1 個區(qū)間。

See the Pen distribute n points on 100% interval (interactive) by Zongbin Niu (@nzbin) on CodePen.

一般來說,索引值為 $i 的豎條的相對權(quán)重是 $i * 100% / ($n - 1) ,這意味著我們要添加如下代碼:

SCSS
$c: #63a6c1 #1e3f57; // 1st = light 2nd = dark

@for $i from 0 to $n {
 // list of mix() arguments for current bar
 $args: append($c, $i * 100% / ($n - 1));

 .bar:nth-child(#{$i + 1}) {
 background: mix($args...);
 }
}

現(xiàn)在這些豎條看起來就和原始demo的一樣了:

See the Pen bar loader #1.3 shading the bars by Zongbin Niu (@nzbin) on CodePen.

探索反射的方案

#WebKit瀏覽器:-webkit-box-reflect

很遺憾,這不是一個標(biāo)準(zhǔn)屬性!我不知道為什么這個屬性沒有標(biāo)準(zhǔn)化。這一屬性首次出現(xiàn)在Safari瀏覽器上時,我還不知道CSS。 但是對于WebKit內(nèi)核的瀏覽器,這是一個非常好的實現(xiàn)方法。它做了很多工作。它的使用很簡單,即使在不支持該屬性的瀏覽器上,除了不顯示反射以外,并沒有什么其他影響。

讓我們看看它是怎么工作的,它需要三個參數(shù)值:

  • 方向:包含 below , left , above , right
  • 偏移值(可選):指定反射的開始位置到元素的底邊的距離(這是一個CSS長度值)。
  • 圖片遮罩(可選):可以是CSS漸變值。
  • See the Pen how `-webkit-box-reflect` works by Ana Tudor (@thebabydino) on CodePen.

    注意:linear-gradient()可以有更多的顏色斷點,也可以用radial-gradient()替換。

    在我們的demo中,我首先想到的就是給 .loader 元素添加這一屬性。

    SCSS
    .loader {
     -webkit-box-reflect: below 0 linear-gradient(rgba(#fff), rgba(#fff, .7));
    }

    但是在WebKit瀏覽器中測試時,我們并沒有看到反射。

    See the Pen bar loader 2.1.1 -webkit-box-reflect by Zongbin Niu (@nzbin) on CodePen.

    這里發(fā)生了什么?我們給所有的元素設(shè)置了絕對定位,但是并沒有設(shè)置 .loader 元素的尺寸。所以這是一個寬高都為0的元素。

    讓我們給 .loader 元素一個明確的尺寸,高度 height 等于豎條的高度 $bar-h ,寬度等于所有豎條的寬度之和 $n * $bar-w 。為了看清元素的邊界,我們暫時給它一個 box-shadow 。

    SCSS
    $loader-w: $n * $bar-w;
    
    .loader {
     width: $loader-w; height: $bar-h;
     box-shadow: 0 0 0 1px red;
    }

    我之所以用 box-shadow 而不用 outline 是因為如果子元素溢出父元素,在不同的瀏覽器上使用 outline 突出物體的效果是不一樣的。

    outline屬性在WebKit瀏覽器中的對比。Edge(上)vs. Firefox(下)

    添加以上代碼后的結(jié)果可以在WebKit瀏覽器中看到:

    See the Pen bar loader 2.1.2 explicitly sizing the loader by Zongbin Niu (@nzbin) on CodePen.

    如果你用的不是WebKit瀏覽器,看下面的圖片,就是這個樣子:

    現(xiàn)在我們可以看到loader元素的邊界和倒影,但是位置不正確。我們希望loader元素在水平中間的位置,所以把它向左移動寬度的一半。我們也希望子元素的底部與父元素的底部貼合,所以設(shè)置子元素 bottom: 0 。

    SCSS
    .loader { margin-left: -.5 * $loader-w; }
    
    .bar { bottom: 0; }

    修正位置之后的樣子如下:

    See the Pen bar loader 2.1.3 tweaking loader and bar positions by Zongbin Niu (@nzbin) on CodePen.

    #火狐瀏覽器 element() + mask

    ##用 element() 制作反射

    element() 函數(shù)(現(xiàn)在仍然有效,必須在火狐瀏覽器中使用并且添加 -moz- 前綴)給我們提供了一個像真實圖片一樣可以任意使用的圖像值。它需要一個參數(shù)值,就是我們希望以 background 還是 border-image 顯示的被選元素的 id 。這允許我們做很多事情,比如使用可以控制的圖片作為背景。我們也可以在Firefox中制作一個反射元素。

    需要著重了解的一點就是 element() 函數(shù)不是遞歸函數(shù),我們不能創(chuàng)建使用元素作為自身背景的圖像。這在創(chuàng)建反射的loader元素的偽類上使用是安全的,因此我們不用創(chuàng)建額外的元素。

    好吧,讓我們看看如何操作。首先,我們給 .loader 元素一個 id 。轉(zhuǎn)到樣式表,我們從適用WebKit瀏覽器的CSS著手。我們在loader元素上添加一個 ::after 偽類

    CSS
    .loader::after {
     position: absolute;
     top: 0; right: 0; bottom: 0; left: 0;
     box-shadow: 0 0 0 2px currentColor;
     color: crimson;
     content: 'REFLECTION';
    }

    為了在最終效果中看清偽類的邊界和方向,我們設(shè)置了一些暫時性的樣式,我們想讓它是顛倒的。

    See the Pen bar loader 2.2.1 adding a pseudo by Zongbin Niu (@nzbin) on CodePen.

    現(xiàn)在我們需要以底邊為基準(zhǔn)把 ::after 偽類鏡像過來。為了做到這一點,我們使用 scaleY() 屬性并且選擇合適的 transform-origin 。

    以下的可交互demo說明了包含多個縮放因子以及變換中心的定向縮放是如何工作的:

    See the Pen how CSS scaling w.r.t. various origins works by Ana Tudor (@thebabydino) on CodePen.

    注意:縮放因子的數(shù)值和變換中心可以超出demo中規(guī)定的。

    在我們的例子中,我們需要 scaleY(-1) 并且 transform-origin 在 ::after 偽類的底邊上。

    使用scaleY(-1)和一個合適的 transform-origin 來鏡像元素

    我們把這些設(shè)置添加到代碼中,并且用 element () 函數(shù)把 ::after 偽類的背景設(shè)置為 #loader

    CSS
    .loader::after {
     transform-origin: 0 100%;
     transform: scaleY(-1);
     background: -moz-element(#loader);
    }

    注意:由于特別的原因我們使用 .loader 作為選擇器并且由于element() 函數(shù)參數(shù)的需要我們設(shè)置它的 id 為 #loader 。

    添加以上代碼后的效果如下所示(只在Firefox瀏覽器中有效)

    See the Pen bar loader 2.2.2 -moz-element() for reflecting pseudo by Zongbin Niu (@nzbin) on CodePen.

    對于在其他瀏覽器閱讀這篇文章的朋友,以下是截圖

    在Firefox中使用 element() 制作的反射效果

    ##用 mask 制作漸變

    我們使用和WebKit情況下一樣的方法給反射添加漸變。在WebKit的情況下,遮罩是 -webkit-box-reflect 屬性的一部分。而現(xiàn)在,我們討論CSS的 mask 屬性,它需要引用SVG作為值。

    CSS
    mask: url(#fader);

    #fader 元素是一個包含長方形的SVG mask 元素。

    SVG
    
     
     
     
    

    我們可以用Haml模板壓縮一下

    Haml
    %svg
     %mask#fader(maskContentUnits='objectBoundingBox')
     %rect(width='1' height='1')

    但是,如果我們加上以上代碼,我們的反射倒影消失了,在Firefox中查看如下demo

    See the Pen bar loader 2.2.3 adding a SVG mask by Zongbin Niu (@nzbin) on CodePen.

    這是因為,默認(rèn)情況下,SVG圖形會有一個純黑色的 fill ,完全不透明,但是,我們的 遮罩 默認(rèn)是有透明度的。因此為了實現(xiàn)反射漸變的效果我們需要給長方形一個 fill (需引入SVG linearGradient )

    Haml
    %rect(width='1' height='1' fill='url(#grad)')

    一個SVG linearGradient 由定義的兩個點 x1 , y1 , x2 , y2 組成。 x1 和 y1 是漸變線的起始點(0%)坐標(biāo),而 x2 和 y2 是這條線的終點(100%)坐標(biāo)。如果這些數(shù)值是空的,默認(rèn)設(shè)為 0% , 0% , 100% , 0% 。這些數(shù)值描繪了從指定元素(由于 gradientUnits 的默認(rèn)值是 objectBoundingBox )的左上( 0% 0% )到右上( 100% 0% )的一條線。這意味著,默認(rèn)情況下,漸變是從左到右。

    但是在我們的例子中,我們希望漸變從上到下,所以我們將 x2 的值從 100% 設(shè)置為 0% 并且將 y2 的值從 0% 設(shè)置為 100% 。這使得指定元素的漸變向量從左上角( 0% 0% )指向左下角( 0% 100% )。

    Haml
    %linearGradient#grad(x2='0%' y2='100%')

    在 linearGradient 元素之內(nèi),我們至少需要兩個 stop 元素。其中有三個特定的屬性, 偏移值 , 顏色斷點 , 透明度斷點。

    1. 偏移值 :可以使用百分比,通常在 0% 到 100% 之間,和CSS漸變一樣。也可以使用數(shù)值,通常是從0到1。
    2. 顏色斷點 :理論上可以使用關(guān)鍵字 hex() , rgb() , rgba() , hsl() 或者 hsla() ,實際上Safari不支持半透明數(shù)值,因此如果想設(shè)置漸變?yōu)榘胪该鳎覀冃枰蕾嚨谌齻€屬性。
    3. 透明度斷點 :可以設(shè)置從0(完全透明)到1(完全不透明)的數(shù)值。

    我們需要記住我們應(yīng)用漸變遮罩的偽類已經(jīng)通過 scaleY(-1) 屬性鏡像過來了,這意味著漸變遮罩的底部在視覺上是頂端。因此我們的漸變是從頂部(視覺下端)的完全透明到底部(視覺上端)的 .7 。

    因為我們的漸變從上到下,所以第一個 stop 是完全透明的。

    Haml
    %linearGradient#grad(x2='0%' y2='100%')
     %stop(offset='0' stop-color='#fff' stop-opacity='0')
     %stop(offset='1' stop-color='#fff' stop-opacity='.7')

    添加線性漸變之后,在Firefox中就是我們想要的結(jié)果了

    實時效果如下:

    See the Pen bar loader 2.2.4 linearGradient it by Zongbin Niu (@nzbin) on CodePen.

    SVG漸變的問題

    在我們的例子中,因為我們的遮罩漸變是垂直的所以看起來很簡單。但是如果我們的漸變不是垂直或者水平或者從一個角到另一個角怎么辦?如果我們想要一個特定角度的漸變怎么辦?

    SVG中有一個 gradientTransform 屬性,它可以通過指定 x1 , y1 , x2 , y2 來旋轉(zhuǎn)漸變線。有人可能會認(rèn)為這是制作具有特定角度的CSS漸變的簡單方法。但是,并沒有想象的那么簡單!

    想一想從金色到深紅色漸變的例子。為了看得清楚一點,我們在兩者之間50%的位置設(shè)置一個劇烈的過渡。首先我們將這個漸變的CSS角度設(shè)置為 0deg 。這意味著漸變會從底部(金色)過渡到頂部(深紅色)。創(chuàng)建這個漸變的CSS如下:

    CSS
    background-image: linear-gradient(0deg, #e18728 50%, #d14730 0);

    如果你還不明白CSS線性漸變的工作原理,你可以看一下Patrick Brosset 做的這個 優(yōu)秀作品。

    我們看到的結(jié)果如下:

    See the Pen CSS linear-gradient at 0deg with sharp stop at 50% by Ana Tudor (@thebabydino) on CodePen.

    為了制作SVG的漸變,我們設(shè)置 y1 為 100% y2 為 0% 以及把 x1 和 x2 設(shè)置成相同的數(shù)值(簡單起見設(shè)置為0)。這意味著漸變線從底部垂直上升到頂部。我們同時把斷點的偏移值設(shè)置為50%。

    Jade
    linearGradient#g(y1='100%' x2='0%' y2='0%' gradientTransform='rotate(0 .5 .5)')
     stop(offset='50%' stop-color='#e18728')
     stop(offset='50%' stop-color='#d14730')

    編輯注:我問Ana為什么她現(xiàn)在要使用Jade模板。她說:我起初使用Haml模板是因為我想避免引入我不需要的循環(huán)變量,而之后使用Jade模板是因為它允許變量和計算。

    這個漸變還沒有旋轉(zhuǎn),因為 gradientTransform 的值是 rotate(0 .5 .5) 。其中后兩個數(shù)值表示漸變旋轉(zhuǎn)的坐標(biāo)。其中 0 0 表示左上角, 1 1 表示右下角, .5 .5 表示中心。

    實時效果如下:

    See the Pen SVG linearGradient bottom to top rotated by 0deg with sharp stop at 50% by Ana Tudor (@thebabydino) on CodePen.

    如果我們希望漸變從左到右,在CSS漸變中,我們把角度從 0deg 設(shè)置為 90deg

    CSS
    background-image: linear-gradient(90deg, #e18728 50%, #d14730 0);

    See the Pen CSS linear-gradient at 90deg with sharp stop at 50% by Ana Tudor (@thebabydino) on CodePen.

    為了在SVG漸變中得到同樣的結(jié)果,我們將 gradientTransform 的值設(shè)置為 rotate(90 .5 .5) 。

    Jade
    linearGradient#g(y1='100%' x2='0%' y2='0%' gradientTransform='rotate(90 .5 .5)')
     // same stops as before

    See the Pen SVG linearGradient bottom to top rotated by 90deg with sharp stop at 50% by Ana Tudor (@thebabydino) on CodePen.

    到目前為止,一切正常。用SVG來代替CSS漸變并沒有遇到太多問題。讓我們嘗試一下其他的角度。在下面的可交互demo中,左側(cè)是一個CSS漸變,右邊是一個SVG漸變。紫色的線是漸變線,它與金色和深紅色的交界線是垂直的。拖拽滑塊可以同時改變CSS和SVG的漸變角度。我們會看到一些錯誤:有些數(shù)值不是 90deg 的倍數(shù)。

    See the Pen CSS vs. SVG gradient, same angle (interactive, responsive) by Ana Tudor (@thebabydino) on CodePen.

    如以上demo所示,有些數(shù)值不是 90deg 的倍數(shù),我們無法得到相同的結(jié)果。只有當(dāng)我們設(shè)置漸變的元素是正方形時結(jié)果是相同的。這意味著我們可以給一個更大的正方形元素設(shè)置漸變,然后裁剪成實際的形狀。然而做這些工作會讓 element() 和 mask 來創(chuàng)建漸變倒影的方法更加復(fù)雜。

    #Edge:可以全用SVG嗎?

    令人遺憾的是,以上提到的兩種方法在Edge中都沒有用。因此既能在Edge中運(yùn)行又無需手動復(fù)制每個豎條的僅有的方法就是,放下前面的工作重新制作SVG加載器。這中方法具有跨瀏覽器的優(yōu)勢。

    總的來說,我們創(chuàng)建一個帶有 viewBox 的SVG元素,以便把 0 0 點放在中間。我們定義一個豎條,它的底邊在x軸上,左邊在y軸上。然后我們在 #loader 群組中根據(jù)需要復(fù)制(通過SVG use 元素)多次。我們?nèi)缰耙粯臃胖眠@些豎條的位置。

    Jade
    - var bar_w = 125, bar_h = 5 * bar_w;
    - var n = 10;
    - var vb_w = n * bar_w;
    - var vb_h = 2 * bar_h;
    - var vb_x = -.5 * vb_w, vb_y = -.5 * vb_h;
    
    svg(viewBox=[vb_x, vb_y, vb_w, vb_h].join(' '))
     defs
     rect#bar(y=-bar_h width=bar_w height=bar_h)
    
     g#loader
     - for(var i = 0; i < n; i++) {
     - var x = (i - .5 * n) * bar_w;
     use(xlink:href='#bar' x=x)
     - }

    以上代碼的效果如下:

    See the Pen bar loader 2.3.1 creating and positioning SVG bars by Zongbin Niu (@nzbin) on CodePen.

    現(xiàn)在我們已經(jīng)創(chuàng)建了所有豎條,我們想把svg元素的位置調(diào)整的更準(zhǔn)確而且我們使用flexbox屬性。同時我們也和之前一樣給豎條添加漸變色。我們用Sass做這些事情

    SCSS
    $n: 10;
    $c: #63a6c1 #1e3f57;
    $bar-w: 1.25em;
    $bar-h: 5 * $bar-w;
    $loader-w: $n * $bar-w;
    $loader-h: 2 * $bar-h;
    
    body {
     display: flex;
     justify-content: center;
     margin: 0;
     height: 100vh;
    }
    
    svg {
     align-self: center;
     width: $loader-w; height: $loader-h;
    }
    
    @for $i from 0 to $n {
     $args: append($c, $i * 100%/($n - 1));
    
     [id='loader'] use:nth-child(#{$i + 1}) {
     fill: mix($args...);
     }
    }

    添加以上代碼后的效果如下:

    See the Pen bar loader 2.3.2 sizing + positioning the SVG & shading the bars by Zongbin Niu (@nzbin) on CodePen.

    我們復(fù)制 #loader 群組(再次使用 use 元素)。我們通過 scale(1 -1) 方法鏡像克隆體并且給它添加一個遮罩,和我們之前給偽類元素設(shè)置的一樣。默認(rèn)情況下,SVG元素相對于SVG畫布的 0 0 點縮放,這個點正好位于loader元素的底邊上,可以很完美的將loader元素鏡像過來,我們不用設(shè)置 transform-origin 。

    Jade/SVG
    use(xlink:href='#loader' transform='scale(1 -1)')

    我們使用 transform 屬性代替CSS變換,因為CSS變換在Edge中不支持。

    現(xiàn)在我們有了反射倒影,如下所示:

    See the Pen bar loader 2.3.3 getting the reflection by Zongbin Niu (@nzbin) on CodePen.

    最后一步就是用 mask 給反射添加漸變。它的方法及代碼和之前都是一樣的,我們不再贅述。所有的代碼都在下面的Pen中

    See the Pen bar loader 2.3.4 fading the reflection by Zongbin Niu (@nzbin) on CodePen.

    動畫

    原始案例中的CSS動畫很簡單,就是用3D方式旋轉(zhuǎn)豎條:

    CSS
    @keyframes bar {
     0% {
     transform: rotate(-.5turn) rotateX(-1turn);
     }
     75%, 100% { transform: none; }
    }

    所有的豎條都是同樣的動畫:

    CSS
    animation: bar 3s cubic-bezier(.81, .04, .4, .7) infinite;

    我們只是給循環(huán)的豎條添加了不同的延遲時間。

    SCSS
    animation-delay: $i*50ms;

    因為我們希望旋轉(zhuǎn)的豎條具有3D效果,所有我們給loader元素添加一個 perspective 屬性

    但是使用 -webkit-box-reflect 方法后和預(yù)期的一樣只能在WebKit瀏覽器中執(zhí)行。

    在Chrome瀏覽器中使用 -webkit-box-reflect 屬性后的最終結(jié)果

    我們同時添加了一張背景圖片來看一下它的表現(xiàn)效果。只能在WebKit瀏覽器中預(yù)覽的效果如下:

    See the Pen bar loader 3.1 animating the bars by Zongbin Niu (@nzbin) on CodePen.

    我們也嘗試在Firefox中執(zhí)行動畫。但是,如果我們把動畫添加到之前在Firefox中運(yùn)行良好的代碼中,好像出現(xiàn)了一些問題。

    在Firefox中使用element()和mask方法做的動畫雛形

    這里有一點問題,下面的demo可以在Firefox中實時檢測:

    See the Pen bar loader 3.2.1 adding animation by Zongbin Niu (@nzbin) on CodePen.

    第一個問題就是反射在偽類的邊界處被切斷。我們可以通過增加loader元素的尺寸來修復(fù)這一問題(偽類元素不受影響):

    SCSS
    $loader-w: ($n + 1) * $bar-w + $bar-h;

    但是我們對于其余的兩個問題就束手無策了。當(dāng)豎條進(jìn)行3D旋轉(zhuǎn)時,反射無法平滑的渲染更新;以及 perspective 屬性導(dǎo)致了豎條的消失。

    添加perspective屬性的結(jié)果 沒有添加perspective屬性的結(jié)果

    以下是實時的顯示結(jié)果:

    See the Pen bar loader 3.2.2 tweaks by Zongbin Niu (@nzbin) on CodePen.

    全部都用SVG的方案怎么樣?很不幸,上面的例子中,我們只用CSS的3D變化制作動畫。在Edge中,SVG元素不支持CSS的變換屬性,所以我們之前在創(chuàng)建倒影時使用了SVG的 transform 屬性。但是 transform 屬性是嚴(yán)格的2D模式,我們只能使用JavaScript添加動畫。

    所以就目前來看,想要制作一個兼容所有瀏覽器并且不用復(fù)制每一個豎條的加載動畫是不可能了。我們現(xiàn)在能做的就是創(chuàng)建兩個loader元素,每一個都有相同數(shù)量的豎條。

    Haml
    - 2.times do
     .loader
     - 10.times do 
     .bar

    豎條的樣式和之前一樣,我們使用 scale(-1) 來鏡像第二個loader元素。

    CSS
    .loader:nth-child(2) {
     transform: scaleY(-1);
    }

    我們添加豎條動畫后得到如下結(jié)果:

    See the Pen bar loader 3.3.1 reflection via duplication by Zongbin Niu (@nzbin) on CodePen.

    現(xiàn)在我們需要給反射添加漸變。遺憾的是,我們不能在第二個loader元素上使用 mask ,因為它只在跨瀏覽器的SVG元素上有效。Edge目前還不支持HTML元素的遮罩效果,但是你可以給官方提建議。

    我們只能在第二個loader元素上添加漸變背景。這樣一來我們就不能使用圖片背景了。漸變背景只在純色背景或者有限的情況下才有效。我們在第二個loader元素的 ::after 上添加漸變背景并且設(shè)置的大一點,這樣就不會擋住旋轉(zhuǎn)的豎條。

    SCSS
    $bgc: #eee;
    $cover-h: $bar-w + $bar-h;
    $cover-w: $n * $bar-w + $cover-h;
    
    html { background: $bgc; }
    
    .loader:nth-child(2)::after {
     margin-left: -.5 * $cover-w;
     width: $cover-w; height: $cover-h;
     background: linear-gradient($bgc $bar-w, rgba($bgc, .3));
     content: '';
    }

    最終結(jié)果如下:

    See the Pen bar loader 3.3.2 emulate fading with cover by Zongbin Niu (@nzbin) on CodePen.

    最后的思考

    我們需要一個更好的跨瀏覽器解決方案。我相信制作物體的反射并不需要像我們在這個例子中一樣復(fù)制所有的子元素。為了制作可以放置在背景圖像上的漸變反射,我們不能替換成SVG的方案(其自身也有很多問題)。

    哪一種方案更好? -webkit-box-reflect 還是 element() + mask ?我也不知道。我個人喜歡同時使用。

    雖然使用 :reflection 偽類元素 看上去很合理,但是我曾經(jīng)確信我不想使用額外的元素制作反射。但是現(xiàn)在有比不用插入額外元素更讓我喜歡的事情。使用 element() 可以在不同方向上自由創(chuàng)建多個反射,以及用不同的方式變換反射,比如3D旋轉(zhuǎn)或者傾斜。這正是我喜歡它的原因。而且用SVG做遮罩意味著我們可以在反射上應(yīng)用更復(fù)雜的遮罩同時獲得更酷的效果。

    另一方面,能力越強(qiáng),責(zé)任越大。也許你沒有時間去接觸強(qiáng)大功能背后的復(fù)雜細(xì)節(jié)。有時你只是想要一個簡單的方法來獲得一個簡單的結(jié)果。

    聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    關(guān)于CSS反射倒影的研究思考

    關(guān)于CSS反射倒影的研究思考:原文地址:https://css-tricks.com/state-css-reflections 譯者:nzbin 友情提示:由于演示demo的兼容性,推薦火狐瀏覽。該文章篇幅較長,內(nèi)容龐雜,有一定難度。而我本人學(xué)識有限,加之時間倉促,所翻譯內(nèi)容可能有不恰當(dāng)及晦澀之處。歡迎大家拍磚指正。
    推薦度:
    標(biāo)簽: 思考 倒影 css
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top 主站蜘蛛池模板: 性久久久久 | 日韩视频免费看 | 日韩精品a在线视频 | 国产精品视频一区二区三区w | 一级毛片特黄久久免费看 | 国产精品免费看 | 欧美人与动性xxxxx杂性 | 精品欧美日韩一区二区三区 | 亚欧乱色视频网站大全 | 欧美日韩高清一区 | 免费观看亚洲视频 | 成人欧美日韩 | 国内一区亚洲综合图区欧美 | 亚洲欧美日韩精品高清 | 国产 欧美 日韩 在线 | 激情综合亚洲欧美日韩 | 黄色免费网站视频 | 亚洲欧美中文日韩在线 | 久久久国产一区二区三区 | 精品一区二区在线 | 91热成人精品国产免费 | 夜夜骑首页 | 欧美在线看欧美视频免费网站 | 国产欧美在线观看一区二区 | 久草婷婷 | 亚洲一级毛片 | 91精品国产免费久久久久久 | 欧美高清在线精品一区二区不卡 | 亚洲精品在线免费观看 | 日韩一区二区三区在线播放 | 素人面接 | 欧美区一区 | 久久伊人一区二区三区四区 | 一级免费毛片 | 欧美一区二区三区视频在线观看 | 亚洲成人免费 | 欧美视频一区二区三区在线观看 | 欧美 韩国 精品 另类 综合 | 国产一二三区视频 | 国产亚洲一欧美一区二区三区 | 日韩在线看片 |