1. 程式人生 > >CSS動效集錦,視覺魔法的碰撞與融合(一)

CSS動效集錦,視覺魔法的碰撞與融合(一)

前言

在本文中我講述了7種CSS的動效,它們也許看起來並不驚豔,但是我認為卻足夠傳達本文的理念:編寫一些特殊的CSS樣式的時候需要不拘於常理,要用特殊的認識角度看待標籤和樣式屬性,從而用「繞個彎」的方式達到效果。

一.浮光掠影

首先我們看第一個實現效果:在滑鼠浮動到圖片上方時,讓一片白影一閃而過。

 

實現思路

  1. 畫一個豎直的長方形的白色div,設定opcity將其變為半透明

  2. 藉助transform:skewX將長方形變成等高的平行四邊形

  3. 白條div絕對定位,外層div相對定位,一開始left屬性預設是0

  4. 在:hover偽元素中修改left值,例如left=600px(超出圖片長度),通過transition指定left和時間,形成過渡

圖示

 

HTML

 

<div class="flash">
        <div class="flash-bar"></div>
        <img src="{圖片地址}" />
</div>

 

CSS

 

.flash {
   position: relative;
   width: 500px;
}
.flash img {
    width: 100%;
}
.flash-bar {
   position: absolute;
   left:-100px;
   width: 20px;
   height: 100%;
   background: #fff;
   opacity: 0.5;
   transform: skewX(-30deg);
   transform-origin: 0 100%;
}
.flash:hover .flash-bar {
  left:900px;
  transition: left ease-in-out 1s;
}

 

 

 

二.發光球體

 

實現思路

讓一個球體散發光芒,一開始好像有點蒙,但是換個角度思考一下,光芒只是另一種顏色的box-shadow而已,然後我們通過animation讓它動起來就好了

 

HTML

<div class="light"></div>

CSS

@keyframes light {
    from {
       box-shadow:0px 0px 4px #f00;
    }
    to {
      box-shadow:0px 0px 16px #f00;
    }
}
.light {
  margin:300px;
  width: 100px;
  height: 100px;
  margin:20px;
  border-radius: 50%;
  animation: light 2s ease-in-out infinite alternate;
}

 

三.圓環進度條

很顯然,圓框是通過border去實現的,但具體怎麼做呢?

 

 

 

這個進度條,表面上看它是由一個div圓框組成,實則不然,它是由左右兩個半圓的div組成的,其中一個div轉動180度,然後另一個div再轉180度。看一下下面的例子你就明白了,我們把顏色調成藍色和紅色,以對比

 

我們一步一步來解釋,首先我們整個圓的外部是一個正放心,左右由兩個div,div-left和div-right組成,各佔一半,分別放左半圓和右半圓。而且兩個div分別設定overflow:hidden實現溢位隱藏,這樣的結果是,左邊的圓的右半邊被隱藏了,右邊的圓的左半邊被隱藏了。

 

 

而且更重要的是,兩個因為溢位被隱藏的半圓分別被塗上了藍色和紅色,而沒有溢位的兩個半圓的圓框則是透明的。所以我們看到的初始的空進度條其實是下面這樣的

 

 

這兩個圓框轉動的規則是:

  1. 左邊的藍色圓框先轉完0度到180度,這段時間裡紅色圓框是不動的

  2. 接下來紅色圓框轉完180度到360度,這段時間裡藍框則是不動的

(備註:我們約定最上方為0/360度)

轉到45度角的時候進度條是下面這樣子

 

 

轉角超過180時也是同理的,不過這個時候就輪到紅色框轉動了,藍框保持不動

 

程式碼如下:

HTML

<div class="progress">
    <div class="wrapper-circle left">
        <div class="circle"></div>
    </div>
    <div class="wrapper-circle right">
        <div class="circle"></div>
    </div>
</div>

CSS

@keyframes left_cirlce_spin {
    0%,50% {
      transform: rotate(-45deg);
    }
    100%{
      transform: rotate(135deg); 
    }
}
@keyframes right_cirlce_spin {
    0% {
      transform: rotate(45deg);
    }
    50%,100%{
      transform: rotate(225deg); 
    }
}
.progress {
    overflow: hidden;
    width: 100px;
    height: 100px;
}
.progress .wrapper-circle {
    overflow: hidden;
    width: 50%;
    height: 100%;
}
.left {
    float: left;
}
.right {
    float: right;
}
.progress {
    margin: 20px;
}
.progress .circle {
    border-radius: 50%;
    width: 90px;
    height: 90px;
}
.progress .left .circle {
    float: left;
    border: 5px solid red;
    border-top-color: transparent;
    border-left-color: transparent;
    animation: left_cirlce_spin 4s linear infinite;
}

.progress .right .circle {
    float: right;
    border: 5px solid red;
    border-top-color: transparent;
    border-right-color: transparent;
    animation: right_cirlce_spin 4s linear infinite;
}

 

四.三角形

這個話題已經是老生常談了,我第一個瞭解的比較有趣的CSS實現就是它。它是通過一個寬高設定為0的div的border去實現的。

要實現三角形,首先我們要改變心裡對border形狀的刻板認知。border其實是一個等腰梯形而不是長方形

 

 

當width和height被減小為0,只有border的時候,border就從等腰梯形變成了等腰三角形:

 

 

然後我們需要哪一塊三角形,就把剩餘的部分border都設為transparent(透明)就可以了

程式碼很簡單,這裡就不加贅述了。

五.有色到透明的漸變

下面這張圖是從知乎的發現欄目上摘來的,很顯然它是利用漸變去實現的。思路也很簡單,主要是要有兩方面的認知:

    • 這張圖其實可以分成兩部分,右邊控制圖形和漸變,左邊就是一張純色背景,和漸變無關

    • 透明transparent也是一種顏色,也是漸變可以設定的

 

 

程式碼如下

HTML

<!-- 有色到透明的背景漸變 -->
<div class="background-gradient">
  <div class="mask"></div>
</div>

CSS

.background-gradient {
    background: rgb(44, 136, 207);
    position: relative;
    width: 500px;
    height: 200px;
}
.background-gradient .mask {
    background-image: linear-gradient(to right, rgb(44, 136, 207), transparent), url("https://pic1.zhimg.co
    m/50/v2-6c5aa2304a93b7fbaf903e3560543d7b_hd.jpg");
    background-position:center;
    background-blend-mode:normal;
    position: absolute;
    height: 100%;
    width: 180px;
    right: 0;
}

 

 

 

六.模糊效果和毛玻璃效果

知乎上,在發表文章或回答時引入連結就會有下面模糊的效果。它其實是由CSS3的filter屬性去實現的

 

 <img class="blur" src="https://pic1.zhimg.com/50/v2-6c5aa2304a93b7fbaf903e3560543d7b_hd.jpg" />

 CSS

.blur {
    width: 100px;
    filter: url(blur.svg#blur); /* FireFox, Chrome, Opera */
    
    -webkit-filter: blur(2px); /* Chrome, Opera */
       -moz-filter: blur(2px);
        -ms-filter: blur(2px);    
            filter: blur(2px);
    
    filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius=2, MakeShadow=false); /* IE6~IE9 */
}

 

效果如下

 

要注意相容,相容各個瀏覽器的方法如上圖所示,順便一提這份程式碼由大神張鑫旭提供,連結如下

CSS濾鏡讓圖片模糊(毛玻璃效果)

模糊效果和IOS中的毛玻璃效果還是不一樣的。(其實我也感覺毛玻璃效果比起模糊效果會漂亮很多),而IOS的毛玻璃效果可以藉助backdrop-filter去實現,連結如下,大家可以自行嘗試

backdrop-filter

CSS原生毛玻璃效果

不過注意,目前backdrop-filter在較高版本的瀏覽器才會支援

七.斜角標籤

有的時候,在顯示一些時效性的UI資料的時候,例如一個商品卡片的打折標籤的時候,我們可能會需要在卡片上顯示一個等腰梯形,那麼我們該怎麼實現呢?

 

 

實際上,我們可以通過一個橫向的div通過transform:rotate逆時針旋轉45度角得到它。如下圖所示,同時要注意給外層div設定overflow:hidden實現溢位隱藏。

 

 

除此之外,還需要進行簡單的計算,因為旋轉上去後,形成的是一個等腰直角三角形,所以標籤div的長度需要是它距離外層div頂部距離的√2(根號2)倍,如上圖所示。

程式碼如下:

HTML

<div class="label">
     <div class="label-bar">打折</div>
     <img src="https://pic1.zhimg.com/50/v2-6c5aa2304a93b7fbaf903e3560543d7b_hd.jpg" />
</div>

CSS

.label {
    position: relative;
    overflow: hidden;
}
.label-bar {
    text-align: center;
    background: red;
    position: absolute;
    top:80px;
    left: 0px;
    width: 141px;
    height:20px;
    transform-origin: 0 100%;
    transform: rotate(-45deg);
}

技術總結

OK,下面進行CSS3的技術(坑點)總結~

 

1.轉換行為(rotate,skew等)的2D座標系是這樣的,Y軸是向下的!原點是div的左上角。根據transform-origin可以設定轉換(例如旋轉或者傾斜)的參考點,預設的參考點是(50%,50%),即中心。如下圖所示

 

2.改變大小的transform方法scale不接受百分比! 只能是用數字表示倍數,如transform:scale(2),

transform:scale(0.5)等等

3.skewX和skewY在2D參考系裡相當於具有傾斜的效果,傾斜時候變成高度不變的平行四邊形。但是skewX和skewY具有相反的差異,skewX是X軸方向不動,Y軸方向逆時針傾斜, skewY是Y軸不動,X軸方向向順時針傾斜,兩者連傾斜的方向都是不一樣的,具體可以參考

https://link.zhihu.com/?target=http%3A//www.lvyestudy.com/css3/css3_9.5.aspx

4.transition和animation在使用最明顯的區別是什麼?

  1. transition的使用是很受限制的,而animation非常靈活,在不借助JS的前提下,它只能在CSS的偽元素中起相應的作用,因為transition只能對發生變化的屬性起作用,而除了偽元素外,其他元素選擇器會出現後面的選擇器覆蓋前面選擇器屬性的現象,到最後屬性只有一個值,怎麼實現過渡呢?當然就不可以了。

  2. 在不借助JS的前提下,transition只能來一遍,而animation可以指定次數:1次,2次或無數次(指定infinite表示無限次數),還可以指定方向(altertive,表示播放結束後倒退播放)

  3. 甚至animation還可以通過百分比指定每一階段的細節變化,這一點transition就做不到了

本文完

 

知乎主頁和專欄

知乎主頁:https://www.zhihu.com/people/peng-hu-wan-56/activities

知乎專欄:  https://zhuanlan.zhihu.com/c_135367198

&n