目录
transform属性
- 在CSS中,利用transform这个属性实现对元素进行旋转、缩放、倾斜或平移
- transform属性的值可以是none或一个或多个css变换函数
- transform的值不是none时,元素会创建自己的层叠上下文
transform的2D变换函数
属性值 | 描述 | 实例 |
---|---|---|
translate(x,y) | x,y 为长度单位,可以是 px,也可以是百分比%, x 表示元素在 x 轴上的移动量 y 表示元素在 y 轴上的移动量,如果 y 值不写,则默认为 0,例如 translate(10px)表示 translate(10px,0) | transform:translate(100px,200px) |
translateX(x) | x 为长度单位,可以是 px,也可以是百分比% 表示元素在平面 x 轴上的位移量 | transform:translateX(300px) |
translateY(y) | y 为长度单位,可以是 px,也可以是百分比% 表示元素在平面 Y 轴上的位移量 | transform:translateY(200px) |
rotate(ax) | ax 代表旋转的角度 正角表示顺时针旋转 负角表示逆时针旋转 | transform:rotate(30deg) |
scaleX(x) | x 数字类型,表示元素在 x 轴上的缩放比 | transform:scaleX(2) |
scaleY(y) | y 数字类型,表示元素在 y 轴上的缩放比 | transform:scaleY(2) |
scale(x,y) | x 数字类型,表示元素在 x 轴上的缩放比 y 数字类型,表示元素在 y 轴上的缩放比 当只有 x,没有 y 时,则 y 默认为 x,元素在 x,y 轴上均匀缩放 | transform:scale(2,3) |
skew(ax,ay) | ax 表示一个角度,表示沿着 x 横坐标扭曲元素的角度 ay 表示一个角度,表示沿着 y 纵坐标扭曲元素的角度 | transform:skew(30deg,30deg) |
skewX(ax) | ax 表示一个角度,表示沿着 x 横坐标扭曲元素的角度,形成水平拉伸效果 | transform:skewX(30deg) |
skewY(ay) | ay 表示一个角度,表示沿着 y 纵坐标扭曲元素的角度,形成垂直拉伸效果 | transform:skewY(30deg) |
transform的3D转换属性值
属性值 | 描述 | 实例 |
---|---|---|
translateZ(z) | x 为 px 长度单位 元素在 3D 空间 z 轴方向上的位移量 | transform:translateZ(200px) |
translate3d(x,y,z) | x,y,z 分别为 px 长度单位 x 表示元素在 x 轴坐标上的位移量 y 表示元素在 y 轴坐标上的位移量 z 表示元素在 z 轴坐标上的位移量,该值不能使用百分比,如果使用会被认为是无效属性 | transform:translate3d(50px,30px ,50px) |
rotateX(ax) | 表示元素绕X 轴旋转一定的角度ax 表示度数,可以为正,也可以为负 | transform:rotateX(30deg); |
rotateY(ay) | 表示元素绕Y 轴旋转一定的角度ay 表示度数,可以为正,也可以为负 | transform:rotateY(30deg) |
rotateZ(az) | 表示元素绕Z 轴旋转一定的角度ax 表示度数,可以为正,也可以为负 | transform:rotate(30deg); |
2D转换
我们先来了解一下2D平面
下图里的x和y轴,就是基于2D平面图形
后期的所有2D动画特效都是在这个2D的平面操作
注意:
- 元素的左上角坐标为(0,0)
- (0,0)坐标的右方,为x轴的正方向
- (0,0)做表的下方,为y轴的正方向
translate位移
css中通过给transform添加translate(x,y)或translateX(x)或translateY(y)来实现元素的水平或垂直位移
属性值 描述 举例 translate(x,y) 实现元素水平和垂直位移量 translate(30px,50px) translateX(x) 实现元素水平位移量 translateX(30px) translateY(y) 实现元素垂直位移量 translateY(50px)
translate(x,y)
- x和y是长度值length,可以是px,也可以是%百分比
- x表示元素在x轴上的位移量,正表示向右移动,负表示向左移动
- y表示元素的y轴上的位移量,正表示向下移动,负表示向上移动
- 位移和相对定位非常像,位移变形也会“老家留坑”,机会占据原来的位置
- 同时不会对其它元素造成影响,相当于悬浮在其它元素上面
x,y为px长度单位
<style>
.box {
width: 100px;
height: 100px;
}
.box1 {
background-color: tomato;
/* 元素水平向右移动50px,向下移动50px */
transform: translate(50px, 50px);
}
.box2 {
background-color: khaki;
}
</style>
<body>
<div class="box box1"></div>
<div class="box box2"></div>
</body>
未添加transform | 添加transform |
---|---|
![]() | ![]() |
x,y为%百分比
- x和y为%百分比,这个百分比分别是相对元素自身的可视宽和可视高而言
- 在标准盒子模型下:
- 水平位移 = (width + 左右padding + 左右border) * x%
- 垂直位移 = (heigt + 上下padding + 上下border) * y%
<style>
.box {
width: 200px;
height: 100px;
}
.box1 {
padding: 25px;
border: 25px solid skyblue;
background-color: tomato;
/*
水平位移=(200+25*2+25*2)*50%=150px
垂直位移=(100+25*2+25*2)*25%=50px;
即:translate(50%,25%)等同于translate(150px,50px)
*/
transform: translate(50%, 25%);
}
.box2 {
background-color: khaki;
}
</style>
<body>
<div class="box box1"></div>
<div class="box box2"></div>
</body>
效果:
y值不写,默认为0
<style>
.box {
width: 100px;
height: 100px;
}
.box1 {
background-color: tomato;
/*
水平位移=100*50%=50px
垂直位移=0
*/
transform: translate(50%);
}
.box2 {
background-color: khaki;
}
</style>
<body>
<div class="box box1"></div>
<div class="box box2"></div>
</body>
效果:
translateX(x)与translateY(y)
- translateX(x)实现元素在x轴的位移量
- translateY(y)实现元素在y轴的位移量
- 本质上translate(x,y)是translateX与translateY两者的复合写法
- transform后面如果跟多个变换函数,则各函数之间用空格隔开
<style>
.box {
width: 100px;
height: 100px;
}
.box1 {
background-color: tomato;
/*
水平向右移动50px
垂直向下移动30px
*/
transform: translateX(50px) translateY(30px);
}
.box2 {
background-color: khaki;
}
</style>
<body>
<div class="box box1"></div>
<div class="box box2"></div>
</body>
效果:
translate与绝对定位结合实现元素水平垂直居中
使用translate移动,可以不再使用“margin-top”与“margin-left”实现居中,超级方便
/* 先利用绝对定位 让元素的顶部和左侧分别与父元素垂直和水平中间对齐 然后再利用translate,让元素向上和向左移动自身宽度的一半 这样就实现了水平和垂直居中 */ position: absolute; top: 50%; left: 50%; /* 向左和向上分别移动元素自身宽和高的一半 */ transform: translate(-50%, -50%);
scale(x,y)
- x,y都是数字类型,可以用百分比%表示,分别表示元素的宽和高缩放比
- 当x,y值 > 1时,表示放大,< 1时,表示缩小, = 1表示不变
- 当只有x,没有y时,则y默认为x,元素宽高同时均匀缩放
<style>
.box {
width: 100px;
height: 100px;
background-color: khaki;
margin: 150px;
}
.item {
width: 100px;
height: 100px;
background-color: rgb(255, 99, 71, 0.5);
/* 宽放大2倍,高放大1.5倍 */
transform: scale(2, 1.5);
/* 宽高同时放大2倍 */
transform: scale(2);
/* 宽缩小一半,高放大2倍 */
transform: scale(0.5, 2);
}
</style>
<body>
<div class="box">
<div class="item"></div>
</div>
</body>
scale(2,1.5) | scale(2) | scale(0.5,2) |
---|---|---|
![]() | ![]() | ![]() |
百分比单位
- x%和y%分别相对于元素的可视宽和可视高而言
- 在标准盒子模型下
- 宽缩放后大小 =(width + 左右 padding + 左右 border) * x%;
- 高缩放后大小 =(height + 上下 padding + 上下 border) * y%
<style>
.box {
width: 150px;
height: 150px;
/* 背景颜色 黄色 */
background-color: khaki;
margin: 150px;
}
.item {
width: 50px;
height: 50px;
padding: 25px;
border: 25px solid rgb(243, 147, 147, 0.9);
/*
宽放大2倍,高缩小一半
宽缩放后大小=(50+25*2+25*2)*200%=300px
高缩放后大小=(50+25*2+25*2)*50%=75px
*/
transform: scale(200%, 50%);
}
</style>
<body>
<div class="box">
<div class="item"></div>
</div>
</body>
scale(200%,50%)0 | scale(200%) |
---|---|
![]() | ![]() |
scaleX(x)与scaleY(y)
- scaleX(x) 实现元素的宽缩放效果
- scaleY(Y) 实现元素高缩放效果
- 本质上 scale(x,y)是 scaleX(x) 与 scaleY(y)的复合写法
/* transform:scale(x,y) 同等于 transform:scaleX(x) scaleY(y); */ transform: scaleX(x) scaleY(y);
<style>
.box {
width: 100px;
height: 100px;
background-color: khaki;
margin: 150px;
}
.item {
width: 100px;
height: 100px;
background-color: rgb(255, 99, 71, 0.5);
/* 宽放大两倍,高缩小一半 */
transform: scaleX(2) scaleY(0.5);
}
</style>
<body>
<div class="box">
<div class="item"></div>
</div>
</body>
skew斜切
- css中通过给“transform”添加“skew(ax,ay)”或“skewX(ax)”或“skewY(ay)”变换函数来实现元素斜切效果
- skewX(ax):用于水平拉伸,使元素的每个点在水平方向上扭曲一定角度
- skewY(ay):用于垂直拉伸,使元素的每个点在垂直方向上扭曲一定角度
- skew(ax,ay):用于水平和垂直拉伸,使元素在水平和垂直方向上扭曲一定角度
- ax:表示一个角度,沿着横坐标扭曲元素的角度
- ay:表示一个角度,沿着纵坐标扭曲元素的角度
skewX(30deg) | skewX(-30deg) | skewY(30deg) | skew(30deg,30deg) |
---|---|---|---|
![]() | ![]() | ![]() | ![]() |
rotate旋转
- css中通过给“transform:rotate(ax)”来表示元素旋转效果
- ax表示旋转的角度,比如rotate(45deg)
- ax为正,表示顺时针方向旋转
- ax为负,表示逆时针方向旋转
<style>
.body,
ul {
margin: 0;
padding: 0;
}
ul {
list-style-type: none;
}
ul li {
width: 100px;
height: 100px;
border: 2px solid red;
margin: 20px;
float: left;
}
.item {
height: 100%;
background-color: khaki;
}
.item1 {
/* 顺时针旋转到30deg */
transform: rotate(30deg);
}
.item2 {
/* 逆时针旋转到30deg */
transform: rotate(-30deg);
}
.item3 {
/* 顺时针旋转到180deg */
transform: rotate(180deg);
}
.item4 {
/* 顺时针旋转30deg */
transform: rotate(450deg);
}
</style>
<body>
<ul>
<li>
<div class="item item1">30deg</div>
</li>
<li>
<div class="item item2">-30deg</div>
</li>
<li>
<div class="item item3">180deg</div>
</li>
<li>
<div class="item item4">450deg</div>
</li>
</ul>
</body>
效果:
transform-origin
- transform-orgin属性,设置元素的变换原点,即元素在交换时是以围绕那个点来发生变换的
- 默认值:transform-origin:50% 50% 0
- x,y的值可以使长度值(px或百分比%)还可以是预设的关键词
- z的值只能是长度值pc
/* x: 表示x轴的坐标位置 y: 表示y轴的坐标位置 z: 表示z轴的坐标位置 */ transform-orign: x y z;
注意:
在2D转换中,元素的默认变换原点为元素的中心(transform:50% 50%)
关键字表示
关键词(left、right)与(top、bottom)与center三组中任意一个与另一组中的一个关键字组合来表示
关键 字 | 描述 |
---|---|
left | 原点为元素左边中间位置,同left center 一样 |
right | 原点为元素右边中间位置,同right center 一样 |
top | 原点为元素上边中间位置,同top center 一样 |
bottom | 原点为元素下边中间位置,同bottom center 一样 |
center | 原点为元素中间位置,同center center 一样 |
top left | 原点为元素左上角,相当于坐标(0 0) |
top right | 原点为元素右上角 |
left bottom | 原点为元素左下角 |
right bottom | 原点为元素右下角 |
元素的默认变换原点为元素的中间位置“transform-origin:center;”
<style>
.body,
ul {
margin: 0;
padding: 0;
}
ul {
list-style-type: none;
margin: 50px;
}
ul li {
width: 100px;
height: 100px;
border: 2px solid red;
margin: 40px;
float: left;
}
.item {
height: 100%;
background-color: khaki;
/* 顺时针旋转60deg */
transform: rotate(60deg);
}
.item1 {
/* 旋转的原点 */
transform-origin: top;
}
.item2 {
/* 旋转的原点 */
transform-origin: right;
}
.item3 {
/* 旋转的原点 */
transform-origin: bottom;
}
.item4 {
/* 旋转的原点 */
transform-origin: left;
}
.item5 {
/* 旋转的原点 */
transform-origin: center;
}
</style>
<body>
<ul>
<li>
<div class="item item1">top</div>
</li>
<li>
<div class="item item2">right</div>
</li>
<li>
<div class="item item3">bottom</div>
</li>
<li>
<div class="item item4">left</div>
</li>
<li>
<div class="item item5">center</div>
</li>
</ul>
</body>
效果
数值表示法
transform-origin: x y;
- x,y为长度单位(px或百分比%)
- 当y省略不写时,默认为元素的垂直中心点
<style>
.body,
ul {
margin: 0;
padding: 0;
}
ul {
list-style-type: none;
margin: 50px;
}
ul li {
width: 100px;
height: 100px;
border: 2px solid red;
margin: 40px;
float: left;
}
.item {
height: 100%;
background-color: khaki;
/* 元素旋转60deg */
transform: rotate(60deg);
}
.item1 {
/* 旋转的原点 */
transform-origin: 0 0;
}
.item2 {
/* 旋转的原点 */
transform-origin: 20px 20px;
}
.item3 {
/* 旋转的原点 */
transform-origin: 50px 50px;
}
.item4 {
/* 旋转的原点 */
transform-origin: 100px 0px;
}
.item5 {
/* 旋转的原点 */
transform-origin: 50px 100px;
}
</style>
<body>
<ul>
<li>
<div class="item item1">0 0</div>
</li>
<li>
<div class="item item2">20px 20px</div>
</li>
<li>
<div class="item item3">50px 50px</div>
</li>
<li>
<div class="item item4">100px 0px</div>
</li>
<li>
<div class="item item5">50px 100px</div>
</li>
</ul>
</body>
效果
百分比表示法
百分比相对的是元素自身的可视宽和可视高而言
<style>
.body,
ul {
margin: 0;
padding: 0;
}
ul {
list-style-type: none;
margin: 50px;
}
ul li {
width: 100px;
height: 100px;
border: 2px solid red;
margin: 40px;
float: left;
}
.item {
width: 100px;
height: 100px;
background-color: khaki;
transform: rotate(60deg);
}
.item1 {
/* 旋转的原点 */
transform-origin: 100%;
}
.item2 {
/* 旋转的原点 */
transform-origin: 50%;
}
.item3 {
/* 旋转的原点 */
transform-origin: 100% 0%;
}
.item4 {
/* 旋转的原点 */
transform-origin: 100% 100%;
}
.item5 {
/* 旋转的原点 */
transform-origin: 100% 50%;
}
</style>
<body>
<ul>
<li>
<div class="item item1">100%</div>
</li>
<li>
<div class="item item2">50%</div>
</li>
<li>
<div class="item item3">100% 0%</div>
</li>
<li>
<div class="item item4">100% 100%</div>
</li>
<li>
<div class="item item5">100% 50%</div>
</li>
</ul>
</body>
scale与skew都可以设置其变换原点
元素默认的转换原点为元素的中心点“transform-orgin:50% 50%;”
<style>
.box {
width: 100px;
height: 100px;
border: 2px solid red;
margin: 150px;
}
.item {
width: 100px;
height: 100px;
background-color: rgb(242, 232, 147, 0.5);
transform: scale(2);
/* 原点左上角 */
transform-origin: 0 0;
/* 原点右边中间 */
transform-origin: 100%;
}
</style>
<body>
<div class="box">
<div class="item"></div>
</div>
</body>
效果
2D转换综合写法顺序问题
同时使用多个转换,其多个转换函数之间用空格隔开
transform: translate() rotate() scale();
转换函数的顺序会影响转换的效果,例如:“先旋转会影响坐标轴方向”
<style>
.box {
width: 100px;
height: 100px;
border: 2px solid red;
margin: 20px 150px;
}
.item {
width: 100px;
height: 100px;
}
.item1 {
/* 背景颜色为 黄色 */
background-color: khaki;
/* 先旋转,再位移 */
transform: rotate(180deg) translateX(100px);
}
.item2 {
/* 背景颜色为 天蓝色 */
background-color: skyblue;
/* 先位移,再旋转 */
transform: translateX(200px) rotate(180deg);
}
</style>
<body>
<div class="box">
<div class="item item1"></div>
</div>
<div class="box">
<div class="item item2"></div>
</div>
</body>
效果:
2D转换实战应用
旋转的三角形
<!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>
.jiantou::after {
content: "";
display: block;
width: 20px;
height: 20px;
border-right: 2px solid red;
border-bottom: 2px solid red;
transform: rotate(-135deg);
transition: transform 1s;
}
.jiantou:hover::after {
transform: rotate(45deg);
}
</style>
</head>
<body>
<div class="jiantou"></div>
</body>
</html>
效果:
鼠标滑动图片放大
<!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>
.container {
width: 200px;
height: 300px;
margin: 100px auto;
position: relative;
overflow: hidden;
}
.container::after {
content: "";
display: none;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 3;
}
.container img {
width: 200px;
height: 300px;
object-fit: cover;
transition: transform 1s;
}
.container .play {
position: absolute;
width: 50px;
height: 50px;
opacity: 0;
background-image: url("/static/play.png");
background-size: contain;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
z-index: 4;
}
.container:hover::after {
display: block;
}
.container:hover img{
transform: scale(1.2);
}
.container:hover .play{
opacity: 1;
transform: translate(-50%,-50%) scale(1.5);
}
</style>
</head>
<body>
<div class="container">
<img src="/static/jjy.png" alt="">
<div class="play"></div>
</div>
</body>
</html>
效果