这是一个系列的文章,你也可以查看其他文章:
0、CSS-预热篇
transform 属性向元素应用 2D 或 3D 转换。transform
属性允许你旋转,缩放,倾斜或平移给定元素。这是通过修改CSS视觉格式化模型的坐标空间来实现的。
只能转换由盒子模型定位的元素。根据经验,如果元素具有display: block
,则由盒模型定位元素。
属性:
transform属性虽然很多,但是可以分为以下几组:
1、matirx
位移,旋转,偏移,缩放分别使用translate/rotate/skew/scale的方式来控制元素变换,也可以使用matrix。
transform: matrix(a,b,c,d,e,f);
写成向量形式
要做变换时,实质上是乘以一个向量
变换后的坐标为
X = ax + cy + e // 即:x坐标
Y = bx + dy + f // 即:y坐标
X为变换后的水平坐标,Y表示变换后的垂直坐标。
假设中心坐标为(0,0),
平移为:
transform: matrix(0,0,0,0,50,50);
=
transform: translate(50,50);
缩放
transform: matrix(ax,0,0,by,0,0);
=
transform: scale(a, b);
旋转和偏移也都是可以用matrix表示,但因为计算较繁琐,在此不一一推导。
我们可以看出位移,旋转,偏移,缩放分别使用translate/rotate/skew/scale的方式来控制元素变换,也可以使用matrix。
2、translate、translateX、translateY
平移。
当参数设置为正数时表示正向移动,负数为反向移动,类似于 position:relative
+ margin
;这里注意,y值的设置是可以省略的,与margin、padding 省略值后表示两者值一致
不同的是,如果省略了y,则表示y的值为0。例:translate(50px)
同 translate(50px,0)
表示沿x轴向右移动50个像素,y轴不变。
注意:要使用translateZ,必须在父元素上设置perspective。
translate
还可以用做垂直居中解决方案。
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.container{
position: relative;
height:300px;
width: 500px;
border: 1px solid #000;
background: lightblue;
}
.item {
position: absolute;
background: darkgoldenrod;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
height: 30px;
width: 100px;
}
</style>
</head>
<body>
<div class="container">
<div class="item">水平垂直居中</div>
</div>
</body>
</html>
结果:
translateZ为3d平移。注意:要使用translateZ,必须在父元素上设置perspective
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.container{
position: relative;
height:300px;
width: 500px;
border: 1px solid #000;
background: lightblue;
perspective: 1000px;
}
.item {
background: darkgoldenrod;
transform: translateZ(50px);
height: 30px;
width: 100px;
}
</style>
</head>
<body>
<div class="container">
<div class="item">translateZ</div>
</div>
</body>
</html>
结果:
3、scale、scaleX,scaleY、scaleZ
缩放。等比例缩放。
允许省略y,当省略y时表示x,y等值缩放。如果只想缩放x或y轴,可以使用 scaleX(x)
, scaleY(y)
。值为 1
表示大小不变。大于1,代表放大,大于0小于1表示缩放,等于0元素消失,小于0,图形反转。
例如:scale(0.3)
等同于 scale(0.3, 0.3)
; scaleX(0.3)
等同于 scale(0.3, 1).
当为负值,则缩放元素有反转效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=<device-width>, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.container{
height: 300px;
width: 500px;
background: darkblue;
border: 1px solid yellowgreen;
}
.item{
height: 30px;
width: 100px;
background: yellow;
border: 1px solid grey;
transform: scale(-1);
}
</style>
</head>
<body>
<div class="container">
<div class="item">coolsummer</div>
</div>
</body>
</html>
结果:
4、rotate、rotateX、rotateY、rotateZ
旋转。rotate(angle)为角度旋转。但与前平移和缩放不同的是,rotateX, rotateY
和 rotateZ
都为rotate3d旋转。
rotate(angle)参数 angle
表示旋转角度,单位为 deg
;当角度为正数时表示顺时针旋转,为负数时表示逆时针旋转,来看一个例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.container{
height: 500px;
margin-top: 100px;
width: 300px;
}
div {
display: inline-block;
width: 80px;
height: 50px;
}
.rotate {
background: darkgoldenrod;
transform: rotate(30deg);
height: 30px;
width: 100px;
}
.normal{
background: red;
height: 30px;
width: 100px;
}
</style>
</head>
<body>
<div class="container">
<div class="normal">normal</div>
<div class="rotate">rotate</div>
</div>
</body>
</html>
结果:
rotateX、rotateY、rotateZ未尝试
5、skew、skewX、skewY
偏移。skew偏移允许使用一个值,当使用一个值时表示 y-angle
为0;倾斜有一个难点就是它的直角坐标系。
x轴的方向是竖直向下方向的,y轴的方向是水平向右方向的。以逆时针为正角度方向。
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.current{
margin: 100px;
width: 100px;
background: blue;
height: 100px;
transform: skewX(45deg);
}
.compare{
margin: 100px;
width: 100px;
background: darkcyan;
height: 100px;
}
</style>
</head>
<body>
<div class="current">skew</div>
<div class="compare">normal</div>
</body>
</html>
结果:
6、matrix3d、translate3d、scale3d、rorate3d
3D相关操作,待补充。。。
7、perspective
表示当前视角的位置;当 translate
值超过视距时,图像就消失了。在测试时,如果需要Z轴的都需要父元素加上这个属性才能有效果。
8、多个函数
transform: translateX(10px) rotate(10deg) translateY(5px);待补充。。。
9、全局
/* Global values */
transform: inherit;
transform: initial;
transform: unset;
transform: translate(12px, 50%);
transform: translateX(2em);
transform: translateY(3in);
transform: scale(2, 0.5);
transform: scaleX(2);
transform: scaleY(0.5);
transform: rotate(0.5turn);
transform: skew(30deg, 20deg);
transform: skewX(30deg);
transform: skewY(1.07rad);
transform: matrix3d(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0);
transform: translate3d(12px, 50%, 3em);
transform: translateZ(2px);
transform: scale3d(2.5, 1.2, 0.3);
transform: scaleZ(0.3);
transform: rotate3d(1, 2.0, 3.0, 10deg);
transform: rotateX(10deg);
transform: rotateY(10deg);
transform: rotateZ(10deg);
transform: perspective(17px);
/* Multiple function values */
transform: translateX(10px) rotate(10deg) translateY(5px);
/* Global values */
transform: inherit;
transform: initial;
transform: unset;
# Transform的前置属性
- transform-origin - 变换原点
- transform-style - 变换类型
- perspective - 3d透视视图的视距(属性)
- perspective-origin - 视距的基点
- backface-visibility - 是否可以看见舞台背面
transform
属性可以指定为关键字值none
或一个或多个<transform-function>
值。
transform影响(来自张鑫旭总结https://www.zhangxinxu.com/wordpress/2015/05/css3-transform-affect/)
1、transform提升元素的垂直地位
transform:scale(1)
个人认为此处改为“层叠等级变高更为妥当”,原理是设置了transform的元素层叠等级变高,即使另一个元素设置一个很大的z-index(1000000)仍然会被另一个未设置的元素覆盖。
/**
*在张鑫旭的示例上更进一步尝试
**/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type='text/css'>
.ml-60 {
margin-left: -60px;
}
.transform {
-ms-transform: scale(1);
transform: scale(1);
}
.z{
z-index: 1000000;
}
</style>
</head>
<body>
<p>
<img src="https://image.zhangxinxu.com/image/study/s/s256/mm1.jpg">
<img src="https://image.zhangxinxu.com/image/study/s/s256/mm1.jpg" class="ml-60">
</p>
<p>
<img src="https://image.zhangxinxu.com/image/study/s/s256/mm1.jpg" class="transform">
<img src="https://image.zhangxinxu.com/image/study/s/s256/mm1.jpg" class="ml-60 z">
</p>
</body>
</html>
2、transform限制position:fixed的跟随效果
transform:scale(1)
降级变成position:absolute,没有了固定效果,即不会随着页面的滚动而滚动
3、transform限制absolute的100%宽度大小
4、transform
属性创建层叠上下文,影响元素发生重叠时候的表现(https://www.zhangxinxu.com/wordpress/2016/01/understand-css-stacking-context-order-z-index/)
浏览器兼容性(来自MDN)
codepen上看到的一个demo,改造了下,用来作为学习使用。
html
<ul class="ch-grid">
<li>
<div class="ch-item ch-img-1">
<div class="ch-info-wrap">
<div class="ch-info">
<div class="ch-info-front ch-img-1"></div>
<div class="ch-info-back">
<div class="ch-info-space"></div>
<h4>CoolSummer</h4>
<p>by thluo <a href="#">Feed ME</a></p>
</div>
</div>
</div>
</div>
</li>
</ul>
css
.ch-grid {
margin: 20px 0 0 0;
padding: 0;
list-style: none;
display: block;
text-align: center;
width: 100%;
}
.ch-grid:after,
.ch-item:before {
content: '';
display: table;
}
.ch-grid:after {
clear: both;
}
.ch-grid li {
width: 320px;
height: 320px !important;
display: inline-block;
margin: 20px;
}
.ch-item {
width: 100%;
height: 100%;
border-radius: 50%;
position: relative;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
cursor: default;
}
.ch-info-wrap,
.ch-info {
position: absolute;
width: 280px;
height: 280px !important;
border-radius: 50%;
transition: all 0.4s ease-in-out;
}
.ch-info-wrap {
top: 20px;
left: 20px;
background: #f9f9f9 url(../images/bg.jpg);
box-shadow: 0 0 0 20px rgba(255, 255, 255, 0.2), inset 0 0 3px rgba(115, 114, 23, 0.8);
perspective: 800px;
}
.ch-info {
transform-style: preserve-3d;
}
.ch-info > div {
display: block;
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
background-position: center center;
transition: all 0.6s ease-in-out;
}
.ch-info .ch-info-front {
transform-origin: 50% 100%;
z-index: 100;
box-shadow: inset 2px 1px 4px rgba(0, 0, 0, 0.1);
}
.ch-info .ch-info-back {
background: rgba(230, 132, 107, 0);
}
.ch-img-1 {
background-image: url(http://placekitten.com/320/320);
}
.ch-info p {
color: #fff;
padding: 20px 5px;
font-style: italic;
margin: 0 30px;
font-size: 32px;
border-top: 1px solid rgba(255, 255, 255, 0.5);
}
.ch-info p a {
display: block;
color: rgba(255, 255, 255, 0.7);
font-style: normal;
font-weight: 700;
text-transform: uppercase;
font-size: 21px;
letter-spacing: 1px;
padding-top: 20px;
font-family: 'Open Sans', Arial, sans-serif;
}
.ch-info p a:hover {
color: rgba(255, 242, 34, 0.8);
}
.ch-info p:hover {
color: rgba(38, 155, 200, 1);
}
.ch-info h3:hover {
color: rgba(38, 155, 200, 1);
}
.ch-item:hover .ch-info-front {
transform: rotate3d(1, 0, 0, -180deg);
box-shadow: inset 0 0 5px rgba(255, 255, 255, 0.2), inset 0 0 3px rgba(0, 0, 0, 0.3);
}
.ch-item:hover .ch-info-back {
background: rgba(230, 132, 107, 0.6);
}
.ch-info-space{
height:50px;
}