CSS - 变换

介绍

通过改变坐标空间,CSS transforms 可以在不影响正常文档流的情况下改变作用内容的位置。

CSS transforms 通过一系列 CSS 属性实现,通过使用这些属性,可以对 HTML 元素进行线性仿射变形(affine linear transformations)。可以进行的变形包括旋转,倾斜,缩放以及位移,这些变形同时适用于 平面与三维空间

注意: 只有使用 盒模型 来定位的元素可以被变换。

 
 

属性 transformtransform-origin

  • transform-origin :指定原点的位置。默认值为元素的中心,可以被移动。
    很多变形需要用到这个属性,比如旋转,缩放和倾斜,他们都需要一个指定的点作为参数。
语法:
transform-origin = 
  [ left | center | right | top | bottom | <length-percentage> ]  |
  [ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ] <length>?  |
  [ [ center | left | right ] && [ center | top | bottom ] ] <length>?  

<length-percentage> = 
  <length>      |
  <percentage>  

可以使用一个,两个或三个值来指定,其中每个值都表示一个偏移量。没有明确定义的偏移将重置为其对应的初始值。

语法示例:
One-value syntax
transform-origin: 2px;
transform-origin: bottom;

x-offset | y-offset
transform-origin: 3cm 2px;

x-offset-keyword | y-offset
transform-origin: left 2px;

x-offset-keyword | y-offset-keyword 
transform-origin: right top;

y-offset-keyword | x-offset-keyword
transform-origin: top right;

x-offset | y-offset | z-offset
transform-origin: 2px 30% 10px;

 x-offset-keyword | y-offset | z-offset
transform-origin: left 5px -3px;

x-offset-keyword | y-offset-keyword | z-offset
transform-origin: right bottom 2cm;

y-offset-keyword | x-offset-keyword | z-offset
transform-origin: bottom right 2cm;

/* Global values */
transform-origin: inherit;
transform-origin: initial;
transform-origin: unset;

 
 

  • transform :指定作用在元素上的变形。
    取值为空格分隔的一系列变形的列表,他们会像被组合操作请求一样被分别执行。
语法:
transform = 
  none              |
  <transform-list>  

<transform-list> = 
  <transform-function>+  
  • none:不应用任何变换。

  • <transform-function>:要应用的一个或多个 CSS 变换函数。
    变换函数按从左到右的顺序相乘,这意味着复合变换按从右到左的顺序有效地应用。
    详情戳这里:CSS 数据类型 - <transform-function>,文章里用到了一些适用于3D模型中的函数,建议参考下面的文章介绍。

 
 

适用于三维的属性

首先我们先搞一个3d的图形,示例在MDN上有,我们直接拿过来,看代码:

CSS:
.cube {
    width: 200px;
    height: 200px;
    backface-visibility: visible;
      perspective-origin: 50% 50%;
    transform-style: preserve-3d;
    border: 1px dashed red;
}
.face {
    display: block;
    position: absolute;
    margin:50px;
    width: 100px;
    height: 100px;
    border: none;
    line-height: 100px;
    font-family: sans-serif;
    font-size: 60px;
    color: black;
    text-align: center;
}
.pers250 {
    perspective: 250px;
}
.front {
    background: rgba(0, 0, 0, 0.3);
    transform: translateZ(50px);
}
.back {
    background: rgba(0, 255, 0, 1);
    transform: rotateY(180deg) translateZ(50px);
}
.right {
    background: rgba(196, 0, 0, 0.7);
    transform: rotateY(90deg) translateZ(50px);
}
.left {
    background: rgba(0, 0, 196, 0.7);
    transform: rotateY(-90deg) translateZ(50px);
}
.top {
    background: rgba(196, 196, 0, 0.7);
    transform: rotateX(90deg) translateZ(50px);
}
.bottom {
    background: rgba(196, 0, 196, 0.7);
    transform: rotateX(-90deg) translateZ(50px);
}
HTML:
<div class="cube pers650">
    <div class="face front">1</div>
    <div class="face back">2</div>
    <div class="face right">3</div>
    <div class="face left">4</div>
    <div class="face top">5</div>
    <div class="face bottom">6</div>
</div>

效果:

示例中有很多的新属性没见过的,没关系我们参考文档一点一点来理解。在三维空间中使用 CSS 变形会稍微复杂一点。

必须先设置一个透视点perspective以便配置 3D 空间,再去定义 2D 元素在空间中的行为。透视正是三维空间的立体感的源泉。

 
 

属性 perspective

指定了观察者与 z=0 平面的距离,使具有三维位置变换的元素产生透视效果。不能为负。

语法:
perspective = 
  none            |
  <length [0,∞]>  
  • none:没有应用 perspective 样式时的默认值。
  • <length>:指定观察者距离 z=0 平面的距离,为元素及其内容应用透视变换。当值为 0 或负值时,无透视变换。
示例1: 修改perspective的值
.pers100 {
    perspective: 100px;
}
.pers250 {
    perspective: 250px;
}

效果:
示例2: 修改front面的属性translateZ()的值
.pers250 {
    perspective: 250px;
}
.front {
    transform:  translateZ(0px);
}
.front {
    transform:  translateZ(150px);
}

效果:
代码解析:
  • 首先我们能明白,translateZ()属性的变化原理,即,随着面在Z轴上的移动,在空间上离透视点越近,即越接近perspective属性值,面会随之变大,直到>=这个值,面会消失。反之会随之变小。

通过上面的解析,我们可以知道perspective属性,具有 视距 的特性。

  • 在示例1中,我们可以明白,改变persective属性值,面的大小也会随之变化。但是,在z=0这个面(容器cube)的前后的面(即面在z轴的位置,大于0 为前面,小于0 为后面)的大小变化确不一致,可以观察一下12这两个面,这是为何呢?

首先我们要明白一点,我们构建的是三维的图形,但是展示是在二维的网页上进行的。

所以看下图:

其实我们在网页上看到的12面,可以看作是真实空间中的面的投影。也可以理解成,通过透视我们可以看到在容器面cube上的12面的投影。
所以:

  • 前面的面:
    • 随着perspective属性的变大,投影出的面会 变小,且 投影出的面 的大小会无限接近于 前面的面 的大小。
    • 随着perspective属性的变小,投影出的面会 变大,可变到无限大,直到视点与前面的面重合,投影的面则会消失。
  • 后面的面:
    • 随着perspective属性的变大,投影出的面会 变大,且 投影出的面 的大小会无限接近于 后面的面 的大小。
    • 随着perspective属性的变小,投影出的面会 变小,可变到无限小,直到视点与容器的面重合,投影的面则会成为一个点。
  • 与容器面交叠的面:
    • 这些面在容器面的前面的部分,与后面的部分,分别遵循以上两种规律。

通过上面的解析,我们可以知道perspective属性,具有 透视 的特性。

 
 

属性 perspective-origin

指定了观察者的位置,即视点。视点的位置是相对的,例如:在上面的示例中,是相对于容器面cube来说的。

语法:
perspective-origin = 
  <position>  

<position> = 
  [ left | center | right | top | bottom | start | end | <length-percentage> ]  |
  [ left | center | right | x-start | x-end | <length-percentage> ] [ top | center | bottom | y-start | y-end | <length-percentage> ]  |
  [ center | [ left | right | x-start | x-end ] <length-percentage>? ] && [ center | [ top | bottom | y-start | y-end ] <length-percentage>? ]  |
  [ center | [ start | end ] <length-percentage>? ] [ center | [ start | end ] <length-percentage>? ]  

<length-percentage> = 
  <length>      |
  <percentage>  
语法示例:
/* One-value syntax */
perspective-origin: x-position;

/* Two-value syntax */
perspective-origin: x-position y-position;

/* When both x-position and y-position are keywords,
   the following is also valid */
perspective-origin: y-position x-position;

/* Global values */
perspective-origin: inherit;
perspective-origin: initial;
perspective-origin: unset;
  • x-position:指定消失点的横坐标,其值有以下形式:

    • <length-percentage>:长度值或相对于元素宽度的百分比值,可为负值。
    • left: 关键字,0 值的简记。
    • center, 关键字:50% 的简记。
    • right, 关键字:100% 的简记。
  • y-position:指定消失点的纵坐标,其值有以下形式:

    • <length-percentage>: 长度值或相对于元素高度的百分比值,可为负值。
    • top,:关键字,0 值的简记。
    • center: 关键字,50% 的简记。
    • bottom: 关键字,100% 的简记。

效果:

 
 

属性 transform-style

实验中的功能。设置元素的子元素是位于 3D 空间中还是平面中。

语法:
transform-style = 
  flat         |
  preserve-3d  
语法示例:
/* Keyword values */
transform-style: flat;
transform-style: preserve-3d;

/* Global values */
transform-style: inherit;
transform-style: initial;
transform-style: unset;
  • flat:设置元素的子元素位于该元素的平面中。

  • preserve-3d:指示元素的子元素应位于 3D 空间中。

 
 

属性 backface-visibility

实验中的功能。指定当元素背面朝向观察者时是否可见。

语法:
backface-visibility = 
  visible  |
  hidden   
语法示例:
/* Keyword values */
backface-visibility: visible;
backface-visibility: hidden;

/* Global values */
backface-visibility: inherit;
backface-visibility: initial;
backface-visibility: unset;
  • visible:背面朝向用户时可见。

  • hidden:背面朝向用户时不可见。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 225,165评论 6 523
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,476评论 3 405
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 172,446评论 0 368
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 61,157评论 1 301
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 70,164评论 6 400
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,615评论 1 316
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,969评论 3 430
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,959评论 0 279
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,495评论 1 324
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,529评论 3 347
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,641评论 1 355
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,233评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,976评论 3 340
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,407评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,552评论 1 277
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,218评论 3 381
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,715评论 2 366

推荐阅读更多精彩内容