「css基础」Transforms 属性在实际项目中如何应用?

时间:2022-06-26
本文章向大家介绍「css基础」Transforms 属性在实际项目中如何应用?,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

关于Transform变形属性大家都不陌生吧,可以通过此属性实现元素的位移translate(x,y),缩放scale(x,y),2d旋转rotate(angle),3d旋转rotate3d(angle),倾斜变换skew(x-angle,y-angle)等,你也许已经很熟悉了这些属性,或许你也会有这样的困惑,这些属性在实际项目中如何应用呢?

今天的文章,笔者不会详细一一介绍相关属性,默许大家已经很熟悉了,今天只做例子,聊聊这些属性在实际项目中的应用。

本篇文章笔者将带着大家完成以下几个例子:

  • 内容垂直居中
  • 对话框气泡
  • 弹跳的小球
  • 转动的线圈(SVG)
  • 翻转的卡片

本篇文章预计15分钟

内容垂直居中

在前端开发过程中,内容居中是常见的需求。其中,居中又可以分为水平居中和垂直居中。水平居中是比较容易的,直接设置元素的margin:0 auto 就可以实现。但是垂直居中相对来说是比较复杂一些的。实现的方法也比较多,比如flex布局,display:table等方法,今天笔者将通过使用Transform属性进行实现。

基本的页面布局和样式

为了方便大家理解,我们先布局两个基本的文本框内容,html代码如下:

<div class="parent">
  <div class="child">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
  </div>
</div>

<div class="parent">
  <div class="child">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam
  </div>
</div>

上述代码并不复杂,我们定义了两段内容长度不同的文本。接下来让我们为文本内容定义宽度,高度和边框,让我们更加直观展示文本内容在展示区域的位置,其css部分代码如下:

.parent {
  height: 300px;
  width: 600px;
  padding: 0 1em;
  margin: 1em;
  border: 1px solid red;
}

.child {
  font-size: 1.2rem;
}

加上CSS代码后,我们完成了基本的页面布局和样式,页面的效果如下图:

使其垂直居中

接下来我们来实现文本垂直居中,有的同学可能想到了使用top属性,实现文本的垂直居中,代码可能是这样的:

.child {
  font-size: 1.2rem;
  position: relative;
  top: 50%;
}

运行后,页面的实际效果和我们预想不一致,如下图所示:

从上面的图中可以看出,文本框的实际效果,文本内容的内容并不是在中间而是在下半部分,并不是我们预想的垂直居中,你也许在想,如果我们把文本内容在往上提一半,正好能满足垂直居中的需求,Transform属性中正好有个平移的属性translate(x,y),我们可以使用Transform让元素在y轴方向移动,样式代码修改如下:

.child {
  font-size: 1.2rem;
  position: relative;
  top: 50%;
  transform: translateY(-50%);
}

正如我们所想,我们实现了内容的垂直居中,完成的效果如下:

细心的同学会注意到,元素的中心位置是在“半像素”这条线上,有可能显得模糊,我们可以添加perspective(视域)属性,让其更清楚,如下代码所示:

.child {
  // ...
  transform: perspective(1px) translateY(-50%);
}

最终的代码

经过上面的步骤,我们最终完成了内容的垂直居中,最终的效果如下:

以下是最终的css代码,是不是很简单:

.parent {
  height: 300px;
  width: 600px;
  padding: 0 1em;
  margin: 1em;
  border: 1px solid red;
}

.child {
  font-size: 1.2rem;
  position: relative;
  top: 50%;
  transform: perspective(1px) translateY(-50%);
}

对话框气泡

微信想必大家天天用,我们是否注意到聊天界面里文本对话框气泡,右边或左边会凸出个小箭头指向聊天人的头像,这个例子就要实现类似微信对话框的气泡。

创建基本的页面布局

首先我们先创建一个基本的布局,代码如下:

html部分

<div class="box">
  <div class="box-content">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam
  </div>
</div>

css部分

html {
  font-size: 16px;
}
.box {
  width: 10rem;
  background-color: #e0e0e0;
  padding: 1rem;
  margin: 1rem;
  border-radius: 1rem;
}

完成以后,我们的页面效果如下:

添加气泡箭头

接下来我们来实现右箭头的气泡效果,贴着文本框我们在右边放置个空文本框,我们使用css的为元素属性 ::before 来实现,样式代码如下:

.box::before {
  content: '';
  width: 1rem;
  height: 1rem;
  background-color: #e0e0e0;
  overflow: hidden;
}

注:上述宽和高的属性,如果值越大,气泡的箭头就越大。

这个宽高1rem的正方形无内容的文本还在文本框内,我们还无法看到,我们需要将这个文本框右对齐,使其的一半内容露在外边,修改后的css代码如下:

.box {
  // ...
  position: relative;
}

.box::before {
  // ...
  position: absolute;
  right: -0.5rem;
}

完后的效果,我们的页面效果是这样的:

气泡箭头应该在内容中间区域的位置,接下来,移动这个小方块的位置,正好可以利用我们刚才学到垂直居中知识,css样式代码如下:

.box::before {
  // ...
  top: 50%;
  transform: translateY(-50%);
}

完成后的,这个小方块真的居中了,页面实际效果如下图所示:

从上图我们可以看出,为了实现向右小箭头三角的效果,我们只需要将方块旋转45度即可,修改后的css代码如下:

.box::before {
  // ...
  top: 50%;
  transform: translateY(-50%) rotate(45deg);
}

最终完成的代码

好了,我们的气泡效果完成了,效果如下:

最终完成的css代码如下:

html {
  font-size: 20px;
}

.box {
  width: 10rem;
  background-color: #e0e0e0;
  padding: 1rem;
  margin: 1rem;
  border-radius: 1rem;
  position: relative;
}

.box::before {
  content: '';
  width: 1rem;
  height: 1rem;
  background-color: #e0e0e0;
  overflow: hidden;
  position: absolute;
  right: -0.5rem;
  top: 50%;
  transform: translateY(-50%) rotate(45deg);
}

.box-content {
  position: relative;
  z-index: 2;
}

弹跳的小球

接下来我们要完成一个常见的需求,比如我们通过API请求后台数据,上传图片等不能立返回结果,我们需要让用户在页面停留片刻,为了给用户良好的用户体验,我们一般都会有个正在加载中的动画进行提示,这个例子笔者将带着大家完成下面一个弹跳的小球,效果如下,是不是很酷:

首先我们先进行基本的静态布局

html部分:

<div class="loader"></div>

css部分:

.loader {
  border-radius: 50%;
  width: 50px;
  height: 50px;
  background: linear-gradient(to bottom, #cb60b3 0%,#c146a1 50%,#a80077 51%,#db36a4 100%);
}

这样我们就完成了一个具有颜色渐变的静态的紫色小球,效果如下:

接下来声明动画名

如何让这个静态的小球动起来呢,我们需要借助css的动画属性,我们来定义一个名为jump的无限循环动画,先快后慢,然后反方向执行一遍动画,1.5s循环一次,代码如下:

.loader {
  // ...
  animation: jump 1.5s ease-out infinite alternate;
}

然后完成动画的实现

怎么定义名为jump的动画?我们让小球在垂直方向移动,我们可以使用translateY进行移动小球:

@keyframes jump {
  from {
    transform: translateY(0px)
  }
  to {
    transform: translateY(-50px)
  }
}

为了让小球有弹跳的空间,我们需要将小球距离顶部50px,css代码修改如下:

.loader {
  margin-top: 50px;
}

继续完善动画效果

为了让动画效果更加有趣,我们可以让小球边旋转边上升,动画部分修改如下:

@keyframes jump {
  from {
    transform: translateY(0px) rotate(0deg)
  }
  to {
    transform: translateY(-50px) rotate(360deg)
  }
}

我们动画可以继续完善,让其更加自然,小球上升过程中,相对地面的观察者,弹的越高,就会感觉小球越小,接下来修改小球动画部分,使用scale属性来缩小球,代码如下:

@keyframes jump {
  from {
    transform: translateY(0px) rotate(0deg) scale(1,1);
    opacity: 1;
  }
  to {
    transform: translateY(-50px) rotate(360deg) scale(0.8,0.8);
    opacity: 0.8;
  }
}

最终完成的css代码

好了,这个效果我们就这样完成了,其完成后的css代码如下,是不是很简单?

.loader {
  margin-top: 50px;
  border-radius: 50%;
  width: 50px;
  height: 50px;
  animation: jump 1.5s ease-out infinite alternate;
background: linear-gradient(to bottom, #cb60b3 0%,#c146a1 50%,#a80077 51%,#db36a4 100%);
}
@keyframes jump {
  from {
    transform: translateY(0px) rotate(0deg) scale(1,1);
    opacity: 1;
  }
  to {
    transform: translateY(-50px) rotate(360deg) scale(0.8,0.8);
    opacity: 0.8;
  }
}

转动的线圈(SVG)

这个例子,我们要实现一个更炫的加载提示器,这次我们要做的是基于SVG的动画效果,要理解这部分内容,你需要会svg相关的基础知识,具体的效果如下,感觉就像”头部“的那个东西在牵动线条转圈圈,是不是很酷:

首先进行基本的绘制

我们先用svg绘制一个基本的圈,示例的代码如下:

<svg class="spinner" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"> <!-- 1 -->

  <circle class="path spinner-border" cx="33" cy="33" r="31" stroke="url(#gradient)"></circle> <!-- 2 -->

  <linearGradient id="gradient"> <!-- 3 -->
    <stop offset="50%" stop-color="#000" stop-opacity="1"></stop>
    <stop offset="65%" stop-color="#000" stop-opacity=".5"></stop>
    <stop offset="100%" stop-color="#000" stop-opacity="0"></stop>
  </linearGradient>

  <circle class="path spinner-dot" cx="37" cy="3" r="2"></circle> <!-- 4 -->

</svg>

上述代码我们完成了以下内容:

  • 我们定义了一个66×66的视口。
  • 我们定义了一个半径为31px的圆圈。
  • 对圆圈的填充我们使用了线性填充,分成了三段,实现了比较酷的渐变填充的线条效果。
  • 接下来我们在圆圈上添加了一个小圆,让用户感觉这个线圈是这个小圆点牵着转动。

接下来我们来定义css部分,将画布定义成180*180,示例代码如下:

.spinner {
  margin: 10px;
  width: 180px;
  height: 180px;
}

然后我们来定义线圈和实心的小圆的css属性:

.spinner-dot {
  stroke: #000;
  stroke-width: 1;
  fill: #000;
}

.spinner-border {
  fill: transparent;
  stroke-width: 2;
  width: 100%;
  height: 100%;
}

.path {
  stroke-dasharray: 170;
  stroke-dashoffset: 20;
}

上述代码有几个属性需要解释下:

  • fill: transparent 的效果就是让大圈圈的填充颜色为透明色,只是个圈圈的线条而已。
  • stroke-dasharray: 170 的意思就是绘制点线和虚线,其实我们显示的不是一个完整的圆圈,给人一种转成圆圈的线条感觉,其值代表线条的长度
  • stroke-dashoffset: 表示偏移绘制起点的距离,其值越大,我们的线条越短。
  • 通过stroke-dasharray,stroke-dashoffset这两个属性,让我们绘制了一个不完整的圆圈。

关于stroke-dasharray,stroke-dashoffset的介绍建议大家看张鑫旭老师的这篇博文《纯CSS实现帅气的SVG路径描边动画效果》 https://www.zhangxinxu.com/wordpress/2014/04/animateion-line-drawing-svg-path-动画-路径/

通过上述代码,我们静态的线圈绘制好了,效果如下所示:

定义动画,让线圈转动起来

让线圈动起来,其实就是让其一直选择360度而已,我们让其2秒转一圈,示例代码如下:

.spinner {
  // ...
  animation: rotate 2s linear infinite;
}

@keyframes rotate {
  to {
    transform: rotate(360deg);
  }
}

让牵动线圈运动的小实心圆更有趣,感觉就像一个牵动发动机的“头”,让其倾斜摆动,示例代码如下:

.spinner-dot {
  // ...
  animation: skew 2s linear infinite alternate;
}

@keyframes skew {
  from {
    transform: skewX(10deg)
  }
  to {
    transform: skewX(40deg)
  }
}

最终完成的代码

就这样我们实行了一个个酷酷的的,转动线圈的效果,完整的css代码如下:

.spinner {
  margin: 10px;
  animation: rotate 2s linear infinite;
  width: 180px;
  height: 180px;
}

.spinner-dot {
  stroke: #000;
  stroke-width: 1;
  fill: #000;
  animation: skew 2s linear infinite alternate;
}

.spinner-border {
  fill: transparent;
  stroke-width: 2;
  width: 100%;
  height: 100%;
}

.path {
  stroke-dasharray: 170;
  stroke-dashoffset: 20;
}

@keyframes rotate {
  to {
    transform: rotate(360deg);
  }
}

@keyframes skew {
  from {
    transform: skewX(10deg)
  }
  to {
    transform: skewX(40deg)
  }
}

翻转的卡片

这个动画效果也是我们常见的,类似一些网站的图片,我们鼠标悬停在上面,图片进行了翻转,就好像一个卡片,翻转到其背面,显示了背面的内容,实现后的效果如下所示:

静态页面布局

首先我们先完成图片卡片的基本布局,示例代码如下:

<section class="container">

  <figure class="photo">
    <img src="https://images.freeimages.com/images/large-previews/535/natural-wonders-1400924.jpg" class="front side">

    <figcaption class="back side">
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    </figcaption>
  </figure>

  <figure class="photo">
    <img src="https://images.freeimages.com/images/large-previews/6d5/lake-at-the-cottage-1372381.jpg" class="front side">

    <figcaption class="back side">
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    </figcaption>
  </figure>

  <figure class="photo">
    <img src="https://images.freeimages.com/images/large-previews/a0d/autumn-tree-1382832.jpg" class="front side">

    <figcaption class="back side">
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    </figcaption>
  </figure>

</section>

上述代码我们有三张图片,并且我们定义了图片背面的文字内容。

接下来我们来定义容器的样式,让三张图片在页面居中:

.container {
  margin: 10px auto;
}

然后我们定义每张图片在容器中左浮动,排成一行,并定义图片的宽与高:

.photo {
  width: 22vw;
  height: 20vw;
  min-width: 130px;
  min-height: 100px;
  float: left;
  margin: 0 20px;
}

接着我们定义图片的填充方式为cover:

.photo img {
  object-fit: cover;
}

最后我们定义图片文字介绍的样式:

.side {
  width: 100%;
  height: 100%;
}

完成后的效果如下:

接着我们继续将文字介绍内容移到图片的顶部:

.photo {
  // ...
  position: relative;
}

.side {
  // ...
  position: absolute;
}

完成后的效果如下所示:

让文字到背面去

现在开始使用css的魔法属性,将图片放置到3D空间去,将其3d变换,给人一种透视的感觉,我们使用transform-style这个属性,示例代码如下:

.photo {
  // ...
  transform-style: preserve-3d;
}

然后修改side样式,定义文字内容为背面,且背面属性不可见,这里使用了css的backface-visibility属性:

.side {
  // ...
  backface-visibility: hidden;
}

然后定义back相关的样式,先让背面翻转过去,在y轴上旋转180度。

.back {
  transform: rotateY(180deg);
  text-align: center;
  background-color: #e0e0e0;
}

这样我们的文字描述部分在背面被隐藏了。

定义悬停动画

接下来,我们定义鼠标悬停翻转卡片的功能,示例代码如下:

.photo:hover {
  transform: rotateY(180deg);
}

为了让动画效果不这么生硬,我们需要增加过渡的动画属性,代码完善如下:

.photo {
  // ...
  transition: transform 1s ease-in-out;
}

最终完成后的代码

好了,最后一个例子我们也完成了,是不是很有趣,最终完整的css代码如下:

.container {
  margin: 10px auto;
}

.photo {
  width: 22vw;
  height: 20vw;
  min-width: 130px;
  min-height: 100px;
  float: left;
  margin: 0 20px;
  position: relative;
  transform-style: preserve-3d;
  transition: transform 1s ease-in-out;
}

.photo:hover {
  transform: rotateY(180deg);
}

.photo img {
  object-fit: cover;
}

.side {
  width: 100%;
  height: 100%;
  position: absolute;
  backface-visibility: hidden;
}

.back {
  transform: rotateY(180deg);
  text-align: center;
  background-color: #e0e0e0;
}

友情提醒

毫无疑问,CSS3为我们提供了强大的动画功能,甚至不需要任何JS我们就可以于创建有趣和美丽的动画效果。但是,重要的是要合理使用它们而不是滥用它们。请记住,您的网站是为用户而不是为自己服务的(在大多数情况下,无论如何)。因此,应该利用CSS动画为用户提供更好的用户体验,而不是耍酷。

小节

在本文中,我们已经了解了如何将CSS的Transforms变换属性运用到真实的项目中。通过本文,我们已经了解了如何在页面上垂直对齐元素,对话框气泡,弹跳和旋转的加载动画,以及如何实现翻转动画。当然,也许你学会了其中的技巧,但是创造炫酷的动画,唯一的瓶颈限制就是你的想象力。

更多精彩内容,请微信关注“前端达人”公众号