十四.CSS变形(transform)、过渡(transition)、动画(animation)详解

5,399 阅读7分钟

一.CSS变形(transform)

1.1移动、缩放、旋转

通过 CSS3 变形属性,我们能够对元素进行移动、缩放、转动、拉长或拉伸。

2D旋转:transform:rotate(45deg);
	注意:默认情况下,是z轴,也可以改变轴向,rotateX();   rotateY();但是为了看到效果,要加上perspective属性;

移动: translate(100px, 0px);/*第一个参数水平方向移动 第二个参数垂直方向移动 */

缩放: transform: scale(0.5, 0.5);/*水平轴上缩小一倍,垂直轴上缩小一倍*/
            transform: scale(1.5);
综合
       1.如果需要进行多个转换, 那么用空格隔开
       2.2D的转换模块会修改元素的坐标系, 所以旋转之后再平移就不是水平平移的
         transform: rotate(45deg) translate(100px, 0px) scale(1.5, 1.5);

1.2形变中心点transform-origin

默认情况下所有的元素都是以自己的中心点作为参考来旋转的, 我们可以通过形变中心点属性来修改它的参考点;

transform-origin: 200px 0px;
transform-origin: 50% 50%;
transform-origin: 0% 0%;
transform-origin: center center;

1.3透视perspective

 perspective: 500px;
注意点:
一定要注意, 透视属性必须添加到需要呈现近大远小效果的元素的父元素上面
添加了 perspective 属性的元素,添加后场景中出现 Z轴,故其子元素获得 3D 效果,包括 translateZ 和 rotateY/rotateX
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>96-2D转换模块-练习</title>
    <style>
      *{
          margin: 0;
          padding: 0;
      }
      div{
          width: 310px;
          height: 438px;
          border: 1px solid #000;
          background-color: skyblue;
          margin: 100px auto;
          perspective: 500px;
      }
      div img{
          transform-origin: center bottom;中心点在底部终点
          transition: transform 1s;transform属性再一秒发生改变
      }
      div:hover img{
          transform: rotateX(80deg);/*点击之后绕x轴旋转80°*/
      }
    </style>
  </head>
  <body>
    <div>
      <img src="images/pk.png" alt="" />
    </div>
  </body>
</html>

二.过渡(transition)

CSS过渡在一段时间内把css属性的初始值变为另一个值,既逐渐变化,不那么突兀。

2.1 过渡属性

在css中过度使用四个属性定义:

1.transition-property:指定哪个或哪些 CSS 属性用于过渡
     /*
         transition-property:transform;
	 transition-property: opacity, left, top, height;
     */

2.transition-duration:指定过渡的时长;
    /*
     transition-duration: 2s
    */

3.transition-timing-function:告诉系统过渡动画的运动的速度;
    /*
        transition-timing-function 属性可接受以下值:
             ease - 规定过渡效果,先缓慢地开始,然后加速,然后缓慢地结束(默认)
             linear - 规定从开始到结束具有相同速度的过渡效果
             ease-in -规定缓慢开始的过渡效果
             ease-out - 规定缓慢结束的过渡效果
             ease-in-out - 规定开始和结束较慢的过渡效果
     */


4.transition-delay:指定延迟,即属性开始变化时与过渡开始发生时之间的时长。
即告诉系统延迟多少秒之后才开始过渡动画;
     /*
         transition-delay: 0.5s
     */

注意点:

  • 过渡的属性和持续时间必须要有一般会写成transition: all 1s;
  • 把过度写在元素上鼠标移入移出都会有过渡效果;
  • 把过度属性写在悬停状态,移入有过渡效果,移出没有,有时候我们就需要这样的,缓缓显示,瞬间消失;
div {
  /*把过度写在元素上鼠标移入移出都会有过渡效果*/
  width: 100px;
  height: 50px;
  background-color: red;
  `transition: all 5s;`
}
/*:hover这个伪类选择器除了可以用在a标签上, 还可以用在其它的任何标签上,*/
div:hover {
  width: 300px;
  background-color: blue;
}
/*
把过度属性写在悬停状态,移入有过渡效果,移出没有,有时候我们就需要这样的,缓缓显示,瞬间消失
*/
div {
  width: 100px;
  height: 50px;
  background-color: red;
 
}
div:hover {
    /*把过度写在悬停上鼠标移入会有过渡效果*/
     transition: all 5s;
     width: 300px;
     background-color: blue;
}

2.2过渡书写格式

transition: 过渡属性 过渡时长 运动速度 延迟时间; 
transition: all 1s;
.container {
        width: 100px;
        height: 100px;
        background: red;
      }
      .container:hover {
        transition: all 1s;
        width: 800px;
        background: green;
      }
  • 1.编写过渡套路
  • 1.1不要管过渡, 先编写基本界面
  • 1.2修改我们认为需要修改的属性
  • 1.3再回过头去给被修改属性的那个元素添加过渡即可

2.3过渡效果小实例--弹性效果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>91-过渡模块-弹性效果</title>
    <style>
      
        div{
            height: 100px;
            background-color: red;
            margin-top: 100px;
            text-align: center;
            line-height: 100px;
        }
        div span{
            font-size: 80px;
            /*transition-property: margin;*/
            /*transition-duration: 3s;*/
            transition: margin 3s;
        }
        div:hover span{
            margin: 0 20px;
        }
    </style>
</head>
<body>
<div>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
</div>
</body>
</html>

2.4过渡效果小实例--手风琴效果

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>92-过渡模块-手风琴效果</title>
   
      ul {
        width: 960px;
        height: 300px;
        margin: 100px auto;
        border: 1px solid #000;
        overflow: hidden;
      }
      ul li {
        list-style: none;
        width: 160px;
        height: 300px;
        background-color: red;
        float: left;
        transition: width 0.5s;
      }
      ul:hover li {
        width: 100px;
      }
      ul li:hover {
        width: 460px;
      }
    </style>
  </head>
  <body>
    <ul>
      <li><img src="images/ad1.jpg" alt="" /></li>
      <li><img src="images/ad2.jpg" alt="" /></li>
      <li><img src="images/ad3.jpg" alt="" /></li>
      <li><img src="images/ad4.jpg" alt="" /></li>
      <li><img src="images/ad5.jpg" alt="" /></li>
      <li><img src="images/ad6.jpg" alt="" /></li>
    </ul>
  </body>
</html>

2.52.4过渡效果小实例--动态下拉菜单

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>99-翻转菜单-综合练习</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .nav{
            width: 400px;
            height: 40px;
            margin: 0 auto;
            margin-top: 100px;
            background-color: black;
        }
        .nav>li{
            list-style: none;
            float: left;
            width: 120px;
            height: 40px;
            background-color: green;
            margin-left: 10px;
            text-align: center;
            line-height: 40px;
            position: relative;
        }
        .sub{
            /*不显示元素*/
            /*display: none;*/
            width: 120px;
            position: absolute;
            left: 0;
            top: 40px;
        }
        .sub li{
            list-style: none;
            background-color: deeppink;
            transform: rotateY(180deg);
            transition: all 1s;
            opacity: 0;
        }
        
        .nav>li:hover .sub li{
            transform: none;
            opacity: 1;
        }
        .nav>li:hover .sub li:nth-child(1){
            transition-delay: 0ms;
        }
        .nav>li:hover .sub li:nth-child(2){
            transition-delay: 200ms;
        }
        .nav>li:hover .sub li:nth-child(3){
            transition-delay: 400ms;
        }
        .nav>li:hover .sub li:nth-child(4){
            transition-delay: 600ms;
        }
        .nav>li:hover .sub li:nth-child(5){
            transition-delay: 800ms;
        }

        .nav>li .sub li:nth-child(5){
            transition-delay: 0ms;
        }
        .nav>li .sub li:nth-child(4){
            transition-delay: 200ms;
        }
        .nav>li .sub li:nth-child(3){
            transition-delay: 400ms;
        }
        .nav>li .sub li:nth-child(2){
            transition-delay: 600ms;
        }
        .nav>li .sub li:nth-child(1){
            transition-delay: 800ms;
        }
        div{
            width: 400px;
            height: 300px;
            background-color: red;
            margin: 0 auto;
        }
    </style>
</head>
<body>
<ul class="nav">
    <li>一级菜单
        <ul class="sub">
            <li>二级菜单</li>
            <li>二级菜单</li>
            <li>二级菜单</li>
            <li>二级菜单</li>
            <li>二级菜单</li>
        </ul>
    </li>
    <li>一级菜单
        <ul class="sub">
            <li>二级菜单</li>
            <li>二级菜单</li>
            <li>二级菜单</li>
            <li>二级菜单</li>
            <li>二级菜单</li>
        </ul>
    </li>
    <li>一级菜单
        <ul class="sub">
            <li>二级菜单</li>
            <li>二级菜单</li>
            <li>二级菜单</li>
            <li>二级菜单</li>
            <li>二级菜单</li>
        </ul>
    </li>
</ul>
<div>我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字</div>
</body>
</html>

三.动画(animation)

CSS animation 可以让一个CSS样式配置自动转换到另一个CSS样式配置,并且还可以控制转换过程。动画包括两个部分:描述动画的样式规则和用于指定动画开始、结束以及中间点样式的关键帧。

3.1 关键帧动画

3.1.1 定义关键帧

创建动画的第一步是使用@keyframes为动画起个名字,并在一对花括号内定义关键帧;

在一对花括号中有一系列关键贞选择符(百分比或from....to...),其后有一段css,声明想以动画形式改变的属性;

第二步:要用animation-name属性把动画附加到元素上。

/*第一种方法:from...to...*/
@keyframes fadeout{
    from {
            opacity:1
            }
            
    to{
        opacity:0
            }
}


/*第二种方法:用百分比*/
@keyframes color-pop{
    0%{
        color:black
    }
    33%{
        color:gray
    }
    100%{
        color:white
    }
}
3.1.2 把动画应用到元素上
div{
    animation-name:fadeout,color-pop;/*指定想用的关键真动画名称*/
    
    animation-duration:1s;/*指定想用的关键真动画时长*/
    
    animation-delay2s/*指定延迟时间*/
    
    animation-iteration-count:infinite;/*指定无限次使动画永远持续下去*/
    animation-direction:reverse ;  
     /*
     属性指定是向前播放、向后播放还是交替播放动画 默认向前,
     alternate" 使动画先向前运行,然后向后运行normal
     */
     
    animation-timing-function:linear;/*匀速*/
    
    animation-fill-mode
}
/*简写*/
div {
  animation: example 5s linear 2s infinite alternate;
}
//重复动画

animation-iteration-count: infinite;

//来回运动
 animation-iteration-count: infinite;
 animation-direction: alternate;

3.2 steps()时许函数

把动画分成一些列等长步幅,接受两个参数,步数和变化点

 .step2{
            width: 200px;
            height: 312px;
            margin:50px;
            background: red;
            animation: move 3s steps(1,end) infinite;
        }      
        @keyframes move {
            0% {background: purple;/*紫色*/}
            50% {background: blue;/*蓝色*/}
            100% {background: red; /*红色*/}
        }
steps(1,end)--表示把动画划分了一帧,最后一帧没有了,也就是看不到红色了
steps(1,start)--表示把动画划分了一帧,第一帧一帧没有了,也就是看不到紫色了
3.3 云层效果

用到三张图:

cloud_one.png

cloud_three.png

cloud_two.png

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>104-动画模块-云层效果</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      ul {
        height: 400px;
        background-color: skyblue;
        margin-top: 100px;
        animation: change 5s linear 0s infinite alternate;
        position: relative;
        overflow: hidden;
      }
      ul li {
        list-style: none;
        width: 400%;
        height: 100%;
        position: absolute;
        left: 0;
        top: 0;
      }
      ul li:nth-child(1) {
        background-image: url("https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/04be1c2125af4980b82f182d3d66c6ab~tplv-k3u1fbpfcp-watermark.image");
        animation: one 30s linear 0s infinite alternate;
      }
      ul li:nth-child(2) {
        background-image: url("https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/04be1c2125af4980b82f182d3d66c6ab~tplv-k3u1fbpfcp-watermark.image");
        animation: two 30s linear 0s infinite alternate;
      }
      ul li:nth-child(3) {
        background-image: url("https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/04be1c2125af4980b82f182d3d66c6ab~tplv-k3u1fbpfcp-watermark.image");
        animation: three 30s linear 0s infinite alternate;
      }
      @keyframes change {
        from {
          background-color: skyblue;
        }
        to {
          background-color: black;
        }
      }
      @keyframes one {
        from {
          margin-left: 0;
        }
        to {
          margin-left: -100%;
        }
      }
      @keyframes two {
        from {
          margin-left: 0;
        }
        to {
          margin-left: -200%;
        }
      }
      @keyframes three {
        from {
          margin-left: 0;
        }
        to {
          margin-left: -300%;
        }
      }
    </style>
  </head>
  <body>
    <ul>
      <li></li>
      <li></li>
      <li></li>
    </ul>
  </body>
</html>

3.4 轮播图

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>105-动画模块-无限滚动</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      div {
        width: 600px;
        height: 188px;
        border: 1px solid #000;
        margin: 100px auto;
        overflow: hidden;
      }

      ul {
        width: 2000px;
        height: 188px;
        background-color: black;
        animation: move 10s linear 0s infinite normal;
      }
      ul li {
        float: left;
        list-style: none;
        width: 300px;
        height: 188px;
        background-color: red;
        border: 1px solid #000;
        box-sizing: border-box;
      }
      ul:hover {
        /*动画添加给谁, 就让谁停止*/
        animation-play-state: paused;
      }
      ul:hover li {
        opacity: 0.5;
      }
      ul li:hover {
        opacity: 1;
      }
      @keyframes move {
        from {
          margin-left: 0;
        }
        to {
          margin-left: -1200px;
        }
      }
    </style>
  </head>
  <body>
    <div>
      <ul>
        <li><img src="images/banner1.jpg" alt="" /></li>
        <li><img src="images/banner2.jpg" alt="" /></li>
        <li><img src="images/banner3.jpg" alt="" /></li>
        <li><img src="images/banner4.jpg" alt="" /></li>
        <li><img src="images/banner1.jpg" alt="" /></li>
        <li><img src="images/banner2.jpg" alt="" /></li>
      </ul>
    </div>
  </body>
</html>

3D 转换模块

给他的父元素添加一个 transform-style 属性, 然后设置为 preserve-3d 即可

transform-style: preserve-3d;
编写正方体方案一:

编写一个 ul 标签,编写六个小 li,设置颜色,上下左右平移宽度的一半,在旋转 90°,前后直接平移宽度的一半

编写方案二:前面一面呈现给用户的始终是正的

编写顺序上后下前,然后分别旋转 90 180 270 360 ,都是向 Z 轴平移 100px

transform: rotateX(90deg) translateZ(100px);

左右设置:

transform: translateX(-100px) rotateY(90deg);
transform: translateX(100px) rotateY(90deg);
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .box {
        width: 200px;
        height: 200px;
        margin: 50px auto;
        top: 100px;
        transform-style: preserve-3d; /*开启3D*/
        position: relative;
        transform: rotateY(-21deg) rotateX(-19deg);
        animation: move 3s linear infinite; /*添加的观测动画效果*/
      }
      .inner {
        position: absolute;
        width: 200px;
        height: 200px;
        background: red;
        opacity: 0.5;
        text-align: center;
        font-size: 44px;
        color: red;
        line-height: 200px;
      }
      .top {
        background: red;
        transform: rotateX(90deg) translateZ(100px);
        color: royalblue;
      }
      .bottom {
        background: orange;
        transform: rotateX(90deg) translateZ(-100px);
      }
      .left {
        background: yellow;
        transform: rotateY(90deg) translateZ(100px);
      }
      .right {
        background: green;
        transform: rotateY(90deg) translateZ(-100px);
      }
      .font {
        background: blue;
        transform: rotateZ(90deg) translateZ(100px);
      }
      .back {
        background: purple;
        transform: rotateZ(90deg) translateZ(-100px);
      }
      @keyframes move {
        25% {
          transform: rotateY(-30deg) rotateX(-30deg);
        }
        50% {
          transform: rotateY(-70deg) rotateX(-70deg);
        }
        50% {
          transform: rotateY(-120deg) rotateX(-110deg);
        }
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div class="inner top"></div>
      <div class="inner bottom"></div>
      <div class="inner left"></div>
      <div class="inner right"></div>
      <div class="inner font"></div>
      <div class="inner back"></div>
    </div>
  </body>
</html>

3D 播放器

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>111-3D播放器下</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      body {
        background: url("images/jacky/bg.jpg") no-repeat;
        background-size: cover;
        overflow: hidden;
      }
      ul {
        width: 200px;
        height: 200px;
        /*background-color: red;*/
        position: absolute;
        bottom: 100px;
        left: 50%;
        margin-left: -100px;
        transform-style: preserve-3d;
        /*transform: rotateX(-10deg);*/
        animation: sport 6s linear 0s infinite normal;
      }
      ul li {
        list-style: none;
        width: 200px;
        height: 200px;
        font-size: 60px;
        text-align: center;
        line-height: 200px;
        position: absolute;
        left: 0;
        top: 0;
        background-color: black;
      }
      ul li:nth-child(1) {
        transform: rotateY(60deg) translateZ(200px);
      }
      ul li:nth-child(2) {
        transform: rotateY(120deg) translateZ(200px);
      }
      ul li:nth-child(3) {
        transform: rotateY(180deg) translateZ(200px);
      }
      ul li:nth-child(4) {
        transform: rotateY(240deg) translateZ(200px);
      }
      ul li:nth-child(5) {
        transform: rotateY(300deg) translateZ(200px);
      }
      ul li:nth-child(6) {
        transform: rotateY(360deg) translateZ(200px);
      }
      ul li img {
        width: 200px;
        height: 200px;
        border: 5px solid skyblue;
        box-sizing: border-box;
      }
      ul:hover {
        animation-play-state: paused;
      }
      ul:hover li img {
        opacity: 0.5;
      }
      ul li:hover img {
        opacity: 1;
      }
      @keyframes sport {
        from {
          /*
                注意点:
                1.动画中如果有和默认样式中同名的属性, 会覆盖默认样式中同名的属性
                2.在编写动画的时候, 固定不变的值写在前面, 需要变化的值写在后面
                */
          transform: rotateX(-10deg) rotateY(0deg);
        }
        to {
          transform: rotateX(-10deg) rotateY(360deg);
        }
      }
      .heart {
        width: 173px;
        height: 157px;
        position: absolute;
        left: 100px;
        bottom: 100px;
        animation: move 10s linear 0s infinite normal;
      }
      @keyframes move {
        0% {
          left: 100px;
          bottom: 100px;
          opacity: 1;
        }
        20% {
          left: 300px;
          bottom: 300px;
          opacity: 0;
        }
        40% {
          left: 500px;
          bottom: 500px;
          opacity: 1;
        }
        60% {
          left: 800px;
          bottom: 300px;
          opacity: 0;
        }
        80% {
          left: 1200px;
          bottom: 100px;
          opacity: 1;
        }
        100% {
          left: 800px;
          bottom: -200px;
        }
      }
    </style>
  </head>
  <body>
    <ul>
      <li><img src="images/jacky/1.png" alt="" /></li>
      <li><img src="images/jacky/2.jpg" alt="" /></li>
      <li><img src="images/jacky/3.jpg" alt="" /></li>
      <li><img src="images/jacky/4.gif" alt="" /></li>
      <li><img src="images/jacky/5.jpg" alt="" /></li>
      <li><img src="images/jacky/6.jpg" alt="" /></li>
    </ul>
    <img src="images/jacky/xin.png" class="heart" />
    <audio
      src="images/jacky/江哥最爱的歌.mp3"
      autoplay="autoplay"
      loop="loop"
    ></audio>
  </body>
</html>

五.总结

  • 可以用css transform属性实现平移、变形、旋转;其中旋转默认情况下,是z轴,也可以改变轴向,rotateX(); rotateY();但是为了看到效果,要加上perspective属性。
  • 一般情况使用css transition就可以实现很多人为触发的动态效果,可以快速使用 transition: all 1s;实现过渡效果,也可配合translate实现过渡效果 transition: translate 1s;,要注意的是这段代码写在元素上和悬停状态会产生不一样的效果。
  • css animation我们一般用的很少,但至少要知道他是怎么用的,首先定义关键帧函数, 然后把animation-name:函数名;属性附加到元素上。就可以使用了。
  • 以上是简单的总结,如果需要更详细的信息,可以好好参考下这篇文章。