CSS3 提供了丰富的动画类属性, 使我们可以不通过 flash 甚至 JavaScript, 就能实现很多动态的效果. 它们主要分为三大类: transform(变换),transition(过渡),animation(动画). 其中 transform 又分为 2D 变换和 3D 变换, 它赋予了我们不通过专业设计软件制作平面或者立体图形的能力.
一 过渡
通过给元素设置 transition 属性设置它的过渡效果. 过渡实际定义的是元素从一种状态变成另一种状态的过程, 比如宽度从 100px 变成 300px, 背景颜色从 red 变成 orange 等等.
- div{
- width:200px;
- height:200px;
- background-color:red;
- transition-property:width,background-color;
- /* 该属性指定需要变换的元素属性, 不同属性用逗号隔开 */
- transition-duration:1s;
- /* 该属性指定整个过程花费的时间, 如需单独为每个变化的属性设置时间, 请使用逗号隔开 */
- transition-timing-function:ease;
- /* 该属性设置变化的速度曲线, 默认值即是 ease, 表示慢 - 快 - 慢, 还有几个其他的取值: linear, 匀速; ease-in, 慢 - 快, ease-out, 快 - 慢, ease-in-out, 慢 - 快 - 慢, 肉眼效果和 ease 相似 */
- transition-delay:1s;
- /* 延迟时间 */
- }
元素的属性设置好以后, 需要某些操作触发了指定属性的变化才能看到效果, 必如: hover, 或者 JS 事件.
另外, transition 实际是一个复合属性, 多个属性过渡可以简写:
- div{
- width:200px;
- height:200px;
- transition:width 2s 1s,background-color 2s;
- /*transition-property 和 transition-duration 是必须的, 另外两个是可选的 */
- }
- div:hover{
- width:400px
- }
当有多个属性需要设置过渡, 并且持续事件, 速度曲线, 延迟时间均相同时, 你可以如下简写:
- div{
- /*some code*/
- transform:all 2s;
- /* 所有发生变化的属性都设置过渡效果 */
- }
二 动画
动画其实和过渡一样, 都是用来给元素设置动态效果的, 不同的是, 过渡需要人为的触发才能被执行, 而这里将要讲解的动画不需要人为触发.
在给元素设置动画之前, 我们首先应该创建一个动画效果, 即开始是什么状态, 结束是什么样的状态.
- @keyframes sport{/*sport 是动画的名称, 可以自定义 */
- from{
- width:200px;
- }
- to{
- width:400px;
- }
- /* 除了使用 from...to 的方式, 你还可以使用百分比创建更加丰富的动画过程, 0% 表示开始时, 100% 表示结束时 */
- }
创建好动画之后, 你就可以为元素设置诸如动画持续时长, 速度曲线, 重复次数等属性了.
- div{
- animation-name:sport;
- /* 规定元素需要执行的动画名称, 即使用 @keyframs 创建的那个 */
- animation-duration:5s;
- /* 规定动画完成一个周期所花费的秒或毫秒 */
- animation-timing-function:ease;
- /* 规定动画的速度曲线, 可选值同过渡 */
- animation-delay:3s;
- /* 规定动画延迟时间 */
- animation-iteration-count:5;
- /* 规定动画被播放的次数, infinite 表示一直循环播放 */
- animation-direction:alternate;
- /* 规定动画是否在下一周期逆向地播放, normal 是默认取值, 表示不逆向播放, 逆向播放一次也会在 animation-iteration-count 属性值中减 1*/
- animation-play-state:paused;
- /* 规定动画是否正在运行或暂停, 默认值是 running, 表示正在运行 */
- animation-fill-mode:forwards;
- /* 规定动画结束后元素的状态, forwards, 保持动画停止时的状态, backwards, 回到开始时的状态, none, 保持默认. 一般没有指定该属性时, 动画结束后会回到开始时的状态. 不同浏览器可能有不同表现 */
- }
三 2D 变换
通过给元素设置 transform 属性, 可以对元素进行 2D 变换. 很多地方把 transform 翻译成转换, 该单词在英语中的含义是使改变, 使变形. 我更倾向于把它翻译成变换, 通过 CSS 变换, 我们可以对元素进行移动, 缩放, 转动, 拉伸等操作.
- 1,translate(x,y)
- div{
- transform:translate(50px,100px);
- }
- /*div 在水平方向移动 50px, 垂直方向移动 100px*/
translate 方法接收两个参数, 分别表示在水平和垂直正方向上的偏移量, 可以接收负值, 表示向反方向偏移.
- 2,rotate(deg)
- div{
- transform:rotate(30deg);
- }
- /* 顺时针方向旋转元素 30 度 */
rotate 方法接收一个参数, 表示元素旋转的角度, 可以接收负值, 表示逆时针方向旋转. rotate 方法实际是通过修改元素的坐标系来达到旋转元素的目的, 比如:
- div{
- transform:rotate(45deg) translate(50px,0);
- /* 多属性复合形式写法 */
- }
- /* 元素先旋转 45 度, 然后向浏览器 x 轴正方向偏下 45 度的方向移动 50px*/
默认情况下, 元素都是以自己的中心点为圆心旋转, 我们可以通过 transform-origin 属性修改该参考点.
- div{
- width:200px;
- height:200px;
- transform:rotate(30deg);
- transform-origin:0px 0px;/* 以左上角为圆点旋转 */
- /* 取值 200px 0px 即以右上角为圆点旋转. 改属性取值也可以是百分比或关键字. top,botton,left,right,center*/
- }
- 3,scale(x,y)
- div{
- transform:scale(2,3);
- }
- /* 元素宽度放大 2 倍, 高度放大 3 倍 */
scale 方法接收两个参数, 分别表示元素宽高需要缩放的比例, 如果参数介于 0 到 1 之间则表示缩小, 如果小于 0, 实际效果相当于翻转元素, 感兴趣的朋友可以自行测试, 观察效果.
- 4,skew(x,y)
- div{
- transform:skew(30deg,30deg);
- }
- /* 元素在水平和垂直方向均倾斜 30 度 */
skew 方法接收两个参数, 分别表示 X 轴和 Y 轴倾斜的角度, 如果第二个参数为空, 则默认为 0, 参数为负表示向相反方向倾斜.
四 3D 变换
要想使元素以 3D 效果呈现, 你可以给元素的父元素添加 transform-style 属性.
- .father{
- transform-style:preserve-3d;
- }
- .son{
- /*some code*/
- }
transform-style 属性的默认值是 flat, 即平面的意思. 通过设置其值为 preserve-3d 即可让子元素以 3D 模式呈现.
事实上, 我们是通过配合使用 rotate 方法, 最终实现 3D 立体效果的.
我们知道, 在 2D 空间, 坐标轴只有 x 和 y 两根轴, 而在 3D 空间, 一共有 x,y,z 三根轴. 我们上面讲解的 rotate 方法实际上都是围绕 z 轴在旋转, 这也是该方法的默认方式. 另外, 其实我们还可以通过 rotateX(),rotateY(), 改变元素默认的旋转轴向. 改变旋转轴向配合 perspective 属性使用效果更佳.
- .father{
- perspective:500px;
- /*perspective 属性取值是一般是一个像素值, 设置后可以实现旋转后元素近大远小的效果 */
- }
- .son{
- width:200px;
- height:200px;
- transform:rotateX(45deg);
- }
- /* 注意, perspective 属性需要设置在旋转元素的祖先元素上, 通常我们把它设置在其父元素上.*/
下面是两个 3D 立方体的示例代码:
html 部分:
- <div class="D3">
- <ul>
- <li>1</li>
- <li>2</li>
- <li>3</li>
- <li>4</li>
- <li>5</li>
- <li>6</li>
- </ul>
- <ul>
- <li>1</li>
- <li>2</li>
- <li>3</li>
- <li>4</li>
- <li>5</li>
- <li>6</li>
- </ul>
- </div>
CSS 部分:
- body{
- background-color: #ccc;
- perspective: 800px;
- }
- .D3{
- width:550px;
- height: 200px;
- margin:100px auto;
- }
- @keyframes sport{
- from{
- transform: rotateX(0deg) rotateY(0deg);
- }
- to{
- transform: rotateX(360deg) rotateY(360deg);
- }
- }
- .D3 ul{
- width: 200px;
- height: 200px;
- position: relative;
- transform-style: preserve-3d;
- transform: rotateX(0deg) rotateY(0deg);
- animation: sport 10s linear infinite alternate;
- display: inline-block;
- margin-left:50px;
- }
- .D3 ul li{
- list-style: none;
- width:200px;
- height: 200px;
- position: absolute;
- opacity: 0.3;
- font-size: 100px;
- line-height: 200px;
- text-align: center;
- }
- .D3 ul li:nth-child(1){
- background-color: red;
- transform:translateZ(100px);
- }
- .D3 ul li:nth-child(2){
- background-color: blue;
- transform: rotateX(90deg) translateZ(100px);
- }
- .D3 ul li:nth-child(3){
- background-color: yellow;
- transform: rotateX(180deg) translateZ(100px);
- }
- .D3 ul li:nth-child(4){
- background-color: pink;
- transform: rotateX(270deg) translateZ(100px);
- }
- .D3 ul li:nth-child(5){
- background-color: purple;
- transform: rotateY(90deg) translateZ(-100px);
- }
- .D3 ul li:nth-child(6){
- background-color: green;
- transform: rotateY(90deg) translateZ(100px);
- }
- /* 还记得吗? rotate 方法是通过改变坐标系来达到旋转的目的哦!*/
五 transform 对其他元素的影响
1, 提高显示优先级
我们知道, 在标准文档流中, 如果使用负的 margin 值可以使一个元素覆盖在另一个元素上, 正常情况下是写在后面的元素覆盖前面的. 但是设置了 transform 属性的元素会覆盖其他元素.
- .top{
- width: 100px;
- height: 100px;
- background-color: red;
- transform: rotate(0deg);
- }
- .bottom{
- width: 100px;
- height: 100px;
- background-color: blue;
- margin-top:-50px;
- }
- /* 红色的会覆盖蓝色的 div 50px*/
2, 改变 fixed 定位的相对对象
通常情况下, 使用了 position:fixed; 属性的元素都会相对浏览器窗口定位, 不受滚动条的影响. 但是当我们给其父元素设置了 transform 属性后, 这一状况被改变了.
- .father{
- width: 500px;
- height: 500px;
- margin-left: 100px;
- margin-top: 100px;
- border: 1px solid #000;
- transform: rotate(0deg);
- }
- .son{
- position: fixed;
- top: 50px;
- left:50px;
- width: 100px;
- height: 100px;
- background-color: red;
- }
- /*.son 不再以浏览器窗口作为参考点, 而是以其父元素. father 作为按参考点了 */
3, 改变 absolute 定位元素的宽度
以前, 如果一个元素设置了绝对定位, 并且宽度设置为 100%, 那么该元素的实际宽度是第一个有定位属性的祖先元素的宽度, 没有则是 body 的宽度. 现在, 如果第一个有定位属性的祖先元素和绝对定位元素之间, 有一个设置了 transform 属性的元素, 那么绝对定位元素的宽度继承链将在该 transform 祖先元素处被截断, 最终绝对定位的元素宽度将继承自 transform 元素.
- .grand{
- width: 500px;
- height: 500px;
- border: 1px solid #000;
- position: absolute;
- }
- .father{
- width: 100px;
- height: 100px;
- background-color: red;
- transform:rotate(0deg);
- }
- .son{
- width: 100%;
- height: 200px;
- position: absolute;
- background-color: yellow;
- }
- /*.son 的宽度不是 500px, 而变成了 100px*/
写在最后, transform 是 CSS3 才引入的属性, 不同浏览器对它的实现也可能有差异, 上面介绍的内容并不能保证在所有浏览器上均有相同的表现, 具体情况请大家自行测试 (我仅在 Chrome 76 测试).
来源: https://www.cnblogs.com/ruhaoren/p/11596523.html