使用CSS3的 border-radius
属性,我们可以制作圆角或圆形。添加一些渐变效果,就能让他们变成球体。让我们来试试,给这些球体添加一些动画,让效果更接近我们的生活。
我们有两种方法,可以使用CSS来制作球体。
一个是使用大量的元素标签来创建一个 3D球体 。比如说下面的一个效果:
其最大的缺点就是要使用很多个元素,这样会影响性能。而且这些效果看起来也有点粗糙,球面也不光滑。
另一个方法就是我们接下来要探讨的方法,利用CSS的渐变和阴影在单个元素上创建3D球体效果。
下面内容中提到的例子都可以在 Codepen 上找到,或者点击Codepen的编辑链接查看每个示例的源码。
示例中的代码,没有为每个浏览器添加对应的私有前缀。我建议使用 Autoprefixer 插件根据需要添加浏览器私有前缀。
在详细介绍示例效果这前,我们先创建一个最简单的圆形形状。那么我们就从HTML开始吧:
<figure class="circle"></figure>
在这里我们使用了 <figure>
元素,实际上可以是任何HTML元素。在HTML5中, <figure>
表示的是一幅图像或图像的一部分内容,移除内容也不会影响需要表达的语义。
需要把这个元素创建成一个圆,我样只要给它设置一个宽度和高度,并且设置 border-radius
值为 50%
。 border-radius
值只要超过 50%
就能制作一个圆。当然,其前提是元素的 width
和 height
是相同(即是一个正方形)。
.circle { display: block; background: black; border-radius: 50%; height: 300px; width: 300px; margin: 0; }
这个时候,你看到的效果如下所示:
现在,我们已经有了一个基本的圆,我们可以在这个基础上添加一些样式,让其变成球形。
CSS其实不仅仅能制作出圆形,其还可以制作出更多图形,如果你对这方面感兴趣,可以阅读早期分享过的《CSS制作图形速查表》和《纯CSS制作的图形效果》。
大多数3D球体的教程做的第一件事情就是添加一个径向渐变,颜色淡一点,并且整圆心偏左一点。
我们可以使用下面的这段CSS代码:
.circle { display: block; background: black; border-radius: 50%; height: 300px; width: 300px; margin: 0; background: radial-gradient(circle at 100px 100px, #5cabff, #000); }
这个时候,效果就变成这样:
radial-gradient
属性需要一些参数。第一个是渐变的圆心。在此之前一般是从 shape
所在的 position
来定。在这个示例中,圆心的位置是 (100px,100px)
。
接下来要指定一系列的颜色。你可以指定两个以前的颜色,同时需要给他们指定对应的位置,让他们有一定的距离,使渐变颜色能更好的融入在一起。
本例中指定了两个颜色。第一个颜色从 0%
慢慢过渡到位置在 100%
位置的颜色。如果我们想要其他的渐变效果,可以指定距离,指定距离可以使用像素或百分比。在接下来的示例中,我们可以看到。
现在的3D效果看起来有点“3D-ish”。没关系,我们可以让其变得更好看一点。
在球面上取用不同的材质,你可以创建出不同的球体效果。首先我们需要有一个地方可以用来创建。
在前面的基础上,我们再添加两个元素:
<section class="stage"> <figure class="ball"><span class="shadow"></span></figure> </section>
在 ball
元素中添加一个 span
元素用来创建球体的影子效果,而且把它们放在一个名为 stage
的 <div>
元素内。这个 div.stage
是很有用的,我们可以给其设置一些角度和影子的位置,让3D球体看起来更具3D效果。
给他们应用一些样式代码:
.stage { width: 300px; height: 300px; display: inline-block; margin: 20px; perspective: 1200px; perspective-origin: 50% 50%; } .ball .shadow { position: absolute; width: 100%; height: 100%; background: radial-gradient(circle at 50% 50%, rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.1) 40%, rgba(0, 0, 0, 0) 50%); transform: rotateX(90deg) translateZ(-150px); z-index: -1; }
请注意,在这演示的代码没有添加浏览器前缀,但在Codepen上的示例都已添加了前缀。在上面的示例中,给 div.stage
设置了 perspective
的值为 1200px
。这个 perspective
属性对于3D变形来说至关重要。该属性会设置查看者的位置,并将可视内容映射到一个视锥上,继而投到一个2D视平面上。如果不指定透视,则Z轴空间中的所有点将平铺到同一个2D视平面中,并且变换结果中将不存在景深概念。简单点说, perspective
让一个舞台看起来在一个3D场景中。
有关于 perspective
属性的详细介绍,可以阅读《 Transform-style和Perspective属性 》。
然后使用渐变给球体制作一个阴影,并且给它设置一个 transform
效果,转换阴影位置。你可以使用 rotate
、 scale
、 translate
或者 skew
在3D空间中改为阴影位置。球体的阴影在 X
轴旋转了 90deg
,然后 Z
轴向下推 150px
。
我们给舞台容器 stage
设置了一个 perspective
值,我们往下看,可以看到一个椭圆形。
现在的效果看起来比以前好多了,接下来给它添加更多的材质效果,让其看起来更像一个3D球体。
在现实世界 中你很难从一个角度找到对象。表现光线反射到其他表面上,最终和不同的光源混合 在一起。使用一个伪元素添加两个渐变效果,让其看起来有两种光源结合在一起,如此一来可以创建一个更接近真实的球体。
.ball { display: inline-block; width: 100%; height: 100%; margin: 0; border-radius: 50%; position: relative; background: radial-gradient(circle at 50% 120%, #81e8f6, #76deef 10%, #055194 80%, #062745 100%); } .ball:before { content: ""; position: absolute; top: 1%; left: 5%; width: 90%; height: 90%; border-radius: 50%; background: radial-gradient(circle at 50% 0px, #ffffff, rgba(255, 255, 255, 0) 58%); filter: blur(5px); z-index: 2; }
上面用了两个稍微复杂的渐变。
在 ball
元素上用了一个渐变创建了一弱光的效果,渐变的中心定位在元素的 (50% 120%)
位置。这样做,让结束的颜色不明显,渐变看起来过渡效果更流畅。
第二个渐变放在顶部,而且更亮,而且其大小是球体的 90%
宽和高。渐变以圆心为中心,向下逐渐消失。
这里我们使用 :before
创建阴影而不是使用一个新元素来创建。
自从渐变有锋利的边缘效果,我们曾使用 blur
来软化这个锋利的边缘,不让它看上去那么突出。不幸的是,到目前为止,这个属性只有Webkit内核浏览器(Chrome和Safari)支持,但其他浏览器在未来也有可能会支持。
两个渐变效果组合之后,效果看起来更好:
到目前为止,效果看起来很暗,让我们给效果添加一些光泽和创建一个斯诺克球。
为了实现这一目标,我们将利用柔和的光线,调整突出的顶部。我们需要利用两个伪元素来做这个效果。
.ball { display: inline-block; width: 100%; height: 100%; margin: 0; border-radius: 50%; position: relative; background: radial-gradient(circle at 50% 120%, #323232, #0a0a0a 80%, #000000 100%); } .ball:before { content: ""; position: absolute; background: radial-gradient(circle at 50% 120%, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0) 70%); border-radius: 50%; bottom: 2.5%; left: 5%; opacity: 0.6; height: 100%; width: 90%; filter: blur(5px); z-index: 2; } .ball:after { content: ""; width: 100%; height: 100%; position: absolute; top: 5%; left: 10%; border-radius: 50%; background: radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.8) 14%, rgba(255, 255, 255, 0) 24%); transform: translateX(-80px) translateY(-90px) skewX(-20deg); filter: blur(10px); }
这里在球体最初的颜色做了一个微秒的变化。同时在 :before
伪类上写了一个更突出的效果,这个效果再次从球体的底部向球的表面反射光。
接下来添加了下新的伪类 :after
,在这个伪类上使用一个从中心开始由白色过渡到透明(大约是在 24%
的位置)的径向的渐变。这将创建了一个白色闪亮的效果,为了让它看上去更像一个反射的三维对像,我们在上面使用CSS的 transform
。
使用 transform
属性,将元素向左移 80px
( translateX(-80px)
),并且向上移 90px
( translateY(-90px)
),同时在 X
轴扭转 -20deg
( skewX(-20deg)
)。这样整个效果,看上去更像一个会发光的球体。
打斯诺克的同学,都知道最后要打一个8号球。下面我们额外增加一步,创建一个8号球。
我们需要额外添加一个元素,用来制作这个 8
的效果:
<section class="stage"> <figure class="ball"> <span class="shadow"></span> <span class="eight"></span> </figure> </section> .ball .eight { width: 110px; height: 110px; margin: 30%; background: white; border-radius: 50%; transform: translateX(68px) translateY(-60px) skewX(15deg) skewY(2deg); position: absolute; } .ball .eight:before { content: "8"; display: block; position: absolute; text-align: center; height: 80px; width: 100px; left: 50px; margin-left: -40px; top: 44px; margin-top: -40px; color: black; font-family: Arial; font-size: 90px; line-height: 104px; }
给这个新创建的元素添加一个 border-radius:100%
样式,创建一个圆,而且将这个圆定位在球体的右上角位置,为了效果更贴切,给它加上一些 transform
样式。为了让球体上能显示出 8
这个数字,需要使用伪类 :before
的 content
,将其值设置为 8
,然后运用一些CSS样式。最后其效果看起来如下:
CSS除了有强大的 transform
属性之外,还有 animation
属性,可以制作一些动画效果。使用CSS的 keyframe
,你可以给 transform
添加一些动画效果。为了能更好的阐述这个,我们接下来创建一个会转动的眼睛。
第一步是在前面的8号球体示例的基础上调整一些颜色。让其看上去更像一个眼睛。修改后的HTML如下所示:
<section class="stage"> <figure class="ball"> <span class="shadow"></span> <span class="iris"></span> </figure> </section>
大部分的CSS类似于制作8号,除一眼睛的膜和瞳孔部分。
.iris { width: 40%; height: 40%; margin: 30%; border-radius: 50%; background: radial-gradient(circle at 50% 50%, #208ab4 0%, #6fbfff 30%, #4381b2 100%); transform: translateX(68px) translateY(-60px) skewX(15deg) skewY(2deg); position: absolute; animation: move-eye-skew 5s ease-out infinite; } .iris:before { content: ""; display: block; position: absolute; width: 37.5%; height: 37.5%; border-radius: 50%; top: 31.25%; left: 31.25%; background: black; } .iris:after { content: ""; display: block; position: absolute; width: 31.25%; height: 31.25%; border-radius: 50%; top: 18.75%; left: 18.75%; background: rgba(255, 255, 255, 0.2); }
在 iris
上创建一个蓝色的渐变,让其看上去像眼睛的膜,并且使用伪类来创建眼睛的瞳孔,使用样式让其更亮一点。并且给他们添加动画效果:
animation: animation-name 5s ease-out infinite;
在这个示例中,创建了一个名为 animation-name
的动画,并且让动画持续 5s
,而且是一直循环这个动画效果。为了让动画看上去更自然一些,给动画添加一个 ease-out
函数,让动画由快到慢运动。
如果没有动画的话,我们创建的只是一个不会转动的眼睛,如下所示:
接下来通过 keyframe
来创建眼球是如何运动。
@keyframes move-eye-skew { 0% { transform: none; } 20% { transform: translateX(-68px) translateY(30px) skewX(15deg) skewY(-10deg) scale(0.95); } 25%, 44% { transform: none; } 50%, 60% { transform: translateX(68px) translateY(-40px) skewX(5deg) skewY(2deg) scaleX(0.95); } 66%, 100% { transform: none; } }
CSS的 animation
中的 keyframe
,初看起来很棘手。通过一系列的阶段来描述元素不同状态在做些什么。每个状态都通过百分比来控制。在这个示例中,主要通过其来改变 iris
中的 transform
。从 20%
开始运用 transform
,来移动睛球。而 0%
到 20%
之间的差距是由浏览器来控制的,其会自动计算,并且让这两个点达到平稳过渡。
继续在每个帧上控制 transform
,正如前面指定的一样。而且让整个动画持续 5s
。
为了能更好的兼容浏览器,别忘了创建 keyfame
动画帧时,添加对应的浏览器前缀。
将 box-shadow
和 animation
结合在一起可以制作出各种各样有趣的效果,比如说气泡效果。
创建气泡效果看起来跟之前的球体类似,只是在用了更透明的颜色,并且在伪类上添加光泽效果。
同时在气泡上使用 transform
,并且借助 animation
让整个气泡摆动起来。
@keyframes bubble-anim { 0% { transform: scale(1); } 20% { transform: scaleY(0.95) scaleX(1.05); } 48% { transform: scaleY(1.1) scaleX(0.9); } 68% { transform: scaleY(0.98) scaleX(1.02); } 80% { transform: scaleY(1.02) scaleX(0.98); } 97%, 100% { transform: scale(1); } }
动画运用在整个气泡上,其效果如下:
到目前为止,我们看到的球体效果都没有使用任何图像。如果使用背景图像来制作球体效果需要添加更多的细节,而且还要利用伪元素的内阴影。如下面看到的示例。
添加一些渐变效果,并且添加一些光泽效果,让人产生一些错觉。
动画也可以用来控制背景图的位置。这样一来我们可以创建一个旋转的地球仪效果。
比如我们拿一张世界地图的平面ltju来作背景:
为了能更好的创建一个3D空间,在效果上添加了一些阴影和动画。下面展示的效果是 @@Sidoruk_SV 写的一个旋转的地球仪:
这篇文章通过示例一步一步的告诉大家如何使用CSS来创建3D球体效果。并且如何利用CSS的 box-shadow
和渐变来给3D球体添加一些光泽效果,让球体更具像是在一个3D空间。并且配合CSS的 animation
让整个球体运动起来。通过上面的示例再次证明了,运用好了 box-shadow
和渐变能制作出各种各样的效果。如果你感兴趣的话,不仿自己动手也试试,说不定能整出更有意思的效果。同时也希望分享您制作的案例。
本文根据 @Donovan 的《 Spheres 》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处: https://cssanimation.rocks/spheres/ 。
常用昵称“大漠”,W3CPlus, Sass中国 创始人,目前就职于手淘。中国Drupal社区核心成员之一。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《 图解CSS3:核心技术与案例实战 》。