先来看MDN给出的定义
MDN
CSS transform属性允许你旋转,缩放,倾斜或平移给定元素。这是通过修改CSS视觉格式化模型的坐标空间来实现的。
The transform CSS property lets you rotate, scale, skew, or translate an element. It modifies the coordinate space of the CSS visual formatting model.
一点简介
-
取值
默认值|
none矩阵|
matrix()\matrix3d()转换|
translate\translateX\translateY\translateZ\translate3d缩放|
scale\scaleX\scaleY\scaleZ\scale3d旋转|
rotate\rotateX\rotateY\rotateZ\rotate3d倾斜|
skew\skewX\skewY透视|
perspectivetips:
1.可组合使用,值与值间空格隔开,组合值`transform:skew() rotate() scale()...`,执行顺序从右至左(待考究)2.
skew没有3D属性支持性
-
2D
- 3D
相关属性
transform-origin
transform-box
其它\可以用来做些什么
-
transform 不会引起回流与重绘
关于回流(reflow)与重绘(repaint),网上的文章基本都是定义以及如何避免等文字性描述,如何确定是否产生了回流or重绘却很少有人提及,我自己写了个小例子
Chrome开一个匿名窗口
先来看不使用transform实现的动画,这边直接用改变top值来做
<head> <style> #test{ height:20px; width:20px; animation:test1 ease-in-out 3s infinite; background:#000; position:absolute } @keyframes test1{ 0%{ top:0 } 100%{ top:200px } } </style> </head> <body> <div id="test"> </div> </body>打开Chrome控制台进到Performance页点击Record开始
这边随缘停止了一下看到以下结果
首先来看Summary的结果
可以看到rendering和painting占用了不少时间进到event log看下
可以看到浏览器一直在paint和composite layers 也就是一直在重绘(repaint)改用transform试一下
<head> <style> #test{ height:20px; width:20px; animation:test1 ease-in-out 3s infinite; background:#000; position:absolute } @keyframes test1{ 0%{ transform:translateY(0) } 100%{ transform:translateY(200px) } } </style> </head> <body> <div id="test"> </div> </body>直接来看Summary
时间差了一点不过影响不大,会发现paint和render事件消失了,可以证明transform确实是不会触发重绘其实除了我写的这处区别外在performance控制台还有好几处区别,具体的大家可以自己试一哈
-
transform实现水平垂直居中
由第一个例子可以了解到,使用
transform:translate()改变位置与直接改变元素top值效果一样,所以transform也可以用来实现水平垂直居中{ position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%); } -
transform:scale()来满足各种需求
最近换了工作,一起配合的UI设计师非常严格,会把你的实现和UI设计稿叠在一起check,很是头痛,尤其是出了一个0.3px圆角边框的需求,试过很多种方法效果都不是十分满意(和UI图对不上),最后选择用scale()来做,感动的设计师都哭了
这边用到的是after伪类来做边框
.test::after{ position:absolute; top:0; left:0; box-sizing:border-box; width:300%; height:300%; border:1px solid #b4b4b4; border-radius:9px; content:" "; transform:scale(.33333,.33333); transform-origin:0 0 }需要注意的是不光长宽需要等比放大,圆角的值也是需要的
另外在Android手机,小于
12px的文字垂直居中有着怪异的表现(偏上),除了用table布局外还可以用transform:scale先把元素放大在缩小的方式来解其实13px的字体在某些机型的安卓上垂直居中也不行,也可以用这种方法解决
-
transform:transition()模拟列表滚动
最后要说的是我最近遇到的一个比较棘手的问题,需求简单来说就是在微信和QQ里禁止滑动漏出“由xx.xx.xx提供的网页”的这句话,但是页面里还有一个滑动的列表。
简单说一下出现的问题:
办法1:全局禁止滑动,列表touchstart时取消禁止,touchend时恢复禁止,touchmove方向位置等做监听 问题:我能想到的第一个办法,但在Android的QQ里触摸事件和我想象的完全不一样,在列表直接下拉确实没问题,先向上滑再往下滑居然就不行了 办法2:touch-action限制滑动行为 问题:看到这个css属性我以为救星来了,但不适用于此处,都是y方向动的,要禁止都禁止了各种方案最后都在安卓QQ上折了,没办法只能转换思路,放弃浏览器默认的
overflow:scroll,改用transform来做以为我这边是用vue做的所以代码的话就不直接给出了
简单的实现方案就是
// html
<div class="外部"> <div class"内部"> 其他滚动元素 </div> </div>当前滚动值 = transformY 上一次touch事件滚动值 = lastY 当前touchstart时Y点 = startY 当前touchmove时Y值 = moveY1.依旧全局禁止滑动,把外部元素原来的
overflow:scroll改为hidden2.监听touchstart事件获得startY
3.监听touchmove事件获得moveY
4.lastY 初始值为0
5.touchmove非顶部与底部时:transformY = lastY + moveY - startY
6.touchmove时顶部判断与底部判断
//顶部向上滑 ``` if(transformY >= 0 && moveY > startY){ transformY = 0 lastY = 0 touchY = curY } ``` //底部向下滑 ``` if(内部.clientHeight - 外部.clientHeight + transformY <= 0)&&moveY < startY){ transformY = -(内部.clientHeight - 外部.clientHeight); lastY = transformY startY = moveY } ```7.监听touchend事件,lastY = transformY
大功告成,亲测在棘手的安卓qq上可完美实现滑动列表效果,至于回弹等效果也可以扩展。