整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

使用CSS变换为您的网站元素设置动画

们都被移动的物体和不寻常的方向所吸引。动画效果可用于改善用户界面或吸引用户注意项目的重要部分。

在这篇文章中,我将向您展示如何应用不同的转换来改善您网站的可用性和设计。

CSS转换

您可以使用CSS属性以多种不同方式对网站元素进行转换,从而为网站元素添加效果 transform。此属性允许您 使用各种变换函数旋转,缩放,移动和倾斜元素。您还可以在鼠标悬停或鼠标单击时触发这些转换。我将在以后的文章中介绍三维变换。

让我们看看每个转换属性函数。

规模

该 scale 函数允许您增加或减少元素的大小,即按元素缩放元素。

例如,因子 2 会将元素的大小转换为其原始大小的2倍。同样,因子 0.4 会将其大小转换为原始大小的0.4倍。

我们来拍摄尺寸为200 * 200的图像。

HTML

<img src = “pic.jpg” class = “element” width = “200” height = “200” >

为图像分配了一个名为“element”的类。

为了使图像大1.5倍,我们将使用 属性的 scale 功能 transform。

CSS

.element:hover {
	-webkit-transform: scale(1.5);
	-moz-transform: scale(1.5);
	-o-transform: scale(1.5);
	transform: scale(1.5);
}

因为我们将1.5作为参数传递给scale 函数,所以上面的代码会将图像的宽度和高度都增加到原始图像的1.5倍 。请注意,该 transform 属性具有供应商前缀 -webkit-, -moz- 并且 -o-。这些是为了获得所有浏览器的最佳支持。

要使转换平滑,请使用该 transition 属性。

CSS

.element{
	-webkit-transition: transform .2s linear;
	-moz-transition: transform .2s linear;
	-o-transition: transform .2s linear;
	transition: transform .2s linear;
}
.element:hover {
	-webkit-transform: scale(1.5);
	-moz-transform: scale(1.5);
	-o-transform: scale(1.5);
	transform: scale(1.5);
}		

这种转换特性将使转换线性发生0.2秒。将鼠标悬停在下图中可查看此转换的实时演示。

更具体地说,您可以使用 scaleX 和 scaleY 值分别缩放元素的宽度和高度。

HTML

<img src = “pic.jpg” class = “scale1” width = “200” height = “200” > 
<img src = “pic.jpg” class = “scale2” width = “200” height = “200” >

CSS

.scale1{
	-webkit-transition: transform .2s linear;
	-moz-transition: transform .2s linear;
	-o-transition: transform .2s linear;
	transition: transform .2s linear;
}
.scale1:hover {
	-webkit-transform: scaleX(1.2);
	-moz-transform: scaleX(1.2);
	-o-transform: scaleX(1.2);
	transform: scaleX(1.2);
}
.scale2{
	-webkit-transition: transform .2s linear;
	-moz-transition: transform .2s linear;
	-o-transition: transform .2s linear;
	transition: transform .2s linear;
}
.scale2:hover {
	-webkit-transform: scaleY(.8);
	-moz-transform: scaleY(.8);
	-o-transform: scaleY(.8);
	transform: scaleY(.8);
}

在悬停在各个图像上时,具有类'scale1'的第一图像的宽度将增加到其原始宽度的1.2倍,并且具有类'scale2'的第二图像的高度将减小到其原始高度的0.8倍。尝试将鼠标悬停在以下图像上。

现在,考虑您希望将宽度增加到1.2倍并将高度同时降低到元素原始值的0.8倍的情况。为此,您必须为scale 以逗号分隔的函数提供两个值 。第一个值将缩放其宽度,第二个值将缩放其高度。

CSS

.element{
	-webkit-transition: transform .2s linear;
	-moz-transition: transform .2s linear;
	-o-transition: transform .2s linear;
	transition: transform .2s linear;
}
.element:hover {
	-webkit-transform: scale(1.2, .8);
	-moz-transform: scale(1.2, .8);
	-o-transform: scale(1.2, .8);
	transform: scale(1.2, .8);
}

您还可以缩放其他CSS属性,如 填充字体大小

回转

这是该transform 物业的另一项功能 。使用此功能,您可以按任何方向旋转元素,无论您想要哪个方向。正值将顺时针旋转元素,负值将逆时针旋转。

让我们尝试将图像旋转一定角度,尽管您可以旋转几乎任何像 div,span,headings或paragraph这样的东西。 您也可以尝试旋转整个html体。听起来怪怪的?试一试吧。

HTML

<img src = “pic.jpg” class = “rotate1” > 
<img src = “pic.jpg” class = “rotate2” >

CSS

/* first image */
.rotate1{
	-webkit-transition: transform .2s linear;
	-moz-transition: transform .2s linear;
	-o-transition: transform .2s linear;
	transition: transform .2s linear;
}

.rotate1:hover {
	-webkit-transform: rotate(40deg);
	-moz-transform: rotate(40deg);
	-o-transform: rotate(40deg);
	transform: rotate(40deg);
}

/* second image */
.rotate2{
	-webkit-transition: transform .2s linear;
	-moz-transition: transform .2s linear;
	-o-transition: transform .2s linear;
	transition: transform .2s linear;
}

.rotate2:hover {
	-webkit-transform: rotate(-40deg);
	-moz-transform: rotate(-40deg);
	-o-transform: rotate(-40deg);
	transform: rotate(-40deg);
}

默认情况下,该 rotate 函数沿Z轴旋转元素。可以专门旋转沿X,Y的元素,并使用Z轴的功能 rotateX, rotateY 和 rotateZ 分别。我们来看看如何。

HTML

<img src = “pic.jpg” class = “rotate1” > 
<img src = “pic.jpg” class = “rotate2” > 
<img src = “pic.jpg” class = “rotate3” >

CSS

/* first image */
.rotate1{
	-webkit-transition: transform 1s linear;
	-moz-transition: transform 1s linear;
	-o-transition: transform 1s linear;
	transition: transform 1s linear;
}
.rotate1:hover {
	-webkit-transform: rotateX(180deg);
	-moz-transform: rotateX(180deg);
	-o-transform: rotateX(180deg);
	transform: rotateX(180deg);
}
/* second image */
.rotate2{
	-webkit-transition: transform 1s linear;
	-moz-transition: transform 1s linear;
	-o-transition: transform 1s linear;
	transition: transform 1s linear;
}
.rotate2:hover {
	-webkit-transform: rotateY(180deg);
	-moz-transform: rotateY(180deg);
	-o-transform: rotateY(180deg);
	transform: rotateY(180deg);
}
/* third image */
.rotate3{
	-webkit-transition: transform .2s linear;
	-moz-transition: transform .2s linear;
	-o-transition: transform .2s linear;
	transition: transform .2s linear;
}
.rotate3:hover {
	-webkit-transform: rotateZ(40deg);
	-moz-transform: rotateZ(40deg);
	-o-transform: rotateZ(40deg);
	transform: rotateZ(40deg);
}

第一和第二表情分别沿X和Y轴旋转180度。第三个笑脸沿Z轴旋转40度,这也是默认的旋转轴。

您可以通过组合这些转换来创建许多新组合。现在,让我们转到另一个转换函数。

翻译

您可以使用该translate 功能在水平,垂直或任何其他方向上移动元素 。它只会改变应用它的元素的位置,而不会中断文档的正常流动。

translateX 用于水平移动元素。给出正值将使其向右移动并向左移动负值。 translateY 将在垂直方向移动您的元素。同样,正值会将其向下移动并向上移动负值。

HTML

<img src = “pic.jpg” class = “translate1” > 
<img src = “pic.jpg” class = “translate2” >

CSS

/* first image */
.translate1{
	-webkit-transition: transform .2s linear;
	-moz-transition: transform .2s linear;
	-o-transition: transform .2s linear;
	transition: transform .2s linear;
}
.translate1:hover {
	-webkit-transform: translateX(40px);
	-moz-transform: translateX(40px);
	-o-transform: translateX(40px);
	transform: translateX(40px);
}
/* second image */
.rotate2{
	-webkit-transition: transform .2s linear;
	-moz-transition: transform .2s linear;
	-o-transition: transform .2s linear;
	transition: transform .2s linear;
}
.rotate2:hover {
	-webkit-transform: translateY(20px);
	-moz-transform: translateY(20px);
	-o-transform: translateY(20px);
	transform: translateY(20px);
}

使用该translateX 函数将第一图像向右移动40px, 使用该translateY 值向下移动第二图像20px 。您也可以同时水平和垂直移动相同的元素。为此,您必须将两个参数传递translate 给以逗号分隔的 函数。第一个值将水平移动元素,而第二个值将垂直移动元素。

HTML

<img src = “pic.jpg” class = “translate1” >

CSS

.translate1{
	-webkit-transition: transform .2s linear;
	-moz-transition: transform .2s linear;
	-o-transition: transform .2s linear;
	transition: transform .2s linear;
}
.translate1:hover {
	-webkit-transform: translate(40px,20px);
	-moz-transform: translate(40px,20px);
	-o-transform: translate(40px,20px);
	transform: translate(40px,20px);
}

上图是跟随悬停的路径,其中最终位置向右40px,低于初始位置20px。

浏览器支持

google之外的所有浏览器都支持此属性 。此外, IE 不支持 transform-style:preserve-3d 属性,因此阻止了3D转换元素的嵌套。

结论

如果适当应用,各种网站元素的位置和方向的微小动画转换可以为您的网站设计带来生命。这只是关于不同类型转换的介绍和基本用法的帖子。这些可用于创建非常惊人的效果和动画,我将在以后的帖子中继续介绍。

欢迎加评论区讨论。整理不易,祝给我收藏关注的大佬发大财emmm。

markdown中写下你的文章,并使用Python将它们转换成HTML-作者Florian Dahlitz,于2020年5月18日(15分钟)

介绍

几个月前,我想开通自己的博客,而不是使用像Medium这样的网站。这是一个非常基础的博客,所有的文章都是HTML形式的。然而,有一天,我突然产生了自己编写Markdown到HTML生成器的想法,最终这将允许我用markdown来编写文章。此外,为它添加诸如估计阅读时间之类的扩展特性会更容易。长话短说,我实现了自己的markdown到HTML生成器,我真的很喜欢它!

在本系列文章中,我想向您展示如何构建自己的markdown到HTML生成器。该系列由三部分组成:

  • 第一部分(本文)介绍了整个管线的实现。

  • 第二部分通过一个模块扩展了实现的管线,该模块用于计算给定文章的预计阅读时间。

  • 第三部分演示如何使用管线生成自己的RSS摘要。

这三部分中使用的代码都可以在GitHub上找到。

备注:我的文章中markdown到HTML生成器的想法基于Anthony Shaw文章中的实现。

项目构建

为了遵循本文的内容,您需要安装几个软件包。我们把它们放进requirements.txt文件。

Markdown是一个包,它允许您将markdown代码转换为HTML。之后我们用Flask产生静态文件。

但在安装之前,请创建一个虚拟环境,以避免Python安装出现问题:

激活后,您可以使用pip安装requirements.txt中的依赖。

很好!让我们创建几个目录来更好地组织代码。首先,我们创建一个app目录。此目录包含我们提供博客服务的Flask应用程序。所有后续目录都将在app目录内创建。其次,我们创建一个名为posts的目录。此目录包含要转换为HTML文件的markdown文件。接下来,我们创建一个templates目录,其中包含稍后使用Flask展示的模板。在templates目录中,我们再创建两个目录:

posts包含生成的HTML文件,这些文件与应用程序根目录中posts目录中的文件相对应。

shared包含在多个文件中使用的HTML文件。

此外,我们还创建了一个名为services的目录。该目录将包含我们在Flask应用程序中使用的模块,或者为它生成某些东西。最后,创建一个名为static的目录带有两个子目录images和css。自定义CSS文件和文章的缩略图将存储在此处。

您的最终项目结构应如下所示:

令人惊叹!我们完成了一般的项目设置。我们来看看Flask的设置。

Flask设置

路由

我们在上一节安装了Flask。但是,我们仍然需要一个Python文件来定义用户可以访问的端点。在app目录中创建main.py并将以下内容复制到其中。

该文件定义了一个具有两个端点的基础版Flask应用程序。用户可以使用/route访问第一个端点返回索引页,其中列出了所有文章。

第二个端点是更通用的端点。它接受post的名称并返回相应的HTML文件。

接下来,我们通过向app目录中添加一个__init__.py,将其转换为一个Python包。此文件为空。如果您使用UNIX计算机,则可以从项目的根目录运行以下命令:

模板

现在,我们创建两个模板文件index.html以及layout.html,都存储在templates/shared目录中。这个layout.html模板将用于单个博客条目,而index.html模板用于生成索引页,从中我们可以访问每个帖子。让我们从index.html模板开始。

它是一个基本的HTML文件,其中有两个元标记、一个标题和两个样式表。注意,我们使用一个远程样式表和一个本地样式表。远程样式表用于启用Bootstrap[1]类。第二个是自定义样式。我们晚点再定义它们。

HTML文件的主体包含一个容器,其中包含Jinja2[2]逻辑,用于为每个post生成Bootstrap卡片[3]。您是否注意到我们不直接基于变量名访问这些值,而是需要将[0]添加到其中?这是因为文章中解析的元数据是列表。实际上,每个元数据元素都是由单一元素组成的列表。我们稍后再看。到目前为止,还不错。让我们看看layout.html模板。

如你所见,它比前一个短一点,简单一点。文件头与index.html文件很相似,除了我们有不同的标题。当然,我们可以共用一个模板,但是我不想让事情变得更复杂。

body中的容器仅定义一个h1标记。然后,我们提供给模板的内容被插入并呈现。

样式

正如上一节所承诺的,我们将查看自定义CSS文件style.css. 我们在static/css中找到该文件,并根据需要自定义页面。下面是我们将用于基础示例的内容:

我不喜欢Bootstrap中blockquotes的默认外观,所以我们在左侧添加了一点间距和边框。此外,blockquote段落底部的页边空白将被删除。不删除的话看起来很不自然。

最后但并非最不重要的是,左右两边的填充被删除。由于两边都有额外的填充,缩略图没有正确对齐,所以在这里删除它们。

到现在为止,一直都还不错。我们完成了关于Flask的所有工作。让我们开始写一些帖子吧!

写文章

正如标题所承诺的,你可以用markdown写文章-是的!在写文章的时候,除了保证正确的markdown格式外,没有其他需要注意的事情。

在完成本文之后,我们需要在文章中添加一些元数据。此元数据添加在文章之前,并由三个破折号分隔开来---。下面是一个示例文章(post1.md)的摘录:

注意:您可以在GitHub库的app/posts/post1.md中找到完整的示例文章。

在我们的例子中,元数据由标题、副标题、类别、发布日期和index.html中卡片对应缩略图的路径组成.

我们在HTML文件中使用了元数据,你还记得吗?元数据规范必须是有效的YAML。示例形式是键后面跟着一个冒号和值。最后,冒号后面的值是列表中的第一个也是唯一的元素。这就是我们通过模板中的索引运算符访问这些值的原因。

假设我们写完了文章。在我们可以开始转换之前,还有一件事要做:我们需要为我们的帖子生成缩略图!为了让事情更简单,只需从你的电脑或网络上随机选取一张图片,命名它为placeholder.jpg并把它放到static/images目录中。GitHub存储库中两篇文章的元数据包含一个代表图像的键值对,值是placeholder.jpg。

注意:在GitHub存储库中,您可以找到我提到的两篇示例文章。

markdown到HTML转换器

最后,我们可以开始实现markdown to HTML转换器。因此,我们使用我们在开始时安装的第三方包Markdown。我们先创建一个新模块,转换服务将在其中运行。因此,我们在service目录中创建了converter.py。我们一步一步看完整个脚本。您可以在GitHub存储库中一次查看整个脚本。

首先,我们导入所需的所有内容并创建几个常量:

ROOT指向我们项目的根。因此,它是包含app的目录。

POSTS_DIR是以markdown编写的文章的路径。

TEMPLATE_DIR分别指向对应的templates目录。

BLOG_TEMPLATE_文件存储layout.html的路径。

INDEX_TEMPLATE_FILE是index.html

BASE_URL是我们项目的默认地址,例如。https://florian-dahlitz.de.默认值(如果不是通过环境变量DOMAIN提供的话)是http://0.0.0.0:5000。

接下来,我们创建一个名为generate_entries的新函数。这是我们定义的唯一一个转换文章的函数。

在函数中,我们首先获取POSTS_DIR目录中所有markdown文件的路径。pathlib的awesome glob函数帮助我们实现它。

此外,我们定义了Markdown包需要使用的扩展。默认情况下,本文中使用的所有扩展都随它的安装一起提供。

注意:您可以在文档[4]中找到有关扩展的更多信息。

此外,我们实例化了一个新的文件加载程序,并创建了一个在转换项目时使用的环境。随后,将创建一个名为all_posts的空列表。此列表将包含我们处理后的所有帖子。现在,我们进入for循环并遍历POSTS_DIR中找到的所有文章。

我们启动for循环,并打印当前正在处理的post的路径。如果有什么东西出问题了,这尤其有用。然后我们就知道,哪个文章的转换失败了。

接下来,我们在默认url之后增加一部分。假设我们有一篇标题为“面向初学者的Python”的文章。我们将文章存储在一个名为python-for-beginners.md,的文件中,因此生成的url将是http://0.0.0.0:5000/posts/python-for-beginners。

变量url_html存储的字符串与url相同,只是我们在末尾添加了.html。我们使用此变量定义另一个称为target_file.的变量。变量指向存储相应HTML文件的位置。

最后,我们定义了一个变量md,它表示markdown.Markdown的实例,用于将markdown代码转换为HTML。您可能会问自己,为什么我们没有在for循环之前实例化这个实例,而是在内部实例化。当然,对于我们这里的小例子来说,这没有什么区别(只是执行时间稍微短一点)。但是,如果使用诸如脚注之类的扩展来使用脚注,则需要为每个帖子实例化一个新实例,因为脚注添加后就不会从此实例中删除。因此,如果您的第一篇文章使用了一些脚注,那么即使您没有明确定义它们,所有其他文章也将具有相同的脚注。

让我们转到for循环中的第一个with代码块。

实际上,with代码块打开当前post并将其内容读入变量content。之后调用_md.convert将以markdown方式写入的内容转换为HTML。随后,env环境根据提供的模板BLOG_TEMPLATE_FILE(即layout.html如果你还记得的话)渲染生成的HTML。

第二个with 代码块用于将第一个with 代码块中创建的文档写入目标文件。

以下三行代码从元数据中获取发布日期(被发布的日期),将其转换为正确的格式(RFC 2822),并将其分配回文章的元数据。此外,生成的post_dict被添加到all_posts列表中。

我们现在出了for循环,因此,我们遍历了posts目录中找到的所有posts并对其进行了处理。让我们看看generate_entries函数中剩下的三行代码。

我们按日期倒序对文章进行排序,所以首先显示最新的文章。随后,我们将文章写到模板目录一个新创建的index.html文件中。别把index.html错认为templates/shared目录中的那个。templates/shared目录中的是模板,这个是我们要使用Flask服务的生成的。

最后我们在函数generate_entries之后添加以下if语句。

这意味着如果我们通过命令行执行文件,它将调用generate_entries函数。

太棒了,我们完成了converter.py脚本!让我们从项目的根目录运行以下命令来尝试:

您应该看到一些正在转换的文件的路径。假设您编写了两篇文章或使用了GitHub存储库中的两篇文章,那么您应该在templates目录中找到三个新创建的文件。首先是index.html,它直接位于templates目录中,其次是templates/posts目录中的两个HTML文件,它们对应于markdown文件。

最后启动Flask应用程序并转到http://0.0.0.0:5000。

总结

太棒了,你完成了这个系列的第一部分!在本文中,您已经学习了如何利用Markdown包创建自己的Markdown to HTML生成器。您实现了整个管线,它是高度可扩展的,您将在接下来的文章中看到这一点。

希望你喜欢这篇文章。一定要和你的朋友和同事分享。如果你还没有,考虑在Twitter上关注我@DahlitzF或者订阅我的通知,这样你就不会错过任何即将发表的文章。保持好奇心,不断编码!

参考文献

Bootstrap (http://getbootstrap.com/)

Primer on Jinja Templating (https://realpython.com/primer-on-jinja-templating/)

Bootstrap Card (https://getbootstrap.com/docs/4.4/components/card/)

Python-Markdown Extensions (https://python-markdown.github.io/extensions/)

Tweet

英文原文:https://florian-dahlitz.de/blog/build-a-markdown-to-html-conversion-pipeline-using-python
译者:阿布铥

HTML5和CSS3的世界里,2D和3D变换为网页设计带来了革命性的变化。通过简单的CSS属性,我们可以实现元素的平移、旋转、缩放和倾斜等效果,从而创造出更加动态和交互性的用户体验。在本文中,我们将探索2D和3D变换的基本概念,并通过一些实例来演示它们的应用。

2D变换

2D变换是指在平面内对元素进行操作,包括平移(translate)、旋转(rotate)、缩放(scale)和倾斜(skew)。以下是一些基本的2D变换例子:

平移(Translate)

.translate-example {
  transform: translate(50px, 100px);
}

这个例子中,元素将沿X轴移动50像素,沿Y轴移动100像素。

旋转(Rotate)

.rotate-example {
  transform: rotate(45deg);
}

在这个例子中,元素将围绕其中心点旋转45度。

缩放(Scale)

.scale-example {
  transform: scale(2, 3);
}

此处,元素的宽度放大到原来的2倍,高度放大到原来的3倍。

倾斜(Skew)

.skew-example {
  transform: skew(30deg, 20deg);
}

这个例子将使元素沿X轴倾斜30度,沿Y轴倾斜20度。

3D变换

3D变换引入了新的维度,即Z轴,为元素添加了深度感。3D变换包括3D平移(translate3d)、3D旋转(rotateX/rotateY/rotateZ)、3D缩放(scale3d)等。

3D平移(Translate3D)

.translate3d-example {
  transform: translate3d(50px, 100px, 200px);
}

在这个例子中,元素沿X轴移动50像素,沿Y轴移动100像素,同时沿Z轴移动200像素,产生一种深入屏幕的效果。

3D旋转(Rotate3D)

.rotate3d-example {
  transform: rotateX(45deg);
}

这里,元素将围绕X轴旋转45度,创建出一个“翻页”的效果。

3D缩放(Scale3D)

.scale3d-example {
  transform: scale3d(2, 2, 2);
}

此例中,元素在三个维度上均放大两倍。

实战例子

让我们通过几个具体的例子来看看2D和3D变换在实际应用中的效果。

例子1:创建一个简单的卡片翻转效果(2D)

<div class="card">
  <div class="card-front">前面</div>
  <div class="card-back">背面</div>
</div>
.card {
  width: 200px;
  height: 300px;
  position: relative;
}

.card-front, .card-back {
  width: 100%;
  height: 100%;
  position: absolute;
  backface-visibility: hidden;
  transition: transform 0.6s;
}

.card-front {
  background-color: #fff;
  z-index: 2;
}

.card-back {
  background-color: #f1f1f1;
  transform: rotateY(180deg);
}

.card:hover .card-front {
  transform: rotateY(-180deg);
}

.card:hover .card-back {
  transform: rotateY(0deg);
}

当鼠标悬停在卡片上时,前面的卡片会翻转到背面。

例子2:3D旋转立方体

<div class="cube">
  <div class="face front">前</div>
  <div class="face back">后</div>
  <div class="face left">左</div>
  <div class="face right">右</div>
  <div class="face top">上</div>
  <div class="face bottom">下</div>
</div>
.cube {
  position: relative;
  width: 200px;
  transform-style: preserve-3d;
  animation: spin 5s infinite linear;
}

.face {
  position: absolute;
  width: 200px;
  height: 200px;
  background-color: rgba(255, 255, 255, 0.7);
  border: 1px solid #ccc;
}

.front  { transform: translateZ(100px); }
.back   { transform: translateZ(-100px) rotateY(180deg); }
.left   { transform: rotateY(-90deg) translateZ(100px); }
.right  { transform: rotateY(90deg) translateZ(100px); }
.top    { transform: rotateX(90deg) translateZ(100px); }
.bottom { transform: rotateX(-90deg) translateZ(100px); }

@keyframes spin {
  from { transform: rotateY(0deg); }
  to { transform: rotateY(360deg); }
}

这个立方体会在页面上无限旋转,展示了一个基本的3D效果。

示例

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>2D & 3D Transform Example</title>
<style>
  body {
    font-family: 'Arial', sans-serif;
    margin: 0;
    padding: 0;
    background: #f0f0f0;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    min-height: 100vh;
  }

  .btn-2d {
    padding: 10px 20px;
    margin: 20px;
    background-color: #007bff;
    color: white;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    outline: none;
    transition: transform 0.3s ease;
  }

  .btn-2d:hover {
    transform: rotateZ(360deg);
  }

  .card-3d {
    width: 200px;
    height: 300px;
    perspective: 1000px;
    cursor: pointer;
    margin: 20px;
  }

  .card-inner {
    width: 100%;
    height: 100%;
    transition: transform 0.6s;
    transform-style: preserve-3d;
    position: relative;
  }

  .card-3d:hover .card-inner {
    transform: rotateY(180deg);
  }

  .card-face {
    position: absolute;
    width: 100%;
    height: 100%;
    backface-visibility: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
    color: white;
    font-size: 24px;
    box-shadow: 0 4px 8px rgba(0,0,0,0.1);
  }

  .card-front {
    background: #007bff;
  }

  .card-back {
    background: #ff5722;
    transform: rotateY(180deg);
  }

  .scene {
    width: 200px;
    height: 200px;
    perspective: 600px;
    margin: 20px;
  }

  .cube {
    width: 100%;
    height: 100%;
    position: relative;
    transform-style: preserve-3d;
    transform: rotateX(-30deg) rotateY(-45deg);
    animation: rotateCube 5s infinite linear;
  }

  .face {
    position: absolute;
    width: 200px;
    height: 200px;
    background: rgba(255, 255, 255, 0.9);
    border: 1px solid #ccc;
  }

  .front  { transform: translateZ(100px); }
  .back   { transform: rotateY(180deg) translateZ(100px); }
  .right  { transform: rotateY(90deg) translateZ(100px); }
  .left   { transform: rotateY(-90deg) translateZ(100px); }
  .top    { transform: rotateX(90deg) translateZ(100px); }
  .bottom { transform: rotateX(-90deg) translateZ(100px); }

  @keyframes rotateCube {
    0% { transform: rotateX(-30deg) rotateY(-45deg); }
    100% { transform: rotateX(-30deg) rotateY(315deg); }
  }

</style>
</head>
<body>

<button class="btn-2d">Click Me!</button>

<div class="card-3d">
  <div class="card-inner">
    <div class="card-face card-front">
      Front Side
    </div>
    <div class="card-face card-back">
      Back Side
    </div>
  </div>
</div>

<div class="scene">
  <div class="cube">
    <div class="face front"></div>
    <div class="face back"></div>
    <div class="face right"></div>
    <div class="face left"></div>
    <div class="face top"></div>
    <div class="face bottom"></div>
  </div>
</div>

</body>
</html>

  • .btn-2d 类定义了一个按钮,当鼠标悬停时,它会应用一个 2D 旋转 (rotateZ) 动画。
  • .card-3d 类定义了一个 3D 翻转卡片的容器,设置了 perspective 属性,这是实现 3D 翻转效果的关键。
  • .card-inner 类定义了卡片的内部元素,它将在鼠标悬停时围绕 Y 轴旋转 (rotateY) 180 度,这是通过 .card-3d:hover .card-inner 选择器设置的。
  • .card-face 类定义了卡片的正反两面,使用了 backface-visibility 属性来在翻转时隐藏背面。
  • .card-front 和 .card-back 类为卡片的前后面分别设置了不同的背景颜色。
  • .scene 类定义了一个 3D 场景的容器,设置了 perspective 属性,以便为其中的 3D 对象创建透视效果。
  • .cube 类定义了正方体的容器,它使用 transform-style: preserve-3d 来保持其子元素的 3D 空间位置。这个容器还应用了一个连续旋转的动画,使正方体不断旋转。
  • .face 类定义了正方体的每个面,每个面都是一个绝对定位的正方形,具有边框和背景颜色。
  • .front、.back、.right、.left、.top 和 .bottom 类分别定义了正方体的六个面的位置,每个面都通过 translateZ 被推到其应在的位置。

结语

通过本文的介绍,我们了解了2D和3D变换的基本概念以及它们在实际应用中的一些例子。随着技术的进步,现代浏览器对这些效果的支持越来越好,而我们作为开发者,可以利用这些工具创造出更加丰富和生动的网页体验。记得在使用这些技术时保持平衡,确保它们增强而不是干扰用户的体验。