元素变形记:CSS 缩放函数全指南

CSS 中的缩放函数分别有 scaleX()scaleY()scaleZ()scale()scale3d() ,用于对元素进行 2D 或 3D 空间进行缩放变换。

所谓缩放,即对元素进行缩小或放大。

scaleX()

沿水平方向缩放元素。

该函数通过一个恒定系数修改元素每个点的横坐标(水平方向,x坐标),除非缩放系数为1(此时函数为恒等变换)。这种缩放并非各向同性,且元素的角度通常不会保持不变(90度的倍数除外)。scaleX(-1) 定义了一种轴向对称变换,对称轴为穿过原点(由 transform-origin 属性指定)的垂直轴。

在 CSS 的 scaleX() 变换函数中,恒定系数(constant factor) 指的是一个固定不变的缩放系数,它会统一作用于元素所有点的 X 坐标(横坐标)。

假设缩放系数为 s,则元素上每个点 (x, y) 的横坐标会被修改为 (s·x, y)。 这里的 s 就是恒定系数,它对元素的所有点均一视同仁地应用相同的缩放比例。

css 复制代码
transform: scaleX(1.5); /* 恒定系数 s=1.5,所有点的 x 坐标扩大 1.5 倍 */
  • 非各向同性:仅水平方向(X 轴)缩放,垂直方向(Y 轴)不变,因此会破坏原始比例。

  • 角度不守恒 :除非缩放因子为 1 或旋转角度为 90° 的倍数(如 180°),否则元素的倾斜角度会改变。

  • 负值的对称性scaleX(-1) 表示以 Y 轴为对称轴进行镜像翻转(需配合 transform-origin 定义原点)。

恒定系数 s=1 时:scaleX(1)恒等变换(identity transform),即元素不发生任何形变,坐标保持不变。

css 复制代码
transform: scaleX(1); /* 无效果,因为 x 坐标乘以 1 不变 */

下面为更加具体的例子:

html 复制代码
<div class="card">
  <div class="box scaleX">
    <div class="fill"></div>
  </div>
  <p>scaleX(2)</p>
</div>
<div class="card">
  <div class="box scaleX">
    <div class="fill"></div>
  </div>
  <p>scaleX(-1)</p>
</div>
css 复制代码
*, *:after, *:before {
  box-sizing: border-box;
}
body {
  background: #F5F3F4;
  margin: 0;
  padding: 10px;
  font-family: 'Open Sans', sans-serif;
  text-align: center;
}
.card {
  display: inline-block;
  margin: 10px;
  background: #fff;
  padding: 15px;
  min-width: 200px;
  box-shadow: 0 3px 5px #ddd;
  color: #555;
}
.card .box {
  width: 100px;
  height: 100px;
  margin: auto;
  background: #ddd;
  cursor: pointer;
  box-shadow: 0 0 5px #ccc inset;
}

.card .box .fill {
  width: 100px;
  height: 100px;
  position: relative;
  background: #03A9F4;
  opacity: .5;
  box-shadow: 0 0 5px #ccc;
  -webkit-transition: 0.3s;
  transition: 0.3s;
}
.card p {
  margin: 25px 0 0;
}
.scaleX:hover .fill {
  -webkit-transform: scaleX(2);
  transform: scaleX(2);;
}
.card:nth-child(2) .scaleX:hover .fill{
  -webkit-transform: scaleX(-1);;
  transform: scaleX(-1);      
}

更多可见scaleX()

scaleY()

沿垂直方向缩放元素。

该函数通过一个恒定系数修改元素每个点的纵坐标(垂直方向,Y坐标),除非缩放系数为1(此时函数为恒等变换)。这种缩放不具备各向同性(会破坏原始比例),且元素的角度不会保持不变。scaleY(-1) 定义了一种轴向对称变换,对称轴为穿过原点(由 transform-origin 属性指定)的水平轴。

css 复制代码
scaleY(s)

s 表示缩放系数,用于对元素每个点的纵坐标(垂直方向,Y坐标)进行比例缩放。

下面为具体的例子:

html 复制代码
<div class="card">
  <div class="box scaleY">
    <div class="fill"></div>
  </div>
  <p>scaleY(2)</p>
</div>
<div class="card">
  <div class="box scaleY">
    <div class="fill"></div>
  </div>
  <p>scaleY(-1)</p>
</div>
css 复制代码
*, *:after, *:before {
  box-sizing: border-box;
}
body {
  background: #F5F3F4;
  margin: 0;
  padding: 10px;
  font-family: 'Open Sans', sans-serif;
  text-align: center;
  padding-top: 50px;
}
.card {
  display: inline-block;
  margin: 10px;
  background: #fff;
  padding: 15px;
  min-width: 200px;
  box-shadow: 0 3px 5px #ddd;
  color: #555;
}
.card .box {
  width: 100px;
  height: 100px;
  margin: auto;
  background: #ddd;
  cursor: pointer;
  box-shadow: 0 0 5px #ccc inset;
}

.card .box .fill {
  width: 100px;
  height: 100px;
  position: relative;
  background: #03A9F4;
  opacity: .5;
  box-shadow: 0 0 5px #ccc;
  -webkit-transition: 0.3s;
  transition: 0.3s;
}
.card p {
  margin: 25px 0 0;
}
.scaleY:hover .fill {
  -webkit-transform: scaleY(2);
  transform: scaleY(2);;
}
.card:nth-child(2) .scaleY:hover .fill{
  -webkit-transform: scaleY(-1);;
  transform: scaleY(-1);      
}

更多可见 scaleY()

scaleZ()

沿 z 轴方向缩放元素。

该缩放变换通过一个恒定系数修改元素每个点的 Z 坐标(纵深方向),除非缩放系数为1(此时函数为恒等变换)。这种缩放不具备各向同性,且元素的角度不会保持不变。scaleZ(-1) 定义了一种轴向对称变换,对称轴为穿过原点(由 transform-origin 属性指定)的 Z轴。

css 复制代码
scaleZ(s)

s 表示缩放系数,用于对元素每个点的 Z 坐标(纵深方向)进行比例缩放。

要注意的是,单独使用 scaleZ() 是无效的,因为平面元素默认是 z 坐标为 0 。

下面为具体的例子:

html 复制代码
<div class="perspective-100">
  <div class="card">
    <div class="box scaleZ">
      <div class="fill"></div>
    </div>
    <p>scaleZ(0.5)</p>
  </div>
  <div class="card">
    <div class="box scaleZ">
      <div class="fill"></div>
    </div>
    <p>scaleZ(1.2)</p>
  </div>    
</div>
css 复制代码
*, *:after, *:before {
  box-sizing: border-box;
}
body {
  background: #F5F3F4;
  margin-top: 100px;
  padding: 10px;
  font-family: 'Open Sans', sans-serif;
  text-align: center;
}
.card {
  display: inline-block;
  margin: 10px;
  background: #fff;
  padding: 15px;
  min-width: 200px;
  box-shadow: 0 3px 5px #ddd;
  color: #555;
}
.card .box {
  width: 100px;
  height: 100px;
  margin: auto;
  background: #ddd;
  cursor: pointer;
  box-shadow: 0 0 5px #ccc inset;
}
.perspective-100 .box {
  -webkit-perspective: 100px;
  perspective: 100px;
}
.card .box .fill {
  width: 100px;
  height: 100px;
  position: relative;
  background: #03A9F4;
  opacity: .5;
  box-shadow: 0 0 5px #ccc;
  -webkit-transition: 0.3s;
  transition: 0.3s;
}
.card p {
  margin: 25px 0 0;
}
.scaleZ:hover .fill {
  -webkit-transform: scaleZ(0.5) translateZ(-50px);
  transform: scaleZ(0.5) translateZ(-50px);
}
.card:nth-child(2) .scaleZ:hover .fill{
  -webkit-transform: scaleZ(1.2) translateZ(50px);
  transform: scaleZ(1.2) translateZ(50px);      
}

下面为 scaleZ(-1) 的例子,原本 translateZ(-50px) 是元素沿 z 轴方向远离用户 50px ,然后元素会变小,由于 scaleZ(-1) ,会对元素的 z 坐标取反,元素反而会在靠近用户的方向走 50px ,因此最终元素会变大。

html 复制代码
<div class="perspective-100">
  <div class="card">
    <div class="box scaleZ">
      <div class="fill"></div>
    </div>
    <p>scaleZ(-1)</p>
  </div>   
</div>
css 复制代码
*, *:after, *:before {
  box-sizing: border-box;
}
body {
  background: #F5F3F4;
  margin-top: 100px;
  padding: 10px;
  font-family: 'Open Sans', sans-serif;
  text-align: center;
}
.card {
  display: inline-block;
  margin: 10px;
  background: #fff;
  padding: 15px;
  min-width: 200px;
  box-shadow: 0 3px 5px #ddd;
  color: #555;
}
.card .box {
  width: 100px;
  height: 100px;
  margin: auto;
  background: #ddd;
  cursor: pointer;
  box-shadow: 0 0 5px #ccc inset;
}
.perspective-100 .box {
  -webkit-perspective: 100px;
  perspective: 100px;
}
.card .box .fill {
  width: 100px;
  height: 100px;
  position: relative;
  background: #03A9F4;
  opacity: .5;
  box-shadow: 0 0 5px #ccc;
  -webkit-transition: 0.3s;
  transition: 0.3s;
}
.card p {
  margin: 25px 0 0;
}
.scaleZ:hover .fill {
  -webkit-transform: scaleZ(-1) translateZ(-50px);
  transform: scaleZ(-1) translateZ(-50px);
}

更多可见 scaleZ()

scale()

在 2D 平面上缩放元素。

scale() 接受两个参数,分别表示元素在 x 轴、y 轴方向上的缩放比例。

当两个坐标值相等时,是对元素进行等比缩放。

css 复制代码
scale(sx)

scale(sx, sy)

sx ,表示缩放向量的横坐标(水平方向)

sy ,表示缩放向量的纵坐标,若未定义,其默认值与横坐标缩放系数(sx)相同,从而保持元素宽高比的均匀缩放。

下面为等比缩放的例子,x 轴、y 轴的缩放系数相同:

html 复制代码
<div class="perspective-100">
  <div class="card">
    <div class="box scale">
      <div class="fill"></div>
    </div>
    <p>scale(0.5)</p>
  </div>
  <div class="card">
    <div class="box scale">
      <div class="fill"></div>
    </div>
    <p>scale(1.5)</p>
  </div>    
</div>
css 复制代码
*, *:after, *:before {
  box-sizing: border-box;
}
body {
  background: #F5F3F4;
  margin-top: 100px;
  padding: 10px;
  font-family: 'Open Sans', sans-serif;
  text-align: center;
}
.card {
  display: inline-block;
  margin: 10px;
  background: #fff;
  padding: 15px;
  min-width: 200px;
  box-shadow: 0 3px 5px #ddd;
  color: #555;
}
.card .box {
  width: 100px;
  height: 100px;
  margin: auto;
  background: #ddd;
  cursor: pointer;
  box-shadow: 0 0 5px #ccc inset;
}
.perspective-100 .box {
  -webkit-perspective: 100px;
  perspective: 100px;
}
.card .box .fill {
  width: 100px;
  height: 100px;
  position: relative;
  background: #03A9F4;
  opacity: .5;
  box-shadow: 0 0 5px #ccc;
  -webkit-transition: 0.3s;
  transition: 0.3s;
}
.card p {
  margin: 25px 0 0;
}
.scale:hover .fill {
  -webkit-transform: scale(0.5);
  transform: scale(0.5);
}
.card:nth-child(2) .scale:hover .fill{
  -webkit-transform: scale(1.5);
  transform: scale(1.5);
}

下面为只缩放 y 轴的例子:

html 复制代码
<div class="perspective-100">
  <div class="card">
    <div class="box scale">
      <div class="fill"></div>
    </div>
    <p>scale(1, 2)</p>
  </div> 
</div>
css 复制代码
*, *:after, *:before {
  box-sizing: border-box;
}
body {
  background: #F5F3F4;
  margin-top: 100px;
  padding: 10px;
  font-family: 'Open Sans', sans-serif;
  text-align: center;
}
.card {
  display: inline-block;
  margin: 10px;
  background: #fff;
  padding: 15px;
  min-width: 200px;
  box-shadow: 0 3px 5px #ddd;
  color: #555;
}
.card .box {
  width: 100px;
  height: 100px;
  margin: auto;
  background: #ddd;
  cursor: pointer;
  box-shadow: 0 0 5px #ccc inset;
}
.perspective-100 .box {
  -webkit-perspective: 100px;
  perspective: 100px;
}
.card .box .fill {
  width: 100px;
  height: 100px;
  position: relative;
  background: #03A9F4;
  opacity: .5;
  box-shadow: 0 0 5px #ccc;
  -webkit-transition: 0.3s;
  transition: 0.3s;
}
.card p {
  margin: 25px 0 0;
}
.scale:hover .fill {
  -webkit-transform: scale(1, 2);
  transform: scale(1, 2);
}

更多可见 scale()

scale3d()

在 3D 空间中缩放元素。

CSS 函数 scale3d() 接受 3 个参数,分别指定元素在xyz 三个方向上的缩放比例。当三个坐标值相等时,将产生均匀缩放(各向同性),此时元素的宽高比保持不变。

css 复制代码
scale3d(sx, sy, sz)

sx ,x 轴的缩放系数

sy ,y 轴的缩放系数

sz,z 轴的缩放系数

下面为具体的例子:

html 复制代码
<div class="perspective-100">
  <div class="card">
    <div class="box scale3d">
      <div class="fill"></div>
    </div>
    <p>scale3d(2, 0.7, 0.2)</p>
  </div> 
</div>
css 复制代码
*, *:after, *:before {
  box-sizing: border-box;
}
body {
  background: #F5F3F4;
  margin-top: 100px;
  padding: 10px;
  font-family: 'Open Sans', sans-serif;
  text-align: center;
}
.card {
  display: inline-block;
  margin: 10px;
  background: #fff;
  padding: 15px;
  min-width: 200px;
  box-shadow: 0 3px 5px #ddd;
  color: #555;
}
.card .box {
  width: 100px;
  height: 100px;
  margin: auto;
  background: #ddd;
  cursor: pointer;
  box-shadow: 0 0 5px #ccc inset;
}
.perspective-100 .box {
  -webkit-perspective: 100px;
  perspective: 100px;
}
.card .box .fill {
  width: 100px;
  height: 100px;
  position: relative;
  background: #03A9F4;
  opacity: .5;
  box-shadow: 0 0 5px #ccc;
  -webkit-transition: 0.3s;
  transition: 0.3s;
}
.card p {
  margin: 25px 0 0;
}
.scale3d:hover .fill {
  -webkit-transform: scale3d(2, 0.7, 0.2) translateZ(100px);
  transform: scale3d(2, 0.7, 0.2) translateZ(100px);
}

更多可见 scale3d()

总结

CSS 缩放函数通过 scaleX/Y/Z()scale()scale3d() 实现元素在 2D / 3D 空间的缩放。

相关推荐
spionbo8 分钟前
Vue 表情包输入组件实现代码及完整开发流程解析
前端·javascript·面试
全宝8 分钟前
✏️Canvas实现环形文字
前端·javascript·canvas
lyc2333338 分钟前
鸿蒙Core File Kit:极简文件管理指南📁
前端
我这里是好的呀8 分钟前
全栈开发个人博客12.嵌套评论设计
前端·全栈
我这里是好的呀10 分钟前
全栈开发个人博客13.AI聊天设计
前端·全栈
金金金__10 分钟前
Element-Plus:popconfirm与tooltip一起使用不生效?
前端·vue.js·element
lyc23333311 分钟前
小L带你看鸿蒙应用升级的数据迁移适配📱
前端
用户268128510666917 分钟前
react-pdf(pdfjs-dist)如何兼容老浏览器(chrome 49)
前端
阿怼丶17 分钟前
🚀 如何在内网中运行 Cesium?基于 NestJS 构建离线地形与影像服务
前端·gis