transform
是诸多css3新特性中最打动个人,由于它让方方正正的box model变得真实了。javascript
transform经过一组函数实现了对盒子大小、位置、角度的2D或者3D变换。不过很长时间内,我对如下问题都想不太明白:css
一、尺寸缩放 scale
与 zoom
变换有何不一样,为何被 scale
的盒子里的内容不会错位,但 zoom
不是。html
二、位移( transform:translate
)与相对定位、绝对定位( position:relative | absolute
)有何关系?java
三、在实际项目中发现,位图(不管是 background-image
仍是 img
)在被transform后会模糊掉,尤为是 scale
;不只如此,在一些网站,好比tmall.com,即便是矢量的svg文件在使用 transform
后,依然模糊了, transform
是否对做用的盒子进行了相似栅格化的操做?css3
四、在实际项目中发现,若是父级元素使用了 transform
且其中的子元素进行了 position:fixed
定位,那么设置了 position:fixed
的子元素将再也不基于窗口定位。web
五、这种场景暂时未能重现,在chrome下:父级元素使用了 position:fixed
,子元素 <a href=".."></a>
设置了 :hover
伪类、 transition
过渡动画、并使用javascript动态添加/删除其class,此时会出现 :hover
样式失效或添加的class样式失效且 transition
过渡动画失效的现象。chrome
等等。express
在网上查看了一些大神的博客, transform
是经过一系列矩阵变换完成的,scale等transform-function都是对matrix的封装,w3c里没找到有关说明。对于线性代数里的东西,博主表示很是小白,其中的数学原理,仍是交给其余人去解释吧o(︶︿︶)o canvas
w3c里的解释是,transform基于可视化格式模型(visual formatting model,这样翻译对不对啊)并为其绘制出一个坐标系,并且全部在这个坐标系内进行的操做,如向右向下,都是在这个坐标系内以像素方式表示,原文:浏览器
The CSS visual formatting model describes a coordinate system within each element is positioned. Positions and sizes in this coordinate space can be thought of as being expressed in pixels, starting in the origin of point with positive values proceeding to the right and down.
那是否是意味着scale缩放,是否只是像素意义上的缩放呢?由此,因缩放致使的svg等矢量内容模糊失真是情理之中了?ಠ_ಠ
我的猜想,应该先转换成像素,而后进行渲染,这应该和每一个浏览器具体渲染过程有关,相关文档我没有查,若是有知道的,请给我留言。
要理解transform,还有一个事情要搞清楚,就是visual formatting model,借助谷歌度娘,找到了w3chelp上的中文版解释:
可视化格式模型是很是抽象的概念。它是 CSS 布局的核心,经过它,框( box )能够得到应有的尺寸,放到须要的位置。
咱们一般所看到的页面都是平面 2D 的效果,但可视化模型倒是 3D 的,除了 X 轴,Y 轴,还有决定元素显示顺序1的 Z 轴。 Z 轴垂直穿过计算机屏幕,面向用户的一侧是正轴,框在 Z 轴方向上离用户越近,显示越是靠前。
可视化格式模型的官方说法是,它规定了用户端在媒介中如何处理文档树( document tree )
……本部分会涉及不少新概念,如包含块、元素的类型、定位体系、块级格式化上下文、行内格式化上下文、浮动、绝对定位和 z-index,以及可视化格式模型的细节部分,自动宽度高度的计算等。
博主第一次听到visual formatting model这个概念,但看了解释应该知道,这不是一个新概念,姿式水平捉急了ಠ_ಠ
根据这个解释,元素设置了 transform
并不会改变元素所在的文档流,其布局仍然受盒模型支配,所以这里的变换的效果是能够与浮动、定位并存的。
当元素设置了transform后,会为该元素定义一个坐标系,而且在该坐标系内进行矩阵变换,将变换结果映射到用户坐标系(也就是实际上的上下文)中。
多个矩阵变换函数将依次从左到右计算,如 transform:translate(80px, 80px) scale(1.5, 1.5)
,浏览器会先计算位移,再缩放1.5倍。如下两种代码效果相同:
<div style="transform: translate(80px, 80px)"> <div style="transform: scale(1.5, 1.5)"> <div style="transform: rotate(45deg)"></div> </div> </div>
<div style="transform: translate(80px, 80px) scale(1.5, 1.5) rotate(45deg);"> </div>
坐标原点的位置受属性 transform-origin
的影响。
若是是3D变换,则还会将其加入一个3D渲染上下文(3D rendering context)。根据我的理解,不管有多少个转换为3D的元素,其将始终在这个上下文内并可能相互影响,相似一个文档中的多个被绝对定位的元素。
任何非none的transform值都会致使一个堆叠上下文(stacking context)和包含块(containing block)的建立。
不过,并不意味着和谐,否则怎么会有那么多坑问题嘛!(,,Ծ▽Ծ,,)
若是元素由于transform而撑开了父级元素,父级元素会根据自身的 overflow
属性决定是否出现滚动条、隐藏溢出的部分或是别的什么。
另外,根据规范,因为堆叠上下文的建立,该元素会影响其子元素的固定定位:被设置 position:fixed
的子元素将不会基于viewport定位,而是基于这个父元素。
咱们知道,通常状况下,全部的position值不为static的元素都会被放到同一个堆叠上下文内(ie不高级浏览器不算),也就是说,只存在一个堆叠上下文。而设置了transform的元素则不一样,因为它建立了一个新的堆叠上下文,也就是说,其内部被定位的元素的z-index会放在一个彻底独立的空间内。
可是这个堆叠上下文不包含被定义transform的元素自己,它仍被放在更大的堆叠上下文(若是有的话)里。
说到这,开篇提到的问题二、4都已经找到答案了,但目前,Chrome还存在一个bug:rendering bug : position:fixed AND -webkit-transform。
上面提得另外一个问题重现场景比较麻烦,先不讨论了。
当 transform
碰见 display:table | table-row | table-cell
3D渲染上下文是个什么玩意
陌生又熟悉的 backface-visibility
transform 与 css3动画
transform 与 canvas
transform 与 svg
艾玛,那么多坑,逃 ( ゚Д゚)σ