CSS3 transform介绍 (简书)

transform本质上是一系列变形函数,分别是translate位移,scale缩放,rotate旋转,skew扭曲,matrix矩阵。

  • 前置属性:

    • transform-origin
    • transform-style
    • perspective
    • perspective-origin
    • backface-visibility
  • 2D变形:
    • translate
    • scale
    • rotate
    • skew
    • matrix
  • 3D变形:
    • translate3d
    • scale3d
    • rotate3d
    • matrix3d
  • 层级影响
  • 前置属性

    transform-origin

    用于指定元素变形的中心点。默认中心点就是元素的正中心,即XYZ轴的50% 50% 0处。可以通过该属性改变元素在XYZ轴的中心点,正值表示正向位移,负值表示负向位移。(XYZ轴的正向分别是往右,往下,靠近用户眼睛。反之为反向)

    表示2维的x-offset/y-offset可以设px值也可以设%百分比,也可设top / right / bottom / left / center等keyword。表示3维的z-offset只能设px值,不能设%百分比,也没有keyword。

    默认中心点在元素正中心,因此关键字top等价于top center等价于50% 0%(x轴仍旧留在50%处,y轴位移到0%处)。同理各关键字例如right等价于right center等价于100% 50%,不多赘述。

    一图胜千言:为图片设置不同的中心点后,看它们旋转,扭曲,缩放的效果。例如图1表头的第一行center表示transform-origin: center。第二行rotate(30deg);表示transform: rotate(30deg);

    另外transform-origin指定变形中心点对translate位移没有影响。translate位移始终相对于元素正中心进行位移,有怀疑精神的可以自己试一下。

    transform-style

    这个属性比较简单只有两个值flatpreserve-3d。用于指定舞台为2D或3D,默认值flat表示2D舞台,所有子元素2D层面展现。preserve-3d看名字就知道了表示3D舞台,所有子元素在3D层面展现。注意,在变形元素自身上指定该属性是没有用的,它用于指定舞台,所以要在变形元素的父元素上设置该属性。设定后,所有子元素共享该舞台。一图胜千言:

    .div1 {
        float: left;
        background-color: red;
        transform: perspective(200px) rotateY(45deg);
    }
    .div1 img{
        transform: translateZ(16px);
    }
    .p3d {
        transform-style: preserve-3d;
    }
    <div class="div1"><img src="head75.png" /></div>
    <div class="div1 p3d"><img src="head75.png" /></div>

    两图唯一的区别是:右图的父div上设了transform-style: preserve-3d;,因此呈现了3d效果。左图的父div没有设transform-style默认是flat,因此元素不会在Z轴展开(translateZ(16px)失效),只能呈现2D效果。

    另外如果同时设了transform-style: preserve-3d;overflow: hidden;,3D效果将失效,等价于transform-style: flat;。如果你发现3D效果没有像预想地那样出现,可以检查一下(包括祖先元素)是否有overflow: hidden;,该属性将flatten everything…

    perspective

    指定3D的视距。默认值是none表示无3D效果,即2D扁平化。上面例子代码里其实已经用到过该属性了。介绍它之前,先借用rotateX / rotateY / rotateZ来明确一下xyz轴坐标的基本概念。一图胜千言,依次是rotateX轴旋转,rotateY轴旋转,rotateZ轴旋转:

    .x {
        transform: perspective(200px) rotateX(60deg);
    }
    .y {
        transform: perspective(200px) rotateY(60deg);
    }
    .z {
        transform: perspective(200px) rotateZ(60deg);
    }
    <img class="x" src="head75.png" />
    <img class="y" src="head75.png" />
    <img class="z" src="head75.png" />

    从图中也可以看出,烤羊肉串就是x轴旋转,钢管舞就是y轴旋转,彩票转盘就是z轴旋转。上面z轴只是一个点,想象一下就能明白,该点其实是一根垂直于屏幕的线,而perspective视距就是该线从屏幕到用户眼睛的距离。

    实现3D的关键就是要有perspective视距,如果将上述代码中perspective(200px)去掉,效果如下:

    除了z轴旋转不受影响外,xy轴虽然还在旋转,但失去了3D效果,是2D扁平化的旋转。原因就是因为不设perspective的话,其默认值为none,没有视距没有3D。

    perspective只能设px值,不能设%百分比。值越小表示用户眼睛距离屏幕越近,相当于创建一个较大的3D舞台。反之,值越大表示用户眼睛距离屏幕越远,相当于创建一个较小的3D舞台。这很容易理解,离的越近东西看起来越大,离的越远东西看起来越小。但具体该怎么设呢?借用W3C的图配合translateZ来帮助理解视距。

    图中d就是perspective视距,Z就是translateZ轴的位移。Z轴正向位移时,3D舞台将放大。反之,Z轴负向位移时,3D舞台将缩小。上图Z是d的一半,因此3D舞台上的元素将是原来的2倍。下图Z同样是d的一半,但由于是负值,所以3D舞台上的元素将缩小三分之一。实际试试:

    .divsp {
        display: inline-block;
        border: 1px blue dashed;
        margin-left: 30px;
        perspective: 100px;
    }
    .z1 {
        transform: translateZ(-75px);
    }
    .z2 {
        transform: translateZ(0px);
    }
    .z3 {
        transform: translateZ(25px);
    }
    .z4 {
        transform: translateZ(101px);
    }
    <div class="divsp"><img class="z1" src="head75.png" /></div>
    <div class="divsp"><img class="z2" src="head75.png" /></div>
    <div class="divsp"><img class="z3" src="head75.png" /></div>
    <div class="divsp"><img class="z4" src="head75.png" /></div>

    4张图的视距都是100px,表示4张图的3D舞台距离你的眼睛100px。我们从右往左来理解。图4的translateZ(101px)看到图片消失了,因为3D舞台距离你眼睛100px,而图片从舞台往Z轴正向位移101px,图片到了你脑袋后面自然什么都看不见。如果设成translateZ(100px),相当于图片紧贴着你的眼睛,所以全屏都是图片。图3的translateZ(25px),原始图片为75px,放大后的图片为100px。这是道初中数学题,你可以画一个底边是75px(图片原始尺寸),高是75px(视距100px-Z轴位移25px=75px)的等腰三角形,然后高扩展到100px,底边将等比例扩大3分之1至100px。图2的translateZ(0px)表示Z轴没有位移,因此仍旧是原始大小。图4的translateZ(-75px),同样是道初中数学题,原始图片为75px,缩小到42.85px,再看看上面W3C的图理解一下,很容易算出来。

    仔细看代码的可以看出来,上面介绍XYZ轴旋转时是直接在变形元素img上指定的transform: perspective(200px) rotateX(60deg);。而上面的代码是给变形元素img的父div指定perspective: 100px;。你可以理解为前一种方式是perspective()函数,后一种方式是perspective属性。两种指定方式是有区别的:

    1. 前者perspective()函数指定只针对当前变形元素,需要和transform其他函数一起使用,仅表示当前变形元素的视距。
    2. 后者perspective属性指定用于3D舞台,即3D舞台的视距,里面的子元素共享这个视距
    perspective-origin

    设置视距的基点,看W3C的图就能明白

    基点默认值是50% 50%即center,表示视距基点在中心点不进行任何位移。你可以让基点在XY轴上进行位移,产生上图那样的效果。注意该属性同样应该定义在父元素上,适用于整个3D舞台。它需要和perspective属性结合着一起用。效果如下图:

    .td1 {
        transform-style: preserve-3d;
        perspective: 200px;
        perspective-origin: center;
    }

    为节约篇幅,只贴出来图1的3D舞台的配置,其余8图只需根据表头修改perspective-origin即可。根据上面9宫格图就比较容易理解perspective-origin视距基点的意思了。默认值50% 50%即center表示眼睛在舞台正中心。然后根据XY轴的位移量,或关键字left(等价于x轴0%)等,调整眼睛看3D舞台的位置。

    backface-visibility

    用于是否可以看见3D舞台背面,默认值visible表示背面可见,可以设成hidden让背面不可见。通常当旋转时,如果不希望背面显示出来,该属性就很有用,设成hidden即可。一图胜千言:

    .stage{
        float: left;
        margin: 5px;
        perspective: 200px;
    }
    .container {
        transform-style: preserve-3d;
    }
    .image {
        backface-visibility: hidden;
    }
    .front {
        position: absolute;
        z-index: 1;
    }
    .back {
        transform: rotateY(180deg);
    }
    .stage:nth-child(1) .container{ transform: rotateY(0deg); }
    .stage:nth-child(2) .container{ transform: rotateY(30deg); }
    .stage:nth-child(3) .container{ transform: rotateY(60deg); }
    .stage:nth-child(4) .container{ transform: rotateY(90deg); }
    .stage:nth-child(5) .container{ transform: rotateY(120deg); }
    .stage:nth-child(6) .container{ transform: rotateY(150deg); }
    .stage:nth-child(7) .container{ transform: rotateY(180deg); }
    
    <div class="stage">    //为节约篇幅该DOM请无脑复制7个
        <div class="container">
            <img class="image front" src="head75.png" />
            <img class="image back" src="bg75.png" />
        </div>
    </div>

    DOM结构中就能看出,是两张图片(一正一反)叠在了一起。由于变形元素img设了backface-visibility: hidden;,当Y轴旋转超过90度时(Y轴旋转正好90度时,正中间图4为一片空白,就像丁字裤在视线里消失了^_^),正面的图片将不可见,底下的背面图片显示出来了。如果将img的backface-visibility属性去掉(默认为visibility),效果如下图。Y轴旋转超过90度时,将显示正面的图片的背部(所谓背部对屏幕来说其实就是图片矩阵的X轴值取反):

    至此5个前置属性介绍完毕。它们多用于3D场合,因此常见的3D的HTML结构如下:

    <舞台>         //为舞台加上perspective
        <容器>     //为容器加上preserve-3d,使容器内元素共享同一个3D渲染环境
            <元素> //为元素加上transform效果
        </容器>
    </舞台>

    2D变形

    2D变形有translate位移,scale缩放,rotate旋转,skew扭曲,matrix矩阵。基本的内容就不细说了,自行参照w3cschool,这里只介绍一些w3cschool上没有讲的内容。

    translate位移

    translate位移系列中用于2D的有:translate,translateX,translateY

    translate位移,类似于position:relative属性。可设单值,也可设双值。正数表示XY轴正向位移,负数为反向位移。设单值表示只X轴位移,Y轴坐标不变,例如transform: translate(100px);等价于transform: translate(100px,0);。这点和CSS中其他单值属性稍有不同,不要误以为单值是X轴和Y轴均位移。当然最好还是用双值,如果真的和Y轴无关,也请用translateX(100px),虽然效果是一样的,但代码可读性更高。同理如果和X轴无关,可以用transform: translateY(100px);等价于transform: translate(0, 100px);

    上面说了效果类似于position:relative属性,但和position语义不同,position用于页面布局,而translate属于transform中的一个系列,用于元素变形。你可能觉得语义不同有什么卵用,效果OK不就行了?就看你用什么标准来衡量效果了。CSS的神奇之处在于你可以将一个属性用在完全违背它原意的场景下,抛开代码可读性不谈,违背原意有时还是会有细微差别的。如结合动画效果时,translate能小于1px过渡,因此动画效果更为平滑。但position最小单位就是1px,动画效果肯定打折扣。另外用translate实现动画时,可以使用GPU,动画的FPS更高,而position显然无法享受这个优势。其他如回流和重绘也都有差异。因此如果你在该用translate的地方用了position,今后一些需求变动达不到要求,你也没什么立场可抱怨的了。

    scale缩放

    scale缩放系列中用于2D的有:scale,scaleX,scaleY

    scale缩放,同样可以设单值和双值。单值时表示X轴和Y轴等值缩放。默认值为1,要缩小请设0.01~0.99之间的值,要放大请设超过1的值。例如缩小一倍可以transform: scale(.5);,放大一倍可以transform: scale(2);。效果在最上面介绍transform-origin时图片里已经有了,不多赘述。

    如果只想X轴缩放,可以用scaleX(.5)相当于scale(.5, 1)。同理只想Y轴缩放,可以用scaleY(.5)相当于scale(1, .5)

    设双值可以实现X轴Y轴不等比例缩放,如transform: scale(.5, 1.5);,原本75*75px的图片变成了37.5*112.5px大小。如左图:

    w3cschool上没说的是,scale还能设负数,负数会先将元素反转再缩放,如transform: scale(-.5, -1.5);,效果见上面右图。为何反转能理解吧?XY轴像素矩阵各值取反后,效果等价于反转。当然你同样可以用rotate实现反转。

    rotate旋转

    rotate旋转系列中用于2D的有:rotate

    rotate旋转,比较简单,只能设单值。正数表示顺时针旋转,负数表示逆时针旋转。如transform: rotate(30deg);,效果在最上面介绍transform-origin时图片里已经有了,不多赘述。(注意和上面不同,在2D层面上没有rotateX / rotateY,它俩和rotateZ都是3D旋转)

    skew扭曲

    skew扭曲系列中用于2D的有:skew,skewX,skewY

    skew扭曲可以设单值和双值。单值时表示只X轴扭曲,Y轴不变,如transform: skew(30deg);等价于transform: skew(30deg, 0);。考虑到可读性,不推荐用单值,应该用transform: skewX(30deg);。skewY表示只Y轴扭曲,X轴不变。效果在最上面介绍transform-origin时图片里已经有了,不多赘述。

    matrix矩阵

    matrix矩阵前面没有直接接触,但却是所有2D变形的本质,上面所有2D变形效果都可以用matrix矩阵来实现。本篇先略过,将它和3D矩阵matrix3d留到下一篇再介绍。

    3D变形

    3D变形有translate3d位移,scale3d缩放,rotate3d旋转, matrix3d矩阵。(注意skew扭曲是没有3D的)。3D的用法和2D差不多,只不过多了个Z轴的值而已(这不是废话么…)。

    translate3d位移

    translate3d位移系列中用于3D的有:translate3d,translateZ

    translate3d(tx,ty,tz),其中tz的Z轴长度只能为px值,不能为%百分比。translateZ等价于translate3d(0,0,tz)。Z轴的值越大表示离眼睛越近,元素就越大,但当值大于perspective视距时元素将消失,因为眼睛无法看见眼睛背后的东西,这在上面介绍perspective时已经介绍过,不再赘述。值越小表示离眼睛越远,元素就越小。实际使用中translateZ效果和2D的scale缩放效果非常像,但原理是有区别的,translateZ是Z轴上位移,而scale是XY轴的缩放。还是那句话,尽量将属性用在符合属性愿意的场合。

    scale3d缩放

    scale3d缩放系列中用于3D的有:scale3d,scaleZ

    scale3d(sx,sy,sz),其中sz为Z轴的缩放比例,取值同sx,sy一样,在0.01~0.99时元素缩小,1时大小不变,大于1时元素变大。scaleZ等价于scale(1,1,sz)。需要注意的是单独使用scale3d或scaleZ不会有任何效果,需要配合其他属性在3D舞台上才能出现效果,否则Z轴的缩放比例根本无法定义。

    rotate3d旋转

    rotate3d旋转系列中用于3D的有:rotate3d,rotateX,rotateY,rotateZ

    rotate3d(x,y,z,a)这里多了一个参数a(读音是阿尔法…)表示3D舞台上旋转的角度,而xyz的取值为0~1为各轴的旋转矢量值。rotate3d,rotateX,rotateY,rotateZ的效果在上面都有展示,不赘述。

    matrix3d矩阵

    最后matrix3d矩阵是所有3D变形的本质,上面所有3D变形效果都可以用matrix3d矩阵来实现。本篇先略过,将它和上面的2D矩阵matrix留到下一篇再介绍。

    层级影响

    现在来看看变形对CSS层级的影响。说起层级,absolute绝对是层级间的高富帅,见一个睡一个,sorry,是见一个压一个,sorry,是见一个覆盖一个。

    //左图
    <img style="position:absolute;" src="bg100.png" />
    <img src="head75.png" />
    //右图
    <img style="position:absolute;" src="bg100.png" />
    <img style="transform:scale(1);" src="head75.png" />

    左图因为第一张img具有absolute,完全无视DOM结构中的顺序,妥妥地覆盖了第二张img。右图给第二张img设了transform,通常我们会认为scale(1)是废代码,但实际从右图已经看出,由于设立transform,使元素具有了相当于absolute的层级,因此两张img平级了,根据DOM中的顺序,后者覆盖了前者。

    (这里使用的是scale,你可以改成rotate,skew等,效果都一样。即层级和transform有关,但和具体哪个transform函数无关)

    因为absolute和transform平级,你可以调整上面两张img的顺序,这样设了transform的图片会被absolute覆盖。如果你非要让absolute高人一等,可以设z-index:1这样层级会高于transform,达到覆盖效果。

    和absolute同系列的relative和fixed也适用上述层级关系。如果你页面上有个fixed广告标签,页面滚动时被transform元素覆盖了,请不要惊讶,试试设一下z-index。

    总结

    transform变形的用法介绍到这就差不多了。为缩减篇幅,文中代码都省略-ms,-o等前缀,需要浏览器全适应的请自行加上。下一篇matrix/matrix3d会更深入其本质,看看这些变形函数究竟是如何变换坐标位置,显示出各种效果的。

时间: 2024-10-22 20:24:29

CSS3 transform介绍 (简书)的相关文章

理解CSS3 transform中的Matrix(矩阵)

一.哥,我被你吓住了 打架的时候会被块头大的吓住,学习的时候会被奇怪名字吓住(如“拉普拉斯不等式”).这与情感化设计本质一致:界面设计好会让人觉得这个软件好用! 所以,当看到上面“Matrix(矩阵)”的时候,难免会心生畏惧(即使你已经学过),正常心理.实际上,这玩意确实有点复杂. 然而,这却是屌丝逆袭的一个好机会. CSS同行间:你是不是有这样的感觉:哎呀呀,每天就是对着设计图切页面,貌似技术没有得到实质性地提升啊,或者觉得日后高度有限! 我们应该都知道二八法则(巴莱多定律),即任何一组东西中

css3 transform中的matrix矩阵

CSS3中的矩阵CSS3中的矩阵指的是一个方法,书写为matrix()和matrix3d(),前者是元素2D平面的移动变换(transform),后者则是3D变换.2D变换矩阵为3*3, 如上面矩阵示意图:3D变换则是4*4的矩阵. 有些迷糊?恩,我也觉得上面讲述有些不合时宜.那好,我们先看看其他东西,层层渐进——transform属性. 具体关于transform属性具体内容可以点击这里补个课.稍微熟悉的人都知道,transform中有这么几个属性方法: .trans_skew { trans

iOS实现简书的账号识别方式(正则表达式)

通过简书iOS客户端登录,我们会看到请输入手机号或者邮箱登录,但是我们随机输入1234567的时候,便会弹出手机格式不正确,同样也会识别我们的邮箱格式,那么我们在项目中怎么实现这种判断呢? 0E471361-060C-4D93-913F-73622F89BC60.png 这就是我们今天要说的正则表达式. 正则表达式的介绍 正则表达式有多种使用方法,根据我们的需要,我们是要判断输入是否合法,还是查找指定的内容,还是捕获多个输入的内容,可以选用不同的方法,今天我们主要说一下,判断输入是否合法,用谓词

CSS3 Transform变形理解与应用

CSS3 Transform变形理解与应用 Transform:对元素进行变形:Transition:对元素某个属性或多个属性的变化,进行控制(时间等),类似flash的补间动画.但只有两个关键贞.开始,结束.Animation:对元素某个属性或多个属性的变化,进行控制(时间等),类似flash的补间动画.可以设置多个关键贞. Transition与Animation:transition需要触发一个事件 ,而animation在不需要触发任何事件的情况下也可以显式的随着时间变化来改变元 素cs

理解CSS3 transform中的Matrix(矩阵)——张鑫旭

by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=2427 一.哥,我被你吓住了 打架的时候会被块头大的吓住,学习的时候会被奇怪名字吓住(如“拉普拉斯不等式”).这与情感化设计本质一致:界面设计好会让人觉得这个软件好用! 所以,当看到上面“Matrix(矩阵)”的时候,难免会心生畏惧(即使你已经学过),正常心理.实际上,这玩意确实有点复杂. 然而,这却是屌丝逆袭的一个好机

仿简书分享:UIActivityViewController系统原生分享

接下来介绍UIActivityViewController: 1. 创建要分享的数据内容,加在一个数组 ActivityItems里. NSString *textToShare = @"我是且行且珍惜_iOS,欢迎关注我!"; UIImage *imageToShare = [UIImage imageNamed:@"wang.png"]; NSURL *urlToShare = [NSURL URLWithString:@"https://github

献给写作者的 Markdown 新手指南 - 简书

body { font-family: 微软雅黑,"Microsoft YaHei", Georgia,Helvetica,Arial,sans-serif,宋体, PMingLiU,serif; font-size: 10.5pt; line-height: 1.5; } html, body { } h1 { font-size:1.5em; font-weight:bold; } h2 { font-size:1.4em; font-weight:bold; } h3 { fon

Docker决战到底(三) Rancher2.x的安装与使用 - 简书

原文:Docker决战到底(三) Rancher2.x的安装与使用 - 简书 image.png 当越来越多的容器化应用被部署,一个可以管理编排这些容器的工具此时就显得尤为重要了.目前容器编排领域的佼佼者非kubernates莫属了, 但我一直没有来得及上手,可能是学习成本比较高吧,加上公司里面使用的rancher1.6,我就直接用rancher来作为容器编排管理的切入点了,只是我这里采用的是rancher2.15版本. 非常意外的是,以前rancher1.6版本还支持docker compos

【凯子哥带你学Android】Andriod性能优化之列表卡顿——以“简书”APP为例

这几天闲得无聊,就打开手机上的开发者模式里面的"GPU过度绘制"功能,看看别家的App做的咋样,然后很偶然的打开了"简书",然后就被它的过度绘制惊呆了,于是写了这篇性能分析的文章,从一个只有APK文件的角度,说下如何寻找布局中可能存在的性能问题,以及解决方案.本文章以简书Android最新版本1.9.1进行分析. GPU过度绘制 Hierarchy View SysTrace TraceView 总结 分析资源下载 GPU过度绘制 首先打开下面两个功能开关 开发者模