CSS中的基本图形和路径
在CSS中有些属性是允许CSS绘制图形形状,比如常见的是使用border
或者box-shadow
来绘制图形或者形状。除此之外,在CSS中还有类似circle()
函数也可以绘制圆形。
除此之外,在CSS中有一些形状是为CSS其它属性服务,比如clip-path
为mask
服务和在shape-outside
让文本围绕形状排版。
还有一些CSS属性使用像SVG中的图形做一些事情,比如offset-path
中使用path()
函数实现路径动画。而其中path()
是一个非常棒的功能,可以绘制任何图形。
在接下来的内容中,来介绍一下CSS中的基本图形和路径。希望对大家有所帮助。
CSS中的基本图形
在CSS中polygon()
、circle()
、ellipse()
和inset()
函数可以绘制基本形状。在CSS中的offset-path
和shape-outside
中都可以使用这四个图形函数,实现对应的路径动画以及文本围绕排版效果。他们虽然绘制基本形状,但也常将其称之为路径图形。那么什么是路径呢?
什么是路径
使用过SVG的同学对路径这个词并不会感到陌生,在SVG中有一个<path>
元素,允许我们绘制任何东西。在HTML中,我们可以这样来使用<path>
绘制图形:
<path d="M 25,100 C 25,150 75,150 75,100 S 100,25 150,75" />
在CSS中可以通过path()
来实现类似上面绘制图形的效果:
path("M 25,100 C 25,150 75,150 75,100 S 100,25 150,75");
属性中的图形
如果你前面有接触过clip-path
或者shape-outside
话知道。虽然这里面用到类似像circle()
和polygon()
的图形,但令人奇怪的是,使用的并不是像SVG中的<path>
或者说path()
函数。而offset-path
却可以使用path()
而不是基本图形里面的图形函数。
看上去有些混乱,但我们可以慢慢将这些理一理,能帮助你更好的理解CSS中的形状和路径。
clip-path可以使用基本形状但不能使用path()
在CSS的clip-path
属性中可以使用CSS的基本图形(polygon()
、circle()
、ellipse()
和inset()
)但不能使用path()
。比如,我们在项目中需要使用不规则的用户头像,那么我们可以通过clip-path
来完成。比如:
.avatar {
clip-path: polygon(0% 5%, 100% 0%, 100% 85%, 65% 80%, 75% 100%, 40% 80%, 0% 75%);
}
你能看到类似下图的效果:
但是,如果你想要用户的头像实现像下图这样形状的效果:
对于上图这样的形状,使用基本的图形形状函数是没办法实现的,但在clip-path
中又没有办法使用path()
函数。不过值得庆幸的是,在clip-path
中可以通过url()
传一个带有ID属性名的<clipPath>
元素。
而<clipPath>
是SVG中的一个元素,在这里面可以通过<path>
元素绘制所需要的图形。比如上面所需的图形,可以通过下面的SVG来绘制:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 201 196.1" class="hide">
<title>bubble-path</title>
<clipPath id="clip">
<path d="M100.5,39.47C100.5,58.3,83.36,74,60.58,77.64l16.85,19.9L33.94,76.25C14.47,70.92.5,56.47.5,39.47c0-21.52,22.39-39,50-39S100.5,17.95,100.5,39.47Z" fill="#fff" stroke="#000" stroke-miterlimit="10"></path>
</clipPath>
</svg>
特别注意:在clipPath
中需要指定一个明确的ID
属性值,比如这里指定了id="clip"
,另外为了让SVG元素不显示,不占空间,给<svg>
元素指定个hide
类名,然后设置样式,让<svg>
元素隐藏起来:
.hide {
position: absolute;
top: -9999px;
left: -9999px;
}
这个时候再通过clip-path
的url()
将SVG绘制的路径图形,运用到用户头像中:
.avatar {
width: 100px;
height: 100px;
margin-right: 2rem;
clip-path: url(#clip);
}
此时你将看到的效果如下图所示:
offset-path可以使用path()但不能使用基本形状
offset-path
早期称为motion-path
。只是后来规范将其改变offset-path
,而它主要用来制作路径动画效果,用来指定动画的行动路径。比如下面这个效果:
动画中的小圆球行动的路径,就是通过path()
来完成的:
path("M100.5,39.47C100.5,58.3,83.36,74,60.58,77.64l16.85,19.9L33.94,76.25C14.47,70.92.5,56.47.5,39.47c0-21.52,22.39-39,50-39S100.5,17.95,100.5,39.47Z");
具体的代码如下:
.move-me {
offset-path: path("M100.5,39.47C100.5,58.3,83.36,74,60.58,77.64l16.85,19.9L33.94,76.25C14.47,70.92.5,56.47.5,39.47c0-21.52,22.39-39,50-39S100.5,17.95,100.5,39.47Z");
animation: move 3s linear infinite;
}
@keyframes move {
100% {
motion-offset: 100%;
}
}
同样的有一个问题,如果你想让小球按一个圆形来运动,你可能会想到像circle(50% at 50% 50%)
来绘制的图形路径,但不幸的是,没有效果。那是因为offset-path
并不支持circle()
函数绘制的路径。不过值得庆幸的是,同样可以使用path()
来会制一个圆形:
offset-path: path("M100,50a50,50,0,1,1-50-50A50,50,0,0,1,100,50Z");
除此之外,还可以使用复合动画来模拟一个圆形动画效果。在@Lea Verou的《CSS Secrets》一书中就有一节专门介绍使用其它方法来实现圆形的路径动效。
其中原理很简单,简单用下图就能阐述:
shape-outside可以使用基本图形,但不支持path()
shape-outside
和clip-path
类似,在其属性值中只能使用CSS的基本图形函数,但不能使用path()
函数绘制的图形。
shape-outside
是能让文本围绕不同形状排版,如果从未接,可以点击早前整理的相关文章。
来看一个简单的示例:
.egg {
float: left;
shape-outside: ellipse(120px 160px at 50% 50%);
width: 280px;
height: 320px;
}
将看到的效果如下:
而其中效果图中的椭圆是通过clip-path
绘制的:
clip-path: ellipse(120px 160px at 50% 50%);
但有时候你想让文本围绕一个弯曲的形状进行排版,像下图所示:
CSS中的基本图形函数是没法绘制上图那相的曲线图形形状,但path()
可以,只不过shape-outside
不能支持path()
绘制的形状。不过还好,在shape-outside
中也可以通过url()
来传SVG中绘制好的形状。也可以像传递一个图片的形式使用:
shape-outside: url('curved-shape.svg');
使用
shape-outside
实现文本围绕不同形状的排版效果,需要对图形元素使用浮动。但在CSS中提供了CSS Exclusions模块,它可以解决这个问题。如果你感兴趣的话,可以阅读《CSS Exclusions:让布局变得更有意思》一文。
在CSS中使用path()改变的基本图形
在SVG中可以通过<path>
来绘制图形。比如:
<svg viewBox="0 0 10 10" class="svg-1">
<path d="M2,2 L8,8" />
</svg>
很有意思的是,在CSS中可以使用path()
来改变SVG中的<path>
图形:
.svg-1:hover path {
d: path("M8,2 L2,8");
}
从上面的效果和代码中,可以看出。在CSS中给显式的设置了path
元素的样式,修改path
元素的属性的属性值。比如path
元素中的d
属性的值,<circle>
元素中的cx
、cy
和r
的值:
svg:hover circle {
cx: 40;
cy: 40;
r: 40;
}
看上去是不是很有意思。
总结
这篇文章简单的介绍了CSS中属性中怎么使用基本图形函数和路径图形函数:
clip-path
和shape-outside
属性值中可以使用polygon()
、circle()
、ellipse()
和inset()
函数绘制的图形,但不能使用path()
函数,不过可能通过url()
给其传<svg>
中<path>
元素绘制的图形offset-path
和clip-path
以及shape-outside
相反,只能使用path()
函数绘制的图形,但不能使用CSS中绘制图形的图形函数- 在CSS中可以显式的重置
svg
元素中图形元素的属性值,从而改变SVG绘制的图形
扩展阅读
文章中部分图片和效果来自于@CHRIS COYIER的博文《Basic Shapes & Path… Never the Twain Shall Meet?》。
另外文章中涉及到的一些相关属性知识,可以阅读下列相关文章:
如需转载,烦请注明出处:https://www.fedev.cn/css/basic-shapes-path.htmlAir Jordan XI 11 Wool