css揭祕筆記——視覺效果

投影

知識點css

box-shadow: <offset-x> <offset-y> <blur-radius> <spread-radius> <color> [inset]?

注意:app

  • 在元素正下方的投影被裁切掉了,是沒有的;而text-shadow不一樣,文字下方的投影不會被裁切。wordpress

  • box-shadow的第三個參數是模糊半徑,假如設置4px,則投影尺寸比元素自己大8px.函數

  • box-shadow第四個參數是擴張半徑,指定整數是擴大,負數爲縮小。字體

單側投影

box-shadow: 0 10px 8px -8px black;

圖片描述

鄰邊投影

box-shadow: 6px 6px 12px -6px black;

圖片描述

雙側投影

box-shadow沒法單獨指定水平或垂直方向上的放大或縮小,因此只能用兩層投影達到目的。flex

box-shadow: 6px 0 12px -6px black, -6px 0 12px -6px black;

圖片描述

不規則投影

box-shadow給矩形或用border-radius生成的形狀加投影很完美,但給除此以外的形狀加投影,就不太行了。好比:動畫

border:10px dashed orange; 
box-shadow: 2px 2px 3px rgba(0,0,0,.5);

圖片描述

能夠使用css新屬性濾鏡filter,使用一些函數,如blur()、grayscale()、drop-shadow()等等,就能夠達到想要的效果。drop-shadow()的參數除了沒有擴張半徑和關鍵字inset,其餘和box-shadow同樣,但它不支持逗號分隔的多層投影語法。url

border:10px dashed orange; 
filter: drop-shadow(2px 2px 3px rgba(0,0,0,.5));

圖片描述

background: linear-gradient(45deg, transparent 20px, orange 0) left bottom /50%,
    linear-gradient(-45deg, transparent 20px, orange 0) right bottom /50%,
    linear-gradient(135deg, transparent 20px, orange 0) left top /50%,
    linear-gradient(-135deg, transparent 20px, orange 0) right top /50%;
background-repeat: no-repeat;
filter: drop-shadow(2px 2px 5px rgba(0,0,0,.5));

圖片描述

.talkbox{
    background-color: orange;
    border-radius: 20px;
    position: relative;
    filter: drop-shadow(2px 2px 3px rgba(0,0,0,.5));
}
.talkbox::after{
    content: '';
    display: block;
    box-sizing: border-box;
    width: 50px;
    height: 50px;
    border-left: 25px solid orange;
    border-top: 25px solid transparent;
    border-bottom: 25px solid transparent;
    position: absolute;
    top: 25%;
    left: 100%;
}

圖片描述

須要注意的是,任何非透明的部分都會被drop-shadow()打上投影。(這並非一種很好的體驗)spa

color: orange; border: 10px solid; 
text-shadow: 2px 2px yellowgreen; 
filter: drop-shadow(2px 2px 2px black);

圖片描述

染色效果

使用filter給圖片添加濾鏡效果。主要用到了sepia()saturate()hue-rotate()這些函數。3d

原圖
圖片描述

sepia() 降飽和度的橙黃色染色效果
圖片描述

saturate() 提高飽和度
圖片描述

hue-rotate() 把每一個像素的色相進行偏移,偏到粉色
圖片描述

還能夠加過分動畫,最終的代碼是

.filter-img{
    transition: .5s filter;
    filter: sepia(.5) saturate(4) hue-rotate(295deg);
 }

 .filter-img:hover,
 .filter-img:focus{
    filter: none;
 }

混合模式的方案

爲了不上面那種濾鏡方式的褪色和不天然的效果,還能夠使用「混合模式」,這種方式控制了上層元素的顏色和下層顏色進行混合的方式。實現染色效果的混合模式是luminosity,它會保留上層元素的hsl高亮信息,並從它的下層吸收色相和飽和度信息。

具體還能夠分爲兩種方式。
方式一:

<div style="background: hsl(335, 100%, 50%);">
    <img style="mix-blend-mode: luminosity;" src="./image/flower.jpg" alt="">
</div>

圖片描述

方式二:

<div class="tinted-img"></div>

.tinted-img{
    background: url(./image/flower.jpg);
    width: 300px; height: 300px; 
    background-size: cover; 
    background-color: hsl(335, 100%, 50%); 
    background-blend-mode: luminosity; 
    transition: .5s background-color;
}

.tinted-img:hover{
    background-color: transparent;
}

圖片描述

這裏須要說明一下,混合模式不像濾鏡同樣可動畫。使用background-blend-mode屬性可讓每層背景跟它的下層背景進行混合。當咱們只有一個背景圖像及一個透明背景色時,就不會有任何混合效果。因此動畫能夠在這個原理上進行設置。

毛玻璃效果

場景:背景是花哨的圖片,在文字下面使用半透明顏色保證文本的可讀性。

<div class="wrapper">
    <div class="main">
        <p> Lorem ipsum dolor sit amet...</p>
    </div>
</div>

失敗案例一:

.wrapper{
    background: url(./image/flower.jpg) 0 / cover;
}
.main{
    background: hsla(0, 0%, 100%, .3);
}

圖片描述

字體不清晰,調高透明度的值:

圖片描述
不太美觀。。。

失敗案例二:
使用blur()濾鏡。

.main{
    filter: blur(2px);
}

圖片描述
(⊙o⊙)… 連字體都模糊了。

解決方案:
按照以前提到過的「平行四邊形」的方案,爲僞元素設置模糊濾鏡,而不會影響文本。

.wrapper{
    width: 600px; height:300px; 
    background: url(./image/flower.jpg) 0 / cover;
    display: flex;
    justify-content: center;
    align-items: center;
}
.main{
    width: 70%;
    height: 65%;
    padding: 1em;
    font-size: 1.2em;
    background: hsla(0, 0%, 100%, .3);
    position: relative;
    z-index: 1; /*定位元素z-index不爲auto時,會建立層疊上下文*/
    overflow: hidden;
}
.main::before{
    content: '';
    position: absolute;
    top: 0; right: 0; bottom: 0; left: 0;
    background: url(./image/flower.jpg) 0 / cover;
    filter: blur(20px);
    z-index: -1;/*負的z-index會降低到其所在的層級上下文的背景之上,在這裏也就是.main元素的背景之上,文本如下。*/
    margin:-30px; /*因爲邊緣的模糊效果會按模糊半徑的長度削減,因此要將模糊元素擴展出去,同時父元素要對延伸出去的部分hidden*/
}

圖片描述

效果出來了,可是須要說明一點,就是層疊順序的問題,若是直接在僞元素設置z-index爲0的話,它會直接跑到最外層背景顏色下方,因此這個層疊順序很複雜,能夠參考下文:
深刻理解CSS中的層疊上下文和層疊順序

看了文章發現,不少屬性均可以建立層疊上下文,如display:flexfiltermix-blend-mode等等。

折角效果

45°折角

background: #58a; /*回退樣式*/
background: 
linear-gradient(-135deg, transparent 50%, rgba(0,0,0,.4) 0) no-repeat 100% 0 / 2em 2em,
linear-gradient(-135deg, transparent 1.5em, #58a 0);

注意,1.5em是經過三角形計算獲得,√2em取整爲1.5。

圖片描述

其餘角度折角

每一個角度都須要複雜的計算,這裏以30°爲例。非45°折角和45°折角不一樣的是,反折過來的角是不同的。因此實現思路就不一樣了。使用僞元素模擬折角,計算獲得的長寬和背景切角相反;以右下角爲中心逆時針旋轉30°;再向上移動一段距離(要調動初中幾何的功底了),就能夠了;最後加點裝飾更真實。

.note{
    background: #58a; 
       background:linear-gradient(-150deg, transparent 1.5em, #58a 0);
    position: relative;
    /*裝飾*/
    border-radius: .5em;
}
.note::before{
    content: "";
    width: 1.73em;
    height: 3em;
    position: absolute;
    top: 0;
    right: 0;
    background: linear-gradient(to left bottom, transparent 50%, rgba(0,0,0,.2) 0, rgba(0,0,0,.4));
    transform-origin: bottom right;
    transform: translateY(-1.3em) rotate(-30deg); /*注意:先平移再旋轉和先旋轉再平移效果是不同的!*/
    /*裝飾*/
    border-bottom-left-radius: inherit;
    box-shadow: -.2em .2em .3em -.1em rgba(0,0,0,.15);
}

代碼不夠DRY,只能使用預處理器的mixin了。

圖片描述

相關文章
相關標籤/搜索