你有没有遇到过这种情况:在 CSS 里给同一个卡片调了十几遍 background 和 border-radius,最后出来的页面还是像没做完的半成品?我刚开始做前端开发那会儿就是这样,背景颜色一顿叠,圆角在 10px 和 50% 之间反复横跳,结果页面虽然能用,但怎么看怎么塑料。后来我才想明白,背景和圆角这两个属性不是拿来“填色”的,而是用来控制视觉层次的。背景能叠加多层渐变和图案,圆角能组合出扇形、水滴、花瓣这类跟“圆角矩形”八竿子打不着的形状,二者配合起来,才是页面颜值飙升的真正底牌。
这篇我把 background 和 border-radius 的进阶用法完整梳理了一遍,从渐变背景到多重背景,从椭圆圆角到切角卡片,再到实战案例和性能坑,适合已经写过基础 CSS、但想把页面做出质感的开发者。不用你有多深的功底,跟着思路走,每一步都能落地。
1. 背景属性的底层逻辑:子属性这么多,先弄懂它们在干什么
很多前端写了几年 background: #fff url(...) no-repeat center,本质上还是“会背不会讲”。背景属性其实是一组子属性的集合,搞懂每个子属性负责什么,后面玩渐变和多重背景时就不会懵。
1.1 background 子属性全景与简写顺序
先列个全景表,把 background 家族的子属性一次看清:
| 子属性 | 作用 | 默认值 |
|---|---|---|
background-color |
背景色,只能有一层 | transparent |
background-image |
背景图或渐变,可叠多层 | none |
background-position |
背景图的起点位置 | 0% 0% |
background-size |
背景图的尺寸 | auto |
background-repeat |
是否平铺 | repeat |
background-origin |
定位参考框:border-box / padding-box / content-box |
padding-box |
background-clip |
绘制范围:border-box / padding-box / content-box / text |
border-box |
background-attachment |
背景是否随滚动 | scroll |
简写的时候,顺序要求并不像 margin 那样严格,但有一个必须记住的规则:position 和 size 要用斜杠 / 分隔,且 size 必须跟在 position 后面。比如 background: url(banner.jpg) center / cover no-repeat,写成 no-repeat center cover 就完全不对。
这里特别容易翻车的是 background-origin 和 background-clip 的简写关系。它俩在简写里如果同时出现两个值,第一个是 origin,第二个是 clip;如果只出现一个值,则两者都被设置成这个值。官方语义里 origin 默认是 padding-box,clip 默认是 border-box,这个错位曾经坑过不少同事。
1.2 background-position 的百分比计算,别再凭感觉写
background-position 用像素、left/right/top/bottom 这些关键字大家都会,但一到百分比就容易懵:为什么 50% 50% 能居中,而 50px 50px 看起来并没有居中?
关键区别在于:百分比是拿“容器尺寸减去背景图尺寸后的剩余空间”乘以百分比来算偏移的。公式是这样的:
code复制偏移量 =(容器尺寸 - 背景图尺寸)× 百分比
举个例子,容器宽 400px,背景图宽 200px:
background-position: 50%→(400 - 200) × 0.5 = 100px,图片从左边偏移 100px,刚好居中。background-position: 100px→ 图片左边缘离容器左边缘固定 100px,但因为图宽 200px,右边缘到容器右边缘也是 100px,看起来也居中。- 但容器改成 410px 再看:
50%会偏移105px,而100px还是死板的100px,差异就冒出来了。
所以如果你想做“背景图随容器宽度变化而保持某种相对位置”的效果,用百分比;想要绝对偏移,再用像素。这个规律同样适用于 background-origin 改变参考框后的计算,搞清楚一次,省得以后每个项目都现场试。
1.3 多重背景的叠加顺序:前面的在顶层
background 支持用逗号分隔多个背景层,比如:
css复制background:
linear-gradient(135deg, rgba(106,92,255,0.8), rgba(162,75,207,0.6)),
url('texture.png'),
#f5f4ff;
规则是:**越靠前的层,层级越高,显示在
