1. 程式人生 > >CSS3 入門詳解(一)

CSS3 入門詳解(一)

image

前言

如同人類的的進化一樣,CSS3CSS2的“進化”版本,在CSS2基礎上,增強或新增了許多特性,彌補了CSS2的眾多不足之處,使得Web開發變得更為高效和便捷。

1.選擇器

CSS3新增了許多靈活查詢元素的方法,極大的提高了查詢元素的效率和精準度。CSS3選擇器與jQuery中所提供的絕大部分選擇器相容。

1.1 屬性選擇器

屬性選擇器就是通過屬性來選擇元素。
選擇器 含義
[attr] 存在attr屬性即可
[attr=val] 屬性值完全等於val
[attr*=val] 屬性值裡包含val字元並且在“任意”位置
[attr^=val] 屬性值裡包含val
字元並且在“開始”位置
[attr$=val] 屬性值裡包含val字元並且在“結束”位置

1、[attr]

<style>
    /* 所有擁有class屬性的標籤,新增color樣式 */
    [class]{
        color: #333;
    }
</style>

2、[attr=val]

<style>
    /* 所有擁有class屬性全等於“one”的標籤,新增color樣式 */
    [class = "one"]{
        color: #333;
    }
</style>

3、[attr*=val]

<style>
    /* class屬性的值裡面包含“one”的標籤,新增color樣式 */
    [attr*="one"]{
        color: #333;
    }
</style>

4、[attr^=val]

<style>
    /* class屬性的值以“one”開始的標籤,新增color樣式 */
    [attr ^= "one"]{
        color: #333;
    }
</style>

5、[attr$=val]

<style>
    /* class屬性的值以“one”結束的標籤,新增color樣式 */
    [attr $= "one"]{
        color: #333;
    }
</style>

1.2 偽類選擇器

除了以前介紹的的:link:active:visited:hoverCSS3又新增了其它的偽類選擇器。

1、結構(位置)偽類

選擇器 含義
:first-child 其父元素的第1個子元素
:last-child 其父元素的最後1個子元素
:nth-child(n) 其父元素的第n個子元素
:nth-last-child(n) 其父元素的第n個子元素(倒著數)

2、空偽類

:empty選中沒有任何子節點的元素
<style>
   div:empty {   /* 沒有子元素的div元素 */
        width: 100px;
        height: 100px;
        background-color: pink;
    }
</style>

<!-- css 樣式不起作用 -->
<div class="one">阿斯蒂芬</div>   

<!-- css樣式不起作用 -->
<div>
    <p></p>
</div>

<!-- css樣式生效 -->
<div></div>

3、目標偽類

:target結合錨點進行使用,處於當前錨點的元素會被選中;
<style type="text/css">
    /* 使用錨鏈接指向當前標籤的時候 */
    .one:target {
        background-color: pink;
        font-size: 30px;
    }
</style>

<a href="#hh">找笑臉去</a>
<p>阿斯頓發撒旦法撒打發放大法的撒雙方都</p>
<p>阿斯頓發撒旦法撒打發放大法的撒雙方都</p>
<p>阿斯頓發撒旦法撒打發放大法的撒雙方都</p>
<p>阿斯頓發撒旦法撒打發放大法的撒雙方都</p>
<p>阿斯頓發撒旦法撒打發放大法的撒雙方都</p>
<p id="hh" class="one">阿斯頓發撒旦法撒打發放大法的撒雙方都</p>
<p>阿斯頓發撒旦法撒打發放大法的撒雙方都</p>
<p>阿斯頓發撒旦法撒打發放大法的撒雙方都</p>
<p>阿斯頓發撒旦法撒打發放大法的撒雙方都</p>
<p>阿斯頓發撒旦法撒打發放大法的撒雙方都</p>
<p>阿斯頓發撒旦法撒打發放大法的撒雙方都</p>
<p>阿斯頓發撒旦法撒打發放大法的撒雙方都</p>
<p>阿斯頓發撒旦法撒打發放大法的撒雙方都</p>

4、排除偽類

:not(selector)selector(任意選擇器)外的元素會被選中;
<style>
    /* 除了類名是“.not”的div元素 */
    div:not(.one) {
        width: 100px;
        height: 100px;
        background-color: pink;
    }
</style>

<!-- css樣式不生效 -->
<div class="one"></div>

<!-- css樣式生效 -->
<p></p>

<!-- css樣式生效 -->
<div></div>

1.3 偽元素選擇器

  • 1、::first-letter文字的第一個單詞或字(如中文、日文、韓文等)
  • 2、::first-line 文字第一行;
  • 3、::selection 可改變選中文字的樣式;
  • 4、::before::after

示例程式碼:偽元素實現橫豎分割線

<style type="text/css">
    * {
         margin: 0;
         padding: 0;
         list-style: none;
    }
    .box {
         width: 300px;
         height: 200px;
         background-color: pink;
         margin: 50px auto;
    }
    .box li {
         width: 100px;
         height: 100px;
         float: left;
         background-color: #555;
         position: relative;
         overflow: hidden;
    }

    li:before {
         content: "";
         display: block;
         width: 90px;
         height: 1px;
         background-color: #ccc;
         position: absolute;
         top: 97px;
         left: 5px;
    }
    li:after {
         content: "";
         display: block;
         width: 1px;
         height: 90px;
         background-color: #ccc;
         position: absolute;
         left: 0px;
         top: 4px;
    }
    li:nth-child(1):after,li:nth-child(4):after {
         display: none;
    }

    li:nth-last-child(-n+3):before {
         display: none;
    }
</style>

<div class="box">
    <ul>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
    </ul>
</div>

效果圖:

image

:after:before在舊版本里是偽元素,CSS3的規範裡“:”用來表示偽類,“::”用來表示偽元素,但是在高版本瀏覽器下:after:before會被自動識別為::after::before,這樣做的目的是用來做相容處理。

2. 顏色

新增了RGBAHSLA模式,其中的A表示透明度,即可以設定顏色值的透明度,相較opacity,它們不具有繼承性,即不會影響子元素的透明度。

2.1 RGBA

RedGreenBlueAlphaRGBARGB取值範圍0~255
<style>
    #box{
        width:100px;
        height:100px;
        background: rgba(200,200,200,.5);
    }
</style>

<div id="box"></div>

2.2 HSLA

  • H 色調 取值範圍0~3600/360表示紅色、120表示綠色、240表示藍色
  • S 飽和度 取值範圍0%~100%
  • L 亮度 取值範圍0%~100%
  • A 透明度 取值範圍0~1
<style>
    #box{
        width:100px;
        height:100px;
        background: hsla(200,50%,50%,.5);
    }
</style>

<div id="box"></div>

2.3 關於 CSS 的透明度

Alphaopacity的區別主要就是,opacity具有繼承性,父盒子設定該屬性,下面所有的子元素都會繼承該屬性。

transparent不可調節透明度,始終完全透明。

3. 文字陰影

text-shadow,可分別設定偏移量、模糊度、顏色(可設透明度)。

如:

text-shadow: 2px 2px 2px #CCC;
  • 1、水平偏移量 正值向右 負值向左;
  • 2、垂直偏移量 正值向下 負值向上;
  • 3、模糊度是不能為負值;
  • 4、陰影顏色。

示例程式碼:文字浮雕

<style>
     html,body {
          margin: 0;
          padding: 0;
          width: 100%;
          height: 100%;
          background-color: #999;
          font-size: 50px;
          text-align: center;
          line-height: 260px;
          color: #999;
     }
        
    .one {
         text-shadow: -1px -1px 1px #fff,1px 1px 1px #000;
    }

    .two {
         text-shadow: -1px -1px 1px #000,1px 1px 1px #fff;
    }
</style>

<div class="one">我是凸起文字</div>
<div class="two">我是凹下去的文字</div>

效果圖:

image

4. 盒模型

CSS3中可以通過box-sizing來指定盒模型,即可指定為content-boxborder-box,這樣我們計算盒子大小的方式就發生了改變。

可以分成兩種情況:

  • 1、box-sizing: border-box盒子大小為width
  • 2、box-sizing: content-box盒子大小為width + padding + border

注:上面的標註的width指的是CSS屬性裡設定的width: lengthcontent的值是會自動調整的。

示例程式碼:

<style type="text/css">
     .box {
          width: 316px;
          height: 170px;
          float: left;
          margin-left: 20px;
          box-sizing: border-box;
     }
     .box img {
          width: 100%;
          height: 100%;
     }

     .box:hover {
          border: 10px solid #00eeff;
     }
</style>

<div class="box">
   <img src="1.jpg" alt="">
</div>

<div class="box">
   <img src="1.jpg" alt="">
</div>

效果圖:

image

可以看出通過設定盒子模型後,雖然.box設定了邊框,但是整個box的盒子大小沒有改變。

5. 邊框

邊框中的邊框圓角、邊框陰影屬性,應用十分廣泛,相容性也相對較好,具有符合漸進增強原則的特徵。

5.1 邊框圓角

通過border-radius屬性,設定邊框圓角,圓角處理時,腦中要形成圓、圓心、橫軸、縱軸的概念,正圓是橢圓的一種特殊情況。

image

為了方便表述,我們將四個角標記成1234,如2代表右上角,CSS裡提供了border-radius來設定這些角橫縱軸半徑值。

分別設定橫縱軸半徑,以“/”進行分隔,遵循“1234”規則,“/”前面的1~4個用來設定橫軸半徑(分別對應橫軸1234位置),“/”後面1~4個引數用來設定縱軸半徑(分別對應縱軸1234位置 )。

<style type="text/css">
    .box {
        margin: 50px auto;
        width: 300px;
        height: 500px;
        border: 1px solid #ccc;
        border-radius: 10px 20px 50px 70px / 10px 20px 50px 70px;
    }
</style>

<div class="box"></div>

效果圖:

一般情況下,我們用不到這麼複雜的,除非特殊需求的時候。

image

支援簡寫模式,具體如下:

  • 1、border-radius: 10px;表示四個角的橫縱軸半徑都為10px
  • 2、border-radius: 10px 5px;表示13角橫縱軸半徑都為10px24角橫縱軸半徑為5px
  • 3、border-radius: 10px 5px 8px;表示1角模縱軸半徑都為10px24角橫縱軸半徑都為8px3角的橫縱軸半徑都為8px
  • 4、border-radius: 10px 8px 6px 4px;表示1角橫縱軸半徑都為10px,表示2角橫縱軸半徑都為8px,表示3角橫縱軸半徑都為6px,表示4角橫縱軸半徑都為6px

橢圓的畫法:

<style type="text/css">
    .box {
        margin: 50px auto;
        width: 300px;
        height: 500px;
        border: 1px solid #ccc;
        /* 當盒子長寬不一致時,圓角屬性 分別設定寬度的一半,以及長度的一半,即是橢圓 */
        /* 或者直接 border-radius:50%; */
        border-radius: 150px 250px;
    }
</style>

<div class="box"></div>

image

如果不想計算,直接設百分比:“50%”。

正圓的畫法:

<style type="text/css">
    .box {
        margin: 50px auto;
        width: 200px;
        height: 200px;
        border: 1px solid #ccc;
        /* 當盒子長寬相等時,圓角屬性分別設定寬度的一半,以及長度的一半,即是正圓 */
        /* 或者直接 border-radius:50%; */
        border-radius: 100px;
    }
</style>

<div class="box"></div>

image

示例程式碼:邊框圓角合集

<style>
    * {
          margin: 0;
          padding: 0;
          list-style: none;
          background-color: wheat;
          overflow: hidden;
     }
    
     .box {
          width: 980px;
          height: 400px;
          background-color: #fff;
          margin: 50px auto;
     }
    
     .box li {
          float: left;
          width: 193px;
          height: 193px;
          background-color: #fff;
          margin:5px;
          box-shadow: 2px 3px 5px #aaa;
     }
    
     li:first-child:after {
          content: "";
          height: 130px;
          width: 130px;
          margin: 30px auto;
          display: block;
          border: 1px solid orangered;
          border-radius: 50%;
     }
     li:nth-child(2):after {
          content: "";
          display: block;
          height: 130px;
          width: 130px;
          border: 1px solid orangered;
          margin: 30px auto;
          border-radius: 65px 65px 0px 0px;
     }
    
     li:nth-child(3):after {
          content: "";
          display: block;
          width: 130px;
          height: 65px;
          border: 1px solid orangered;
          margin: 50px auto;
          border-radius: 65px 65px 0px 0px;
     }
    
     li:nth-child(4):after {
          content: "";
          display: block;
          width: 130px;
          height: 130px;
          border: 1px solid orangered;
          margin: 20px auto;
          border-radius: 65px 0px 0px 0px;
     }
    
     li:nth-child(5):after {
          content: "";
          width: 130px;
          height: 65px;
          display: block;
          border: 1px solid orangered;
          border-radius: 50%;
          margin: 50px auto;
     }
     li:nth-child(6):after{
          content: "";
          height: 130px;
          width: 65px;
          display: block;
          border: 1px solid orangered;
          border-radius: 50%;
          margin: 20px auto;
     }
    
     li:nth-child(7):after {
          content: "";
          height: 130px;
          width: 130px;
          display: block;
          border: 1px solid orangered;
          margin: 20px auto;
          border-radius: 135px 0px 0px 0px;
     }
    
     li:nth-child(8):after {
          content: "";
          width: 135px;
          height: 30px;
          display: block;
          margin: 30px auto;
          border: 1px solid orangered;
          border-radius: 65px 65px 0px 0px / 30px 30px 0px 0px;
     }
</style>

<div class="box">
    <ul>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
    </ul>
</div>

效果圖:

image

5.2 邊框陰影

box-shadow,與文字陰影類似,可分別設定盒子陰影偏移量、模糊度、顏色(可設透明度)。

如:

box-shadow: 5px 5px 5px #CCC
  • 1、水平偏移量 正值向右 負值向左;
  • 2、垂直偏移量 正值向下 負值向上;
  • 3、模糊度是不能為負值;
  • 4、inset可以設定內陰影;

注:設定邊框陰影不會改變盒子的大小,即不會影響其兄弟元素的佈局。可以設定多重邊框陰影,實現更好的效果,增強立體感,符合漸進增強,實際開發中可以大膽使用。

示例程式碼:

<style>
    .box {
        width: 200px;
        height: 200px;
        margin: 50px auto;
        border: 1px dashed #000;
        box-shadow: 2px 3px 4px rgba(0, 247, 255, 0.452),inset 5px 6px 7px rgba(255, 0, 140, 0.562);
    }
</style>

<div class="box"></div>

效果圖:

image

我們通過上圖可以看到,虛線是盒子的位置,粉色陰影是inset屬性設定的,所以是內陰影,淺藍色是直接設定的外陰影,效果一目瞭然。

6. 背景

背景在CSS3中也得到很大程度的增強,比如背景圖片尺寸、背景裁切區域、背景定位參照點、多重背景等。

6.1 background-size

通過background-size設定背景圖片的尺寸,就像我們設定img的尺寸一樣,在移動Web開發中做螢幕適配應用非常廣泛。

其引數設定如下:

  • 可以設定長度單位(px)或百分比(設定百分比時,參照盒子的寬高)
  • 設定為cover時,會自動調整縮放比例,保證圖片始終填充滿背景區域,如有溢位部分則會被隱藏。
  • 設定為contain會自動調整縮放比例,保證圖片始終完整顯示在背景區域。

6.2 background-origin

通過background-origin可以設定背景圖片定位(background-position)的參照原點。

其引數設定如下:

  • border-box以邊框做為參考原點;
  • padding-box以內邊距做為參考原點;
  • content-box以內容區做為參考點;

示例程式碼:

<style type="text/css">
    .box1,.box2,.box3 {
        width: 200px;
        height: 200px;
        display: inline-block;
        margin: 50px 30px;
        border: 10px dashed aquamarine;
        padding: 10px;
        background-image: url(bg.jpg);
        background-repeat: no-repeat;
    }
    .box1{
        background-origin: padding-box;
    }
    .box2{
        background-origin: content-box;
    }
    .box3{
        background-origin: border-box;
    }
</style>


<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>

效果圖:

image

6.3 background-clip

通過background-clip,可以設定對背景區域進行裁切,即改變背景區域的大小。

其引數設定如下:

  • border-box裁切邊框以內為背景區域;
  • padding-box裁切內邊距以內為背景區域;
  • content-box裁切內容區做為背景區域;

image

6.4 多背景

以逗號分隔可以設定多背景,可用於自適應佈局。在一個盒子裡可以設定多個背景圖片,通過背景定位的功能將兩張圖片組裝起來。

示例程式碼:

<style type="text/css">
    .box {
        width: 320px;
        height: 410px;
        margin: 50px auto;
        background: url(head.jpg) no-repeat left top,
                      url(foot.jpg) no-repeat left bottom; 
        background-size: contain;
        background-color: #ccc;
    }
</style>

<div class="box"></div>

效果圖:

image

從效果圖中我們可以看到,在盒子裡面設定了兩張背景圖,分別是上面一部分,下面一部分。這裡故意給盒子高度拉長了一點,並且設定了一個灰色的背景,為的就是大家能夠清楚的看到上下兩部分的背景圖。

7. 漸變

漸變是CSS3當中比較豐富多彩的一個特性,通過漸變我們可以實現許多炫麗的效果,有效的減少圖片的使用數量,並且具有很強的適應性和可擴充套件性。

7.1 線性漸變

linear-gradient線性漸變指沿著某條直線朝一個方向產生漸變效果。

1、必要的元素:

藉助Photoshop總結得出線性漸變的必要元素
  • a、方向
  • b、起始色
  • c、終止色
  • d、漸變距離

2、關於方向

通過具體的方位詞指定
  • to left
  • to right
  • to top
  • to bottom
通過角度改變漸變的方向
  • ,從下往上漸變
  • 90°,從左向右漸變

示例程式碼:

<style type="text/css">
    .box {
        width: 400px;
        height: 150px;
        margin: 100px auto;
        /* 線性漸變 */
        background-image: linear-gradient(
            /*漸變的方向*/
            45deg,
            /*漸變開始的顏色*/
            #88f5ea,
            /*漸變結束的顏色*/
            #d36be7
        );
    }
</style>

<div class="box"></div>

效果圖:

image

3、漸變範圍

如果不設定範圍,預設漸變的範圍是父盒子的寬度,如果通過background-size設定寬度的話,漸變範圍即為設定的寬度。
<style>
    .box {
        width: 500px;
        height: 100px;
        margin: 100px auto;
        background-image: linear-gradient(
            135deg,
            yellow 20%,
            black 20%,
            black 40%,
            yellow 40%,
            yellow 60%,
            black 60%,
            black 80%,
            yellow 80%,
            yellow 
        );
        background-size: 66px 100px;
    }
</style>

<div class="box"></div>

效果圖:

image

7.2 徑向漸變

radial-gradient徑向漸變指從一箇中心點開始沿著四周產生漸變效果。

1、必要的元素:

  • a、輻射範圍即圓半徑
  • b、中心點 即圓的中心
  • c、漸變起始色
  • d、漸變終止色
  • e、漸變範圍

2、關於中心點

中心位置參照的是盒子的左上角,例如:
<style>
    #div{
        width:200px;
        height:200px;
        background: radial-gradient(
            /* 100px是漸變輻射的範圍 0 0 指的是圓心在盒子的左上角 */
            100px at 0 0,
            /*漸變起始色*/
            orange,
            /*漸變終止色*/
            #ff4500
        )
    }
</style>

<div id="box"></div>

image

示例程式碼:映象漸變畫個球

<style type="text/css">
    * {
        margin: 0;
        padding: 0;
    }

    html,body {
        width: 100%;
        height: 100%;
        background-color: #ccc;
    }

    .box {
         width: 400px;
         height: 400px;
         background-color: #fff;
         margin: 50px auto;
         border-radius: 50%;

         background-image: radial-gradient(
               300px at 100px 100px,
               rgba(0,0,0,.1),
               rgba(0,0,0,.8)
         );
    }
</style>

<div class="box"></div>

效果圖:

image

8. 過渡

過渡是CSS3中具有顛覆性的特徵之一,可以實現元素不同狀態間的平滑過渡(補間動畫),經常用來製作動畫效果。

8.1 幀動畫

通過一幀一幀的畫面按照固定順序和速度播放,如電影膠片。

image

示例程式碼:

<!--
    baidu.png這個背景圖由64張圖片橫向組成,我們通過動態改變圖片的位置,實現動畫效果
-->
<style>
    body {
        margin: 0;
        padding: 0;
        background-color: #F7F7F7;
    }

    .logo {
        width: 270px;
        height: 129px;
        margin: 100px auto;
        background-image: url(./baidu.png);
        background-position: 0 0;
    }
</style>

<div class="logo"></div>
<script>
    var logo = document.querySelector('.logo');

    var offset = -270;
    var n = 0;
    setInterval(function () {
        n++;
        logo.style.backgroundPosition = offset * n + 'px 0px';
        if(n >= 64) n = 0;
    },100);
</script>

效果圖:

image

這裡不做詳細瞭解,主要是為了區分與補間動畫的區別。

8.2 補間動畫

自動完成從起始狀態到終止狀態的的過渡。

語法:transition

當前元素只要有“屬性”發生變化時,可以平滑的進行過渡,並不僅僅侷限於hover狀態。
  • transition-property設定過渡屬性
/*設定哪些屬性要參加到動畫效果中*/
transition-property: all;
  • transition-duration設定動畫過渡執行時間
transition-duration: 2s;
  • transition-timing-function設定過渡速度型別
transition-timing-function:linear; 

/* ease| ease-in | ease-out | ease-in-out | linear; */
  • transition-delay設定過渡延時
/*1s後,過渡動畫開始過渡*/
transition-delay: 1s;

連寫:

/*          屬性  執行時間 延時時間 過渡型別*/
transition: all   2s       1s       linear;

示例程式碼:

<style type="text/css">
    .box {
        width: 250px;
        height: 250px;
        background-color: pink;
        margin: 100px auto;
        transition: all 2s 1s linear;
    }
    
    .box:hover {
        width: 200px;
        height: 200px;
        border-radius:50%;
        background-color: rgb(25, 221, 247);
    }
</style>

<div class="box"></div>

效果圖:

image

我們可以看到,觸發hover事件的時候延遲1s後開始執行動畫。

示例程式碼:過渡的實際應用

<style type="text/css">
    html,body {
         margin: 0;
         padding: 0;
         width: 100%;
         height: 100%;
    }

    .box {
         width: 100%;
         height: 100%;
         background-color: #eee;
    }

    .l_box {
         float: left;
         width: 234px;
         height: 300px;
         margin: 100px 50px;
         cursor: pointer;
         transition: all 0.5s linear;
    }

    .l_box:hover {
        box-shadow: -2px -2px 20px #777;
        margin-top: 90px;
    }

    .r_box {
         width: 234px;
         height: 300px;
         float: left;
         margin: 100px 0px;
         background-color: #fff;
         text-align: center;
         position: relative;
    }

    .cover {
        position: absolute;
        bottom: 0;
        height: 0px;
        width: 234px;
        background-color: orange;
        transition: all 1s linear;
    }

    .r_box:hover .cover {
        height: 100px;
    }
</style>

<div class="box">
    <div class="l_box">
        <img src="img/1.jpg" alt="">
    </div>
    <div class="r_box">
        <img src="img/2.jpg" alt="">
        <div class="cover"></div>
    </div>
</div>

效果圖:

image

9. 2D轉換

轉換(transform)是CSS3中具有顛覆性的特徵之一,可以實現元素的位移、旋轉、變形、縮放,甚至支援矩陣方式,配合即將學習的過渡和動畫知識,可以取代大量之前只能靠Flash才可以實現的效果。

9.1 位移

CSS3中,通過translate屬性對元素進行位移。

移動translate(x, y)可以改變元素的位置,xy可為負值;

  • a、移動位置相當於自身原來位置
  • b、y軸正方向朝下
  • c、除了可以畫素值,也可以是百分比,相對於自身的寬度或高度
transform: translate(100px, 30px);

示例程式碼

<style type="text/css">
    .line {
        height: 200px;
        background-color: pink;
    }
    
    .box {
        width: 100px;
        height: 100px;
        background-color: rgb(30, 230, 245);
        transition: all 1s linear;
    }
    
    .line:hover .box {
        /* 位移 */
        transform: translate(100px, 30px);
    }
</style>

<div class="line">
    <div class="box"></div>
</div>

效果圖:

image

我們可以看到,滑鼠移上去之後,藍色盒子,分別向左和向下移動了一段距離。

9.2 縮放

縮放scale(x, y)可以對元素進行水平和垂直方向的縮放,xy的取值可為小數;
/*寬和高都放大1倍*/
transform: scale(1.5);

示例程式碼:

<style type="text/css">
    .box {
        width: 200px;
        height: 200px;
        background-color: pink;
        margin: 50px auto;
        transition: all 2s linear;
    }

    .box:hover {
        /* 縮放 */
        transform: scale(0.5);
    }
</style>

<div class="box"></div>

效果圖:

image

9.3 旋轉

旋轉rotate(deg)可以對元素進行旋轉,正值為順時針,負值為逆時針;
  • a、當元素旋轉以後,座標軸也跟著發生的轉變
  • b、調整順序可以解決,把旋轉放到最後
/* 順時針旋轉 90度 */
transform: rotate(90deg);

示例程式碼:

<style type="text/css">
    .box {
        width: 200px;
        height: 200px;
        background-color: #0df3cd;
        margin: 100px auto;
        transition: all 2s linear;
    }
    
    .box:hover {
        transform: rotate(-90deg);
    }
</style>

<div class="box"></div>

效果圖:

image

旋轉原點:

預設情況下,旋轉是按照元素的中心點旋轉的,但是我們可以手動設定元素旋轉的中心點。
transform-origin: 30px 40px;

示例程式碼:

<style type="text/css">
    .box {
        width: 150px;
        height: 150px;
        background-color: cyan;
        margin: 100px auto;
        transition: all 1s linear;
        /* 設定旋轉原點位置 */
        /* transform-origin: left top; */
        transform-origin: 30px 40px;
    }
    
    .box:hover {
        transform: rotate(90deg);
    }
</style>

<div class="box"></div>

效果圖:

image

示例程式碼:撲克牌

<style type="text/css">
    * {
        margin: 0;
        padding: 0;
    }

    .box {
         width: 310px;
         height: 438px;
         border: 1px solid #ccc;
         margin: 50px auto;
         position: relative;
    }

    .box img {
         position: absolute;
         transform-origin:bottom;
         transition: all 2s linear;
    }

    .box:hover img:nth-child(1) {
         transform: rotate(10deg);
    }
    .box:hover img:nth-child(2) {
         transform: rotate(20deg);
    }
    .box:hover img:nth-child(3) {
         transform: rotate(30deg);
    }
    .box:hover img:nth-child(4) {
         transform: rotate(40deg);
    }
    .box:hover img:nth-child(5) {
         transform: rotate(50deg);
    }
    .box:hover img:nth-child(6) {
         transform: rotate(60deg);
    }
</style>


<div class="box">
      <img src="img/pk1.png" alt="">
      <img src="img/pk1.png" alt="">
      <img src="img/pk1.png" alt="">
      <img src="img/pk1.png" alt="">
      <img src="img/pk1.png" alt="">
      <img src="img/pk1.png" alt="">
</div>

效果圖:

image

9.4 傾斜

傾斜skew(deg, deg)可以使元素按一定的角度進行傾斜,可為負值,第二個引數不寫預設為0
transform: skew(30deg,30deg);

示例程式碼:

<style type="text/css">
    .box {
        width: 150px;
        height: 150px;
        background-color: cyan;
        margin: 100px auto;
        transition: all 2s linear;
    }
    
    .box:hover {
        /* 傾斜 */
        transform: skew(30deg, 30deg);
    }
</style>

<div class="box"></div>

效果圖:

image

9.5 矩陣

矩陣matrix()把所有的2D轉換組合到一起,需要6個引數。transform-origin可以調整元素轉換的原點,但是對於transform: translate(x,y)沒有影響。我們可以同時使用多個轉換,其格式為:transform: translate() rotate() scale() ...等,其順序會影轉換的效果。

詳細可參見

10. 3D 轉換

10.1 3D 座標軸

XYZ分別表示空間的3個維度,三條軸互相垂直。如下圖:

image

網格狀的正方形,可以想象成是我們的電腦桌面2D平面。

在 3D 轉換中,前面 2D 轉換的屬性在這都可以使用:

  • 位移
transform:translate(100px,100px,100px);
  • 旋轉
transform:rotate(30deg,30deg,30deg);
  • 縮放
transform:scale(2,0.5,0.5);
  • 傾斜
transform:skew(30deg,30deg,30deg);

3D轉換中,一定要加上一個透視屬性,才能在電腦2D平面中顯示出3D的效果,透視屬性請看下章。

10.2 透視(perspective)

電腦顯示屏是一個2D平面,影象之所以具有立體感(3D效果),其實只是一種視覺呈現,通過透視可以實現此目的。perspective通過透視產生的3D效果,只是視覺呈現而已,並不是真正的3d立體的盒子;就是近大遠小的效果。

透視的概念其實很簡單,就是“近大遠小”。

image

舉個例子:

2D轉換的時候,我們知道一個translate屬性,他分別可以設定向左向右或者向上向下平移,但是卻不能向裡面或外面平移。
<style>
    .box{
        width: 550px;
        height: 150px;
        margin: 100px auto;
        padding: 6px;
        border: 1px dashed #ccc;
    }
    .box li{
        float: left;
        width: 150px;
        height: 150px;
        padding: 0;
        list-style: none;
        margin-right: 50px;
        transition: all 0.5s linear;
        
    }
    .box li:first-child{
        background: salmon;
    }
    .box li:nth-child(2){
        background: deepskyblue;
    }
    .box li:last-child{
        background: khaki;
        margin-right: 0px;
    }
    /* 第一個盒子向X軸的負方向移動100px */
    .box li:first-child:hover{
        transform: translateX(-100px);
    }
    /* 第二個盒子向Y軸的正方向移動100px */
    .box li:nth-child(2):hover{
        transform: translateY(100px);
    }
    /* 第三個盒子Z軸的負方向移動100px */
    .box li:last-child:hover{
        transform: translateZ(-100px);
    }
</style>

<ul class="box">
    <li></li>
    <li></li>
    <li></li>
</ul>

效果圖:

image

沒有加透視屬性的時候,因為z軸是垂直電腦平面射出來的,translateZ是看不出效果的。

如何設定透視屬性?

給當前元素的直接父元素新增perspective: 800px;透視屬性,注意這個值可以是隨意的,但是最佳展現距離是600px~1000px
<style>
    .box{
        width: 550px;
        height: 150px;
        margin: 100px auto;
        padding: 6px;
        border: 1px dashed #ccc;
        /* 給變換的 li 的直接父元素 ul 新增透視屬性 perspective */
        perspective: 800px;
    }
    .box li{
        float: left;
        width: 150px;
        height: 150px;
        padding: 0;
        list-style: none;
        margin-right: 50px;
        transition: all 0.5s linear;
        
    }
    .box li:first-child{
        background: salmon;
    }
    .box li:nth-child(2){
        background: deepskyblue;
    }
    .box li:last-child{
        background: khaki;
        margin-right: 0px;
    }
    /* 第一個盒子向X軸的負方向移動100px */
    .box li:first-child:hover{
        transform: translateX(-100px);
    }
    /* 第二個盒子向Y軸的正方向移動100px */
    .box li:nth-child(2):hover{
        transform: translateY(100px);
    }
    /* 第三個盒子Z軸的負方向移動100px */
    .box li:last-child:hover{
        transform: translateZ(-100px);
    }
</style>

<ul class="box">
    <li></li>
    <li></li>
    <li></li>
</ul>

效果圖:

image

如圖所示,在ul加上透視屬性後,第三個盒子向著z軸的負方向移動了100px

透視可以將一個2D平面,在轉換的過程當中,呈現3D效果。(沒有perspective,便“沒有”Z軸)並非任何情況下都需要透視效果。

10.3 3D呈現(transform-style)

什麼是3D呈現呢?不要與前面的透視搞混,透視只能使一個物體呈現近大遠小的狀態,不能呈現出一個立體感的東西,比如我在頁面上用六個面組成一個正方形,通過透視你可能只能改變他的遠近距離,並不能讓他看起來像個立體的盒子,所以這裡需要用到另一個屬性:transform-style
transform-style: preserve-3d | flat
  • flat:所有子元素在2D平面呈現
  • preserve-3d:保留3D空間

必須設定在父元素身上並且父元素有轉換(就是有變形)並且子元素也得有轉換(變形)才能看得到效果。

1、示例程式碼:正方體

<style type="text/css">
    * {
         margin: 0;
         padding: 0;

    }

    .box {
         width: 200px;
         height: 200px;
         margin: 150px auto;

         position: relative;
        
         /* 透視 */
         /* perspective: 1000px; */

         /* 轉為立方體 */
         transform-style: preserve-3d;

         transform: rotateY(45deg) rotateX(30deg);
    }

    .box>div {
         position: absolute;
         width: 100%;
         height: 100%;
    }

    .left {
        background-color: pink;
        transform: rotateY(-90deg) translateZ(150px);
    }

    .right {
        background-color: green;
        transform: rotateY(90deg) translateZ(150px);
    }

    .top {
        background-color: orange;
        transform: rotateX(90deg) translateZ(150px);
    }

    .bottom {
        background-color: blue;
        transform: rotateX(-90deg) translateZ(150px);
    }

    .before {
        background-color: red;
        transform: translateZ(150px);
    }

    .back {
        background-color: greenyellow;
        transform: translateZ(-150px);
    }

</style>

<div class="box">
    <div class="left"></div>
    <div class="right"></div>
    <div class="top"></div>
    <div class="bottom"></div>
    <div class="before"></div>
    <div class="back"></div>
</div>

效果圖:

image

2、示例程式碼:3D 導航

<style type="text/css">
    
     * {
          margin: 0;
          padding: 0;
          list-style: none;
     }

     nav {
          width: 600px;
          height: 60px;
          line-height: 60px;
          margin: 200px auto;
     }

     li {
          height: 60px;
          width: 150px;
          float: left;
          position: relative;
          transform-style: preserve-3d;
          transition: all 0.5s ease-in;
     }

     span {
          position: absolute;
          width: 150px;
          height: 60px;
          display: block;
         color: #fff;
          text-align: center;
     }

     span:first-child{
          background-color: #ff287a;
         transform: rotateX(90deg) translateZ(30px);
     }

     span:last-child{
         transform: translateZ(30px);
         background-color: #00bdab;
     }

     li:hover {
          transform: rotateX(-90deg);
     }
</style>

<nav>
    <ul>
        <li>
            <span>Home</span>
            <span>主頁</span>
        </li>
        <li>
            <span>Menu</span>
            <span>選單</span>
        </li>
        <li>
            <span>Admin</span>
            <span>管理</span>
        </li>
        <li>
            <span>About</span>
            <span>關於我們</span>
        </li>
    </ul>
</nav>

效果圖:

image

10.4 3D呈現案例:3D輪播圖

1、普通版 3D 輪播圖

實現思路:

  • 通過CSS3transform-style: preserve-3d的概念,將檢視設定成3D展示模式;
  • 四張圖片,分別設定其繞著X軸旋轉的角度,分別對應四個立體面;
  • 將旋轉好的圖片沿著Z軸平移盒子寬度的一半;
  • 定義一個全域性變數num,用來記錄按鈕點選的次數,噹噹按動按鈕的時候,讓ul旋轉num*90°

示例程式碼:

<style>
    * {
        padding: 0;
        margin: 0;
        list-style-type: none;
    }
    
    .box {
        width: 960px;
        height: 540px;
        /* border: 5px solid #999; */
        margin: 150px auto;
    }
    
    .box ul {
        width: 960px;
        height: 540px;
        position: relative;
        transform-style: preserve-3d;
        transition: transform .6s;
    }
    
    .box ul li {
        width: 100%;
        height: 100%;
        position: absolute;
        left: 0;
        top: 0;
    }
    
    img {
        width: 100%;
        height: 100%;
    }
    
    .box ul li:nth-child(1) {
        transform: rotateX(90deg) translateZ(270px);
    }
    
    .box ul li:nth-child(2) {
        transform: rotateX(-90deg) translateZ(270px);
    }
    
    .box ul li:nth-child(3) {
        transform: rotateX(180deg) translateZ(270px);
    }
    
    .box ul li:nth-child(4) {
        transform: translateZ(270px);
    }
    
    .btn {
        width: 1080px;
        margin: 0 auto;
        position: relative;
        height: 0px;
        top: -470px;
    }
    
    .btn button {
        width: 40px;
        height: 80px;
        border-radius: 10px;
        background: rgba(0, 0, 0, 0.2);
        border: none;
        outline: none;
        font: 900 24px/80px '宋體';
        color: #fff;
    }
    
    .btn button:frist-child {
        float: left;
    }
    
    .btn button:last-child {
        /* border-radius: 0 10px 10px 0; */
        float: right;
    }
</style>

<div class="box">
    <ul>
        <li><img src="./imgs/1.jpg" alt=""></li>
        <li><img src="./imgs/2.jpg" alt=""></li>
        <li><img src="./imgs/3.jpg" alt=""></li>
        <li><img src="./imgs/4.jpg" alt=""></li>
    </ul>
</div>
<div class="btn">
    <button>&lt;</button>
    <button>&gt;</button>
</div>

<script type="text/javascript">
    var btn = document.querySelectorAll('button');
    var box = document.querySelector('.box');
    var _ul = box.querySelector('ul');
    var num = 0;

    // btn 獲取到的是一個偽陣列
    btn[1].onclick = function () {
        num++;
        _ul.style.transform = 'rotateX(' + num * 90 + 'deg)'
    }

    btn[0].onclick = function () {
        num--;
        _ul.style.transform = 'rotateX(' + num * 90 + 'deg)';
    }
</script>

效果圖:

image

2、切割版 3D 輪播圖

實現思路:

  • 結構上將之前定義好的ul重複四次;
  • 設定延時,整個動畫執行時間是0.8s,設定每一個ul延遲執行0.2s,即第一個延時0s,第二個延時0.2s,第三個延時0.4s,第四個延時0.6s
  • 其餘步驟同上,著重強調的是,相對於上面的案例,本案例給按鈕加了限制,監聽第一次所有的ul旋轉結束之後,按鈕才能再一次被點選。

示例程式碼:

<style>
    * {
        padding: 0;
        margin: 0;
        list-style-type: none;
    }
    
    .box {
        width: 960px;
        height: 540px;
        margin: 150px auto;
        display: flex;
    }
    
    .box ul {
        width: 960px;
        height: 540px;
        position: relative;
        transform-style: preserve-3d;
        transition: transform .8s;
    }
    
    .box ul li {
        width: 100%;
        height: 100%;
        position: absolute;
        left: 0;
        top: 0;
        overflow: hidden;
    }
    
    img {
        width: 960px;
        height: 540px;
    }
    
    /* 設定延時 */
    .box ul:nth-child(1) {
      transition-delay:0s;
    }
    .box ul:nth-child(2) {
      transition-delay:.2s;
    }
    .box ul:nth-child(3) {
      transition-delay:.4s;
    }
    .box ul:nth-child(4) {
      transition-delay:.6s;
    }
    
    /* 拼湊圖片 */
    .box ul:nth-child(2) img {
      margin-left: -240px;
    }
    .box ul:nth-child(3) img {
      margin-left: -480px;
    }
    .box ul:nth-child(4) img {
      margin-left: -720px;
    }
    
    .box ul li:nth-child(1) {
        transform: rotateX(90deg) translateZ(270px);
    }
    
    .box ul li:nth-child(2) {
        transform: rotateX(-90deg) translateZ(270px);
    }
    
    .box ul li:nth-child(3) {
        transform: rotateX(180deg) translateZ(270px);
    }
    
    .box ul li:nth-child(4) {
        transform: translateZ(270px);
    }
    
    .btn {
        width: 1080px;
        margin: 0 auto;
        position: relative;
        height: 0px;
        top: -470px;
    }
    
    .btn button {
        width: 40px;
        height: 80px;
        border-radius: 10px;
        background: rgba(0, 0, 0, 0.2);
        border: none;
        outline: none;
        font: 900 24px/80px '宋體';
        color: #fff;
    }
    
    .btn button:frist-child {
        float: left;
    }
    
    .btn button:last-child {
        /* border-radius: 0 10px 10px 0; */
        float: right;
    }
</style>


<div class="box">
<ul>
  <li><img src="./imgs/1.jpg" alt=""></li>
  <li><img src="./imgs/2.jpg" alt=""></li>
  <li><img src="./imgs/3.jpg" alt=""></li>
  <li><img src="./imgs/4.jpg" alt=""></li>
</ul>

<ul>
  <li><img src="./imgs/1.jpg" alt=""></li>
  <li><img src="./imgs/2.jpg" alt=""></li>
  <li><img src="./imgs/3.jpg" alt=""></li>
  <li><img src="./imgs/4.jpg" alt=""></li>
</ul>

<ul>
  <li><img src="./imgs/1.jpg" alt=""></li>
  <li><img src="./imgs/2.jpg" alt=""></li>
  <li><img src="./imgs/3.jpg" alt=""></li>
  <li><img src="./imgs/4.jpg" alt=""></li>
</ul>

<ul>
  <li><img src="./imgs/1.jpg" alt=""></li>
  <li><img src="./imgs/2.jpg" alt=""></li>
  <li><img src="./imgs/3.jpg" alt=""></li>
  <li><img src="./imgs/4.jpg" alt=""></li>
</ul>
</div>
<div class="btn">
<button>&lt;</button>
<button>&gt;</button>
</div>

<script type="text/javascript">
    var btn = document.querySelectorAll('button');
    var box = document.querySelector('.box');
    var _ul = box.querySelectorAll('ul');
    var num = 0;
    var flag = true;
    // btn 獲取到的是一個偽陣列    
    btn[1].onclick = function () {
      if (flag) {
        flag = false;
        num++;
        for (var i = 0; i < _ul.length; i++) {
          _ul[i].style.transform = 'rotateX(' + num * 90 + 'deg)';
    
        }
        // 監聽最後一個transition事件結束的時候 將flag 置為 true 防止重複點選
        _ul[_ul.length - 1].addEventListener('transitionend', function () {
          flag = true;
        })
      }
    }
    btn[0].onclick = function () {
      if (flag) {
        flag = false;
        num--;
        for (var i = 0; i < _ul.length; i++) {
          _ul[i].style.transform = 'rotateX(' + num * 90 + 'deg)';
    
        }
        _ul[_ul.length - 1].addEventListener('transitionend', function () {
          flag = true;
        })
      }
    
    }
</script>

效果圖:

image

10.5 backface-visibility

backface-visibility屬性定義當元素不面向螢幕時是否可見。

如果在旋轉元素不希望看到其背面時,該屬性很有用。有兩個屬性:

  • 1、visible背面是可見的
  • 2、hidden背面是不可見的