折腾网页设计的时候,总碰到那种圆鼓鼓、不规则的黏糊形状,江湖人称“blob”。这玩意儿看着随意,真上手用CSS硬磕,分分钟让人头大。有人爱它那种软乎乎的手感,也有人恨它怎么调都差点意思。到底怎么整才能又快又稳地产出一个正经blob?下面直接开整几种实打实的操作流程,从最简单到最硬核,挨个走一遍。
一篇实操向指南,专门唠唠用CSS捣鼓blob形状的那些事儿。先扯清楚blob是个啥——就是那种不规则的、像水滴或黏菌一样的圆润图形。接着上四种真能用的解法:在线工具撸SVG直接扔进去、拿border-radius魔改四角、用滤镜把几个圆“黏”成一坨、还有最新出的shape()函数配合clip-path。每种法子都掰开揉碎讲步骤,顺带点明路上容易踩的坑,比如border-radius只能搞凸形,滤镜玩法颜色容易翻车,shape()不支持边框阴影。看完照着敲,保准能出活儿。
在线生成SVG
这是最省事的野路子,不用手写一行复杂代码。打开那些专门搞blob的在线小工具,鼠标拖一拖,一个独一无二的黏糊形状就出来了。操作流程分三步:
- 找个顺手的blob生成器(比如Haikei或者Blobmaker这类),页面上通常有个画板或者一堆滑块。
- 调整形状的胖瘦、凹凸程度、旋转角度,直到看着顺眼。工具一般实时预览,指哪打哪。
- 点导出按钮,复制生成的SVG代码。那段代码里最关键的是
<path>标签的d属性,里面一串数字就是形状的骨骼。
拿到SVG之后,直接嵌进HTML。举个例子:
<div class="blob-svg">
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<path fill="#FA4D56" d="M65.4,-37.9C79.2,-13.9,81,17,68.1,38C55.2,59.1,27.6,70.5,1.5,69.6C-24.6,68.8,-49.3,55.7,-56,38.2C-62.6,20.7,-51.3,-1.2,-39,-24.4C-26.7,-47.6,-13.3,-72,6.2,-75.6C25.8,-79.2,51.6,-62,65.4,-37.9Z" transform="translate(100 100)"/>
</svg>
</div>这种方式的坑在于,SVG本身是个独立元素,想用CSS滤镜、渐变背景或者阴影的时候,有时候会跟外部样式打架。比如给.blob-svg加个box-shadow,阴影会老老实实沿着SVG的外框走,不会沿着那个不规则的blob边缘。解决办法是把阴影直接写进SVG里面,用<filter>标签搞,但那就又复杂了。另外,如果页面上要放好多个不同颜色的blob,每个都得重新生成一次SVG,代码量蹭蹭涨。
border-radius魔改
这招说出来可能不信,用圆角属性居然能拼出一个不规则的blob。原理是把四个角的水平半径和垂直半径拆开设置,每个角变成一个椭圆,四个椭圆拼在一起就产生了那种软乎乎的边缘。具体操作:
- 新建一个
<div>,宽高设一样,比如width: 300px; height: 300px;。 - 写
border-radius,用斜杠/分隔水平值和垂直值。比如:
.blob-radius {
width: 300px;
height: 300px;
background: #3b82f6;
border-radius: 70% 30% 60% 40% / 50% 60% 40% 50%;
}- 数值可以随便调,越离谱越像blob。每个百分数分别对应左上、右上、右下、左下四个角。斜杠前面四个数是水平半径,后面四个是垂直半径。
实际操作中会发现,这方法只能做出凸形的blob,永远不会有凹进去的坑坑洼洼。因为border-radius本质上是用圆弧切掉角,再复杂也切不出内陷的效果。而且调数值全靠蒙,没点空间想象力根本调不出想要的样子。有个叫Nils Binder的老哥专门做了个可视化工具,拖拽滑块就能看到实时效果,调好了把数值抄下来就行。但即便用工具,调出来的形状依然偏“肉”,像被吹鼓的气球,缺少那种不规则黏菌的随意感。
滤镜黏合大法
这招特别像把几滴水滴凑一块,它们会自动融合成一坨。CSS里用filter配合blur()和contrast()就能模拟这种效果。核心思路是先让几个圆变模糊,互相渗透,然后把对比度拉爆,模糊的边缘被强行提亮,就变成了一个连体的blob。但直接怼CSS滤镜容易翻车,换个颜色就糊成一团。更稳的玩法是用SVG滤镜,只对透明度通道加对比度,颜色通道原样保留。
操作流程(单元素版本):
- 准备一个空的
<div class="blob-filter">。 - 在HTML里埋一段SVG滤镜代码,最好放在
<body>开头或末尾,用position: absolute藏起来:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="position: absolute; width: 0; height: 0;">
<defs>
<filter id="goo">
<feGaussianBlur in="SourceGraphic" stdDeviation="12" result="blur" />
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -6" result="goo" />
<feBlend in="SourceGraphic" in2="goo" />
</filter>
</defs>
</svg>- 用
background的径向渐变画多个圆,全部叠在一个元素上:
.blob-filter {
filter: url(#goo);
width: 400px;
height: 300px;
background:
radial-gradient(farthest-side, #f97316 100%, #0000) 20% 30% / 35% 45%,
radial-gradient(farthest-side, #f97316 100%, #0000) 75% 40% / 40% 50%,
radial-gradient(farthest-side, #f97316 100%, #0000) 50% 70% / 45% 35%;
background-repeat: no-repeat;
}这里每个radial-gradient就是一个圆。farthest-side保证圆不会被裁成椭圆,颜色写死成目标色(比如橙色),末尾的#0000是全透明黑色,用来让圆之外的部分透明。后面的20% 30%是圆心的位置,/ 35% 45%是圆的宽和高。三个圆位置错开,经过SVG滤镜一黏,就成了一个不规则的blob。
这种玩法有个巨大的好处——背景可以随便换,因为父元素.blob-filter本身是透明的,真正显色的是那些径向渐变。想换颜色?改渐变里的色值就行。想加渐变背景?把.blob-filter的父级背景设成渐变色就完事。缺点也很明显:没法用border和box-shadow,因为滤镜会把这些也一起糊掉。另外调三个圆的位置和大小是个细致活,想调出一个特别好看的blob得反复试。一个偷懒技巧是先把三个圆用纯色画出来,不开滤镜看它们的位置关系,调满意了再套滤镜。
shape函数新招
最近CSS里冒出来个shape()函数,配合clip-path用,能把元素切成任意形状。这玩意儿的语法抄的是SVG的path,但写起来更像个英文句子。直接用脑子想贝塞尔曲线控制点太反人类,正确的姿势是:先用在线工具生成SVG的blob,然后把SVG里的d属性扔进转换器,一键变成shape()语法。
操作流程:
- 随便用哪个在线blob生成器(比如Blobmaker),拖出一个满意的形状,复制
<path>标签里的d属性值。 - 打开Temani Afif做的“SVG to shape()”转换工具(网上搜一下就有),把
d属性粘贴进去。 - 工具会吐出一段CSS,类似这样:
.blob-shape {
aspect-ratio: 0.925;
clip-path: shape(
from 91.52% 26.2%,
curve to 93.52% 78.28% with 101.76% 42.67%/103.09% 63.87%,
curve to 44.11% 99.97% with 83.95% 92.76%/63.47% 100.58%,
curve to 1.45% 78.42% with 24.74% 99.42%/6.42% 90.43%,
curve to 14.06% 35.46% with -3.45% 66.41%/4.93% 51.38%,
curve to 47.59% 0.33% with 23.18% 19.54%/33.13% 2.8%,
curve to 91.52% 26.2% with 62.14% -2.14%/81.28% 9.66%
);
}- 把这段CSS贴到目标元素上,给元素设个背景色或背景图。
用这招,任何SVG blob都能精确复刻成CSS形状。而且支持渐变背景,想搞个彩虹色blob都没问题。但有两个硬伤:一是clip-path切出来的形状,边框和阴影也会被切掉。比如给.blob-shape加border: 5px solid red,边框会沿着原始矩形走,不会贴着blob边缘。box-shadow同理,阴影是矩形的。二是shape()目前还在较新版本浏览器里才能用,老一点的浏览器直接不认。如果不介意边框阴影被切,或者压根不需要边框阴影,这方法就是目前最理想的——单元素、可设计、可渐变。
| 方法 | 单元素 | 在线设计 | 渐变背景 | 边框阴影 |
|---|---|---|---|---|
| 在线SVG | 否 | 是 | 受限 | 受限 |
| border-radius | 是 | 工具辅助 | 是 | 是 |
| 滤镜黏合 | 是 | 否 | 是 | 否 |
| shape函数 | 是 | 是 | 是 | 否 |
每种路子都有翻车点,但也都能在特定场景下发光。比如急着出图又不差那点代码体积,直接SVG糊上去最省事。想要纯CSS且兼容性好到爆,border-radius虽然形状呆但够用了。追求那种液体融合的丝滑感,滤镜大法值得折腾。要是对边框阴影没执念又想形状精确,shape()就是版本答案。选哪个,看具体需求怎么要求。
