变化效果 - CSS3 gradient渐变 transition过渡 transform转换

945 阅读10分钟

gradient 渐变

CSS3渐变(gradient)可以让你在两个或多个指定的颜色之间显示平稳的过渡,而不必使用提前设计好的图像来实现效果,由此,渐变不会因为界面大小变化而出现失真,因为gradient是由浏览器生成的。

线性渐变 - 关键代码

background:linear-gradient(<direction>,<color1>,<color2>,...);
/* 渐变不是制定颜色而已,因此这里不能使用background-color属性 */
.simple-linear {
  background: linear-gradient(blue, pink);
}
.horizontal-gradient {
  background: linear-gradient(to right, lime 28px, red 77%, cyan);
}
.diagonal-gradient {
  background: linear-gradient(to bottom right, blue, pink);
}
.angled-gradient {
  background: linear-gradient(70deg, blue, pink);
  /**
   * 0deg 代表渐变方向为从下到上
   * 90deg 代表渐变方向为从左到右
   * 正角度->顺时针方向,负角度->逆时针方向
   */
}
属性值取值
directionto bottom(默认,由上向下的渐变) / to top / to right / to left / deg

径向渐变 - 关键代码

线性渐变是从“一个方向”向“另一个方向”的颜色渐变,而径向渐变是从“一个点”向四周的颜色渐变,类似“水中涟漪”。

属性值取值
shape渐变的形状,ellipse(默认,椭圆) / circle(圆形),如果元素形状为正方形,则两者显示一样
size渐变的大小,即渐变到哪里停止
closest-side / farthest-side / closest-corner / farthest-corner
at position渐变起点的位置,可以为百分比,默认是图形的正中心(at center center/at 50% 50%)
background:-webkit-radial-gradient(<shape> <size> <at position>, <color1>, <color2>, ...);
/* radial-gradient 兼容性不完全保障 */
.simple-radial {
  background: radial-gradient(red, blue);
}
.radial-gradient {
  /* Positioning the center of the gradient with keyterms, percentage, or absolute lengths */
  background: radial-gradient(at left 50%, 
      red 10px, yellow 30%, #1e90ff 50%);
}
.radial-ellipse-side {
  /* Sizing radial gradients,and farthest-corner is the default */
  background: radial-gradient(ellipse closest-side, 
      red, yellow 10%, #1e90ff 50%, beige);
}
.radial-ellipse-far {
  background: radial-gradient(ellipse farthest-corner at 90% 90%,
      red, yellow 10%, #1e90ff 50%, beige);
}
.radial-circle-close {
  background: radial-gradient(circle closest-side at 25% 75%,
      red, yellow 10%, #1e90ff 50%, beige);
}
.stacked-radial {
  background:
      radial-gradient(circle at 50% 0,
        rgba(255,0,0,.5),
        rgba(255,0,0,0) 70.71%),
      radial-gradient(circle at 6.7% 75%,
        rgba(0,0,255,.5),
        rgba(0,0,255,0) 70.71%),
      radial-gradient(circle at 93.3% 75%,
        rgba(0,255,0,.5),
        rgba(0,255,0,0) 70.71%) beige;
  border-radius: 50%;
}
/* 其它不按顺序的写法 */
.radial_1{ 
    background:-webkit-radial-gradient(30px 30px,circle farthest-corner,white,#78C5FF); 
} 
.radial_2{ 
    background:-webkit-radial-gradient(circle contain,white,lightgreen,green); 
}

image.png

线性重复渐变

background:-webkit-repeating-linear-gradient(<point>, <color1>, <color1>, ...);
-----------------------------------------------------
<point> => [ left | right ]? [ top | bottom ]? || [<angle>]
-----------------------------------------------------
.repeating-linear {
  background: repeating-linear-gradient(90deg, 
      yellow, yellow 20px, black 20px, black 40px);
}
/* 需要通过rgba()设置透明度 */
.multi-repeating-linear {
    background:
        repeating-linear-gradient(
            190deg, 
            rgba(255, 0, 0, 0.5) 40px,
            rgba(255, 153, 0, 0.5) 80px, 
            rgba(255, 255, 0, 0.5) 120px,
            rgba(0, 255, 0, 0.5) 160px, 
            rgba(0, 0, 255, 0.5) 200px,
            rgba(75, 0, 130, 0.5) 240px, 
            rgba(238, 130, 238, 0.5) 280px,
            rgba(255, 0, 0, 0.5) 300px),
        repeating-linear-gradient(
            -190deg, 
            rgba(255, 0, 0, 0.5) 30px,
            rgba(255, 153, 0, 0.5) 60px, 
            rgba(255, 255, 0, 0.5) 90px,
            rgba(0, 255, 0, 0.5) 120px, 
            rgba(0, 0, 255, 0.5) 150px,
            rgba(75, 0, 130, 0.5) 180px, 
            rgba(238, 130, 238, 0.5) 210px,
            rgba(255, 0, 0, 0.5) 230px);
}

线性重复渐变.png

径向重复渐变

background:repeating-radial-gradient(<position1> <position2>, <shape> <size>, <color1>, <color2>, ...);
-----------------------------------------------------
<position> => <length> | <percentage> | left | center | right | bottom | top
<shape>    => circle | ellipse
<size>     => closest-side | closest-corner | farthest-side | farthest-corner 
                    contain | cover
-----------------------------------------------------
.repeating-radial {
  background: repeating-radial-gradient(black, black 5px, white 5px, white 10px);
}
.multi-target {
  background:
      repeating-radial-gradient(ellipse at 80% 50%,rgba(0,0,0,0.5),
        rgba(0,0,0,0.5) 15px, rgba(255,255,255,0.5) 15px,
        rgba(255,255,255,0.5) 30px) top left no-repeat,
      repeating-radial-gradient(ellipse at 20% 50%,rgba(0,0,0,0.5),
        rgba(0,0,0,0.5) 10px, rgba(255,255,255,0.5) 10px,
        rgba(255,255,255,0.5) 20px) top left no-repeat yellow;
  background-size: 200px 200px, 150px 150px;
}

颜色渐变 VS 颜色突变

  1. 颜色渐变
linear-gradient(to bottom,red 30%,green% 60%,blue 90%);
/**
 * 30% red颜色(表示从0-30%都是red)
 * 60% green颜色(从30%到60%由red渐变为green)
 * 90% blue颜色(从60%到90%由green渐变为blue,90%后面的都是blue颜色了)
 */
  1. 颜色突变
linear-gradient(to bottom,red 33.33%,green 33.33% 66.66%,blue 66.66%);
/**
 * 33.33% red颜色
 * 33.33%-66.66% green颜色
 * 66.66% blue颜色
 */

渐变覆盖

.stacked-linear {
  background:
      linear-gradient(217deg, rgba(255,0,0,.8), rgba(255,0,0,0) 70.71%),
      linear-gradient(127deg, rgba(0,255,0,.8), rgba(0,255,0,0) 70.71%),
      linear-gradient(336deg, rgba(0,0,255,.8), rgba(0,0,255,0) 70.71%);
}

渐变覆盖.png

```CSS
/* transparent 透明色  mistyrose 薄雾玫瑰色 */
background: linear-gradient(to right, transparent, mistyrose),url(./10bf209477.jpg);
background-size: contain;

渐变覆盖.png

See Also - CSS gradients

transition 过渡

语法 - 关键代码

transition 属性是一个简写属性,用于设置四个过渡属性:

  • transition-property
  • transition-duration
  • transition-delay
  • transition-timing-function
transition: <property> <duration> <delay> <timing-function>;
属性值说明
property参与过渡的属性,可取值:all(所有属性) / <指定单一属性>
不支持display:none/block;;transition-property可以指定多个属性
duration必要,过渡的持续时间,一般取值秒/毫秒(s/ms)
delay延迟过渡的时间,一般取值秒/毫秒(s/ms)
timing-function动画过渡的类型,可取值:linear默认匀速/ease慢速减速/ease-in加速/ease-out减速/ease-in-out先加速后减速/bezier曲线
/* eg.1 指定所有属性*/
transition:all 5s 3s linear;
/* eg.2 指定单一属性*/
div{
    width:100px;
    height:100px;
    transition:width 2s;
}
div:hover{
    width:300px;
    height:150px;
}
/* eg.3 指定多个属性 */
transition-property:width height;
transition-duration:2s;
transition-delay:0.5s;
transition-timing-function:ease;

bezier曲线 bezier工具网站

transform 转换

  • transform 属性向元素应用 2D 或 3D 转换
  • 该属性允许我们对元素进行旋转、缩放、移动或倾斜

属性1 - 移动 - translate()

该属性将元素向指定的方向移动,类似于position中的relative。

属性值说明
translate(x,y)定义 2D 转换,对角移动(在水平和垂直方向上都有移动)
translate3d(x,y,z)定义 3D 转换。
translateX(x)定义转换,只是用 X 轴的值,水平移动
translateY(y)定义转换,只是用 Y 轴的值,垂直移动
translateZ(z)定义 3D 转换,只是用 Z 轴的值。
.translate_box{
    background-color: antiquewhite;
    transform: translate(30px,50px);
    /* *
     * 30px --> translateX(30px)
     * 50px --> translateY(50px)
     */
     
     /*TIP:可以使用100%来移动与自身大小等宽/等高的距离
       transform: translationX(100%); 水平方向上向右移动自身width相等的距离
     */
}
.normal_box{
    background-color: aqua;
}

translate(x,y).png

属性2 - 缩放 - scale()

让元素根据中心原点对对象进行缩放。

属性值说明
scale(x,y)定义 2D 缩放转换,x和y的取值规则相同,0.01-0.99缩小、默认为1(不缩放)、1.01及以上均为放大;如果取负值,则是倒向缩放
scale3d(x,y,z)定义 3D 缩放转换
scaleX(x)通过设置 X 轴的值来定义缩放转换。
scaleY(y)通过设置 Y 轴的值来定义缩放转换。
scaleZ(z)通过设置 Z 轴的值来定义 3D 缩放转换。
ul{
    list-style: none;
    padding-left: 0;  /*消除ul的左内边距*/
}
li{
    height: 100px;
    width: 600px;
    padding: 10px;
    margin: auto;
    border-radius: 10px;
    transition: all 0.3s 1ms ease; /* 返回一般状态的过渡 */
}

li:nth-child(1){  background-color:cyan;  }
li:nth-child(2){  background-color:deepskyblue;  }
li:nth-child(3){  background-color:aquamarine;  }
li:hover{
    border-radius: 5px;
    color: darkblue;
    transform: scale(1.05,0.9); /* X->1.05 Y->0.9 */
    transition: all 0.3s 5ms ease; /* 返回hover状态的过渡 */
}

transform scale 缩放.gif

属性3 - 旋转 - rotate()

rotate()指定一个2D/3D旋转

属性值说明
rotate(angle)定义 2D 旋转,在参数中规定角度。如果为正,元素相对于原点中心顺时针旋转,如果为负,则呈现逆时针旋转
rotate3d(x,y,z,angle)定义 3D 旋转,0 到 1 之间的数值,表示旋转轴 xyz 坐标方向的矢量。
rotateX(angle)定义沿着 X 轴的 3D 旋转。
rotateY(angle)定义沿着 Y 轴的 3D 旋转。
rotateZ(angle)定义沿着 Z 轴(垂直视平面)的 3D 旋转。
li{
    height: 200px;
    width: 200px;
    margin: auto;
    transition: all 1s 1ms ease;
}
li:nth-child(1){
    border-radius: 20px;
    background-color:cyan;            
}
li:nth-child(2){
    border-radius: 50%;
    background: repeating-linear-gradient(45deg,deepskyblue 0 40%,cyan 40% 60%,aquamarine 60%);
}
li:nth-child(3){
    background: repeating-radial-gradient(circle farthest-side at right center,deepskyblue 40%,cyan 60%,aquamarine 60%);
}
li:nth-child(4){
    background: repeating-radial-gradient(circle farthest-corner at right center,red, yellow 10%, #1e90ff 50%, beige);
}
li:nth-child(1):hover{
    transition: all 2s 5ms ease-in; 
    transform: rotate(720deg);  /* 顺时针旋转2周 */
}
li:nth-child(2):hover{
    transition: all 0.6s 2ms ease-in;
    transform: rotate(-108deg);  /* 逆时针旋转108度 */
}
li:nth-child(3):hover{
    transition: all 1.2s 2ms ease-in-out;
    transform: rotateX(180deg);
}
li:nth-child(4):hover{
    transition: all 0.98s 1.6ms ease-out;
    transform: rotate(30deg);
}

transform rotate 2d.gif

多属性值顺序影响

transform 属性可以同时将 translate() scale() rotate() 简写在一起,顺序调整也同样生效,但需要注意不同的顺序产生的效果会大相径庭,因此,一般需要注意当多个属性简写时,要先将translate()属性写在最前面,否则会出现移动距离出现错误。

section:hover .translate{
    transform: translate(200px);
}
section:hover .translate_scale_rotate{
    transform: translateX(200px) scale(0.5) rotate(180deg);
}
section:hover .scale_translate{
    transform: scale(0.5) translate(200px);
}
section:hover .rotate_translate{
    transform: rotate(180deg) translateX(200px);
}

transform 多属性顺序不同产生的影响.gif

属性4 - 倾斜 - skew()

  • skew() 指定一个或两个参数,它们表示在每个方向上应用的倾斜量
  • skewX(x) / skew(x) 沿横坐标倾斜 x 度
  • skewY(y) 沿纵坐标倾斜 y 度
  • skew(x,y) 沿横坐标和纵坐标各自倾斜 x 和 y 度

transform-origin

  • transform-origin 属性可以更改元素的x、y、z轴的位置,从而可以改变元素中心点的位置
transform:<x-axis> <y-axis> <z-axis>; /* 默认 transform:50% 50% 0; --> 元素中心点 */
属性值说明
x-axis定义视图被置于 X 轴的何处。可能的值:left / center / right / length / %
y-axis定义视图被置于 Y 轴的何处。可能的值:top / center / bottom / length / %
z-axis定义视图被置于 Z 轴的何处。可能的值:length

3D 取值

三维坐标系

  • x 轴:水平向右 -- x 轴右边是正值,左边是负值
  • y 轴:垂直向下 -- y 轴下面是正值,上面是负值
  • z 轴:垂直屏幕 -- 往外边的是正值,往里面的是负值

image.png

  • 3D 位移:translate3d(x, y, z) 
  • 3D 旋转:rotate3d(x, y, z)
  • 3D 缩放:scale3d(x,y,z)
  • 注意:x, y, z 对应的值不能省略,不需要填写用 0 进行填充,transform: translate3d(100px, 100px, 0)

代码示例

三色国旗

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            outline: 1px dashed lightblue;
        }
        body{
            display: flex;
            flex-flow: row wrap;
            justify-content: space-between;
        }
        div{
            width: 25%;
            height: 24vh;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 1.3vw;
            text-align: center;
        }
        .radial_center,.radial_percent,.radial_color{
            width: 33.33%;
        }
        .zebra,.concentric{
            width: 50%;
        }
        /* 线性渐变 */
        .to_bottom{
            background: linear-gradient(to bottom, #FFA969, #FFD062, #F9F871);
        }
        .to_top{
            background:linear-gradient(to top, #00C9A9, #028a73);
        }
        .to_right{
            background:linear-gradient(to right, #B4829F, #DDD7C6, #FFF6FD);
        }
        .deg{
            background:linear-gradient(45deg,#B190E8,#78C5FF,#0FF5FF);
        }
        /* 线性渐变 - 国旗 */
        .France{
            background: linear-gradient(to bottom,#FDFDFD 33.33%,#0000FC 33.33% 66.66%,#FD0000 66.66%);
        }
        .Italy{
            background: linear-gradient(to right,#2A9936 33.33%,#FFFFFF 33.33% 66.66%,#DE322C 66.66%);
        }
        .German{
            background: linear-gradient(to top,#FFD000 33.33%,#DE0000 33.33% 66.66%,#000000 66.66%);
        }
        .Romania{
            background: linear-gradient(to left,#C6042B 33.33%,#FFCC00 33.33% 66.66%,#002266 66.66%);
        }
        /* 径向渐变 */
        .radial_center{
            background:-webkit-radial-gradient(30px 30px,circle farthest-corner,white,#78C5FF);
        }
        .radial_percent{
            background:-webkit-radial-gradient(circle contain,white,lightgreen,green);
        }
        .radial_color{
            background:radial-gradient(circle closest-side,red 50%, white 50%);
        }
        /* 线性重复渐变 - 斑马线 */
        .zebra{
            background:-webkit-repeating-linear-gradient(right, white 0 5%, black 5% 10%);
        }
        /* 径向重复渐变 - 同心圆 */
        .concentric{
            background:-webkit-repeating-radial-gradient(center center, circle closest-side, white 0 5%, black 5% 10%);
        }
    </style>
</head>
<body>
    <!-- eg.1 -->
    <div class="to_bottom">linear-gradient(to bottom, #FFA969, #FFD062, #F9F871);<br>从上到下,三色</div>
    <div class="to_top">linear-gradient(to top, #00C9A9, #028a73);<br>从下到上,两色</div>
    <div class="to_right">linear-gradient(to right, #B4829F, #DDD7C6, #FFF6FD);<br>从左到右,三色</div>
    <div class="deg">linear-gradient( 45deg, #B190E8, #78C5FF, #0FF5FF);<br>45°角度,三色</div>
    <!-- eg.2 -->
    <div class="France"></div>
    <div class="Italy"></div>
    <div class="German"></div>
    <div class="Romania"></div>
    <!-- eg.3 -->
    <div class="radial_center">-webkit-radial-gradient(50% 50%,ellipse,white,#78C5FF);</div>
    <div class="radial_percent">-webkit-radial-gradient(50% 50%,circle,white 5%,lightgreen 35%,green 80%);</div>
    <div class="radial_color">background:radial-gradient(circle closest-side, red 50%, white 50%);</div>
    <!-- eg.4 -->
    <div class="zebra"></div>
    <div class="concentric"></div>
</body>
</html>

渐变.png

太极图

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body,html{
            height: 100%;
        }
        body{
            display: flex;
        }
        .taiji{
            width: 45vw;
            height: 45vw;
            background-color: black;
            margin: auto;
            border-radius: 50%;
            background: linear-gradient(to bottom, white 50%, black 50%);
            display: flex;
            align-items: center;
            border: 1px solid black;
        }
        .taiji::before,.taiji::after{
            content: "";
            display: block;  /* 伪元素是没有任何默认样式的,因此主要制定行内还是块级 */
            width: 50%;
            height: 50%;
        }
        .taiji::before{
            background: -webkit-radial-gradient(circle, black 15%, white 15%);
            border-radius: 50%;
        }
        .taiji::after{
            background: -webkit-radial-gradient(circle, white 15%, black 15%);
            border-radius: 50%;
        }
    </style>
</head>
<body>
    <div class="taiji"></div>
</body>
</html>

太极图.png

赛马

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            /* outline: auto; */
        }
        body,html{
            height: 100%;
            margin: 0 5px;
        }
        .gameName{
            display: block;
            font: normal bolder 16px/18px Aria;
            text-align: center;
            color: black;
            background-color: yellow;
        }
        main{
            height: calc(100% - 18px);
            display: flex;
            justify-content: space-between;
        }
        span{
            width: 100px;
            background: -webkit-repeating-linear-gradient(45deg,yellow 0 20px,black 20px 40px);
        }
        span>b{
            display: block;
            width: 100%;
            background-color: yellow;
            font: normal normal 12px/16px Aria;
            text-align: center;
            cursor: default;
        }
        section{
            width: 100%;
            display: flex;
            flex-flow: column;
            justify-content: space-around;
        }
        div{
            width: 0;
            height: 10%;
            border-bottom: 1px solid red;
            /* ease 速度逐渐变慢的減速 */
            transition: all 1s 10ms ease;
        }
        div>img{
            margin-left: 0;
            height: 100%;
            float: right;
        }
        span:hover~section div{
            width: 100%;
        }
        span:hover~section .horse1{
            border-bottom: 1px solid red;
            /* linear 匀速 */
            transition: all 2.6s 10ms linear;
        }
        span:hover~section .horse2{
            border-bottom: 1px solid green;
            transition: width 4.2s 15ms ease;
        }
        span:hover~section .horse3{
            border-bottom: 1px solid yellow;
            /* ease-in 加速 */
            transition: all 2.4s 10ms ease-in;
        }
        span:hover~section .horse4{
            border-bottom: 1px solid black;
            /* ease-out 逐渐减速 */
            transition: all 3.3s 11ms ease-out;
        }
        span:hover~section .horse5{
            border-bottom: 1px solid olive;
            /* ease-in-out 想加速后减速 */
            transition: all 5.5s 2ms ease-in-out;
        }
        span:hover~section .horse6{
            border-bottom: 1px solid olive;
            /* cubic-bezier 贝塞尔曲线 */
            transition: all 3.4s 0.2ms cubic-bezier(.31,1.35,.53,-0.54);
        }

    </style>
</head>
<body>
    <strong class="gameName">Horse Race Game</strong>
    <main>
        <span><b>START</b></span>
        <section>
            <div class="horse1"><img src="./horse/Horse (1).png"></div>
            <div class="horse2"><img src="./horse/Horse (2).png"></div>
            <div class="horse3"><img src="./horse/Horse (3).png"></div>
            <div class="horse4"><img src="./horse/Horse (4).png"></div>
            <div class="horse5"><img src="./horse/Horse (5).png"></div>
            <div class="horse6"><img src="./horse/Horse.png"></div>
        </section>
        <span><b>TERMINUS</b></span>
    </main>
</body>
</html>

HorseGame_动画过渡示例.gif

折扇效果

.container{
    width: 50%;
    height: 400px;
    position: relative;
    margin: auto;
}
.fan{
    width: 40px;
    height: 220px;
    position: absolute;
    left: 50%;
    margin-left: -20px;
    bottom: 50px;
    /* 旋转轴设处在底部 */
    transform-origin: bottom;
    transition: all 1s 2ms ease-in;
    /* 裁剪形状 */
    clip-path: polygon(0% 0%, 100% 0,50% 100%);
    /* 圆润边角 */
    border-radius: 20px;
}
/* 折扇颜色 */
.fan:nth-child(1),.fan:nth-child(19),.fan:nth-child(3),.fan:nth-child(17),.fan:nth-child(5),.fan:nth-child(15),.fan:nth-child(7),.fan:nth-child(13),.fan:nth-child(9),.fan:nth-child(11){
    background-color: violet;
}
.fan:nth-child(2),.fan:nth-child(18),.fan:nth-child(4),.fan:nth-child(16),.fan:nth-child(6),.fan:nth-child(14),.fan:nth-child(8),.fan:nth-child(12){
    background-color: aqua;
}
.fan:nth-child(10){
    background-color: chartreuse;
}
/* 折扇翻转角度 */
.container:hover .fan:nth-child(1){
    transform: rotate(90deg);
}
.container:hover .fan:nth-child(19){
    transform: rotate(-90deg);
}
.container:hover .fan:nth-child(2){
    transform: rotate(80deg);
}
.container:hover .fan:nth-child(18){
    transform: rotate(-80deg);
}
.container:hover .fan:nth-child(3){
    transform: rotate(70deg);
}
.container:hover .fan:nth-child(17){
    transform: rotate(-70deg);
}
.container:hover .fan:nth-child(4){
    transform: rotate(60deg);
}
.container:hover .fan:nth-child(16){
    transform: rotate(-60deg);
}
.container:hover .fan:nth-child(5){
    transform: rotate(50deg);
}
.container:hover .fan:nth-child(15){
    transform: rotate(-50deg);
}
.container:hover .fan:nth-child(6){
    transform: rotate(40deg);
}
.container:hover .fan:nth-child(14){
    transform: rotate(-40deg);
}
.container:hover .fan:nth-child(7){
    transform: rotate(30deg);
}
.container:hover .fan:nth-child(13){
    transform: rotate(-30deg);
}
.container:hover .fan:nth-child(8){
    transform: rotate(20deg);
}
.container:hover .fan:nth-child(12){
    transform: rotate(-20deg);
}
.container:hover .fan:nth-child(9){
    transform: rotate(10deg);
}
.container:hover .fan:nth-child(11){
    transform: rotate(-10deg);
}

transform rotate 实例 circular fan.gif

See Also