还在用老掉牙的圆角?来试试这个让UI起飞的corner-shape,能整出各种花活儿

2,640字
11–17 分钟
in

回想当年刚入行那会儿,想做个圆角盒子,得在Photoshop里抠图切图,搞五张背景图片拼起来,那叫一个费劲。所以当border-radius这玩意儿横空出世的时候,整个前端圈都炸了,感觉就像给网页设计来了场革命。那会儿的网页都是方方正正的,突然能整出圆角,简直不要太酷。现在十几年过去了,大家对圆角早就习以为常,甚至开始觉得满屏的大圆角有点“腻”了。这时候,一个叫corner-shape的新属性悄悄在Chrome 139及以上版本里亮了相,配合着老朋友border-radius,能搞出斜角、扇形、甚至那种像苹果图标一样的“超椭圆”效果。

目录

这玩意儿到底是个啥

corner-shape翻译过来就是“角落形状”,它不再满足于只把角变圆,而是可以定义角落到底长啥样。目前它可以有几种值:round就是咱们熟悉的圆角,bevel是切角(像被刀削了一下),scoop是内凹的扇形,squircle是介于方和圆之间的超椭圆,还有notch是那种缺了一块的凹槽。但最关键的一点是,corner-shape必须和border-radius一起用,前者管形状,后者管尺寸,两口子配合干活。

上手撸个“斜切角”

现在很多网站喜欢用那种被切了一刀的角,看着特别有现代感,比如一些粗野主义风格的卡片。要做出这种效果,代码简单得让人想哭。

.card {
  corner-shape: bevel;
  border-bottom-right-radius: 16px;
}

这两行代码下去,卡片的右下角就被切掉了,切掉的深度是16px。这里有个小细节需要注意,切角的实现原理是,从角点出发,在水平方向和垂直方向上各取一个点,然后把这两个点连成一条直线。 如果只给一个值,比如border-bottom-right-radius: 16px,那就相当于水平方向和垂直方向都是16px,切出来的线就是45度角。如果想切出更夸张的斜角,比如那种从很远的水平位置切下来,只切一点点垂直距离,可以给两个值:

.slanted {
  corner-shape: bevel;
  border-bottom-right-radius: 100% 50px;
}

这样,水平方向几乎切到底(100%),垂直方向只切50px,连起来的线就形成了一个很长的斜边,看着就像版面被故意切歪了一样,很有动感。

搞个电商大促“价格牌”

逛淘宝京东,经常能看到商品图上挂着那种三角形的“爆款”、“限时抢购”标签。以前要实现这种效果,要么切图,要么用复杂的伪元素拼凑。现在用corner-shape,可以把形状“捏”出来。

.sale-tag {
  /* 形状顺序:左上、右上、右下、左下,顺时针方向 */
  corner-shape: round bevel bevel round;
  /* 水平半径 / 垂直半径 */
  border-radius: 16px 48px 48px 16px / 16px 50% 50% 16px;
}

这代码看着有点晕,咱们把它拆解一下。corner-shape定义了左上和右下是圆的,右上和左下是被切掉一块的。border-radius那一串,斜杠左边是每个角的水平半径,右边是垂直半径。所以右上角(第二个值)是48px 50%,意味着从角的水平方向48px处开始切,垂直方向从50%的地方开始切,两者连起来就形成了一个尖尖的箭头形状。在实际操作中,如果想让标签尖角更尖,可以调整50%这个比例,或者调整48px这个长度,数值越大,箭头越宽。 但要注意,如果给标签加边框或外轮廓,浏览器渲染角的时候会变得很奇怪,尖角处会糊掉,所以建议直接用背景色。

做个带小尾巴的“提示框”

那种对话气泡一样的提示框,右下角有个小箭头指向被解释的元素。这个小箭头可以用corner-shape: scoop来搞,做出一种圆润内凹的感觉,比三角形的箭头更Q弹。

假设有一个按钮,和一个通过popover属性关联的提示框,并且用了锚点定位把提示框定在按钮旁边。那么提示框的小尾巴可以这么写:

.tooltip::after {
  content: "";
  width: 5px;
  height: 10px;
  corner-shape: scoop;
  border-top-left-radius: 100% 50%;
  border-bottom-left-radius: 100% 50%;
}

这里用伪元素生成了一个宽5px高10px的小矩形,通过corner-shape: scoop把它的角变成内凹的扇形,然后通过锚点定位把这个小矩形贴在提示框的左边。这个过程中,锚点定位的属性anchor-nameposition-anchor的配合是关键,要确保伪元素相对于提示框来定位,而不是相对于页面。 另外,popover属性自带的定位方式可能会和手动设置的定位冲突,记得把position: fixed之类的样式写清楚。

画个“手绘”高亮

在网页里用<mark>标签给文字加黄色背景高亮,默认效果就是一块直愣愣的长方形。如果想让高亮看起来像用荧光笔在纸上随手画的那种,边缘有点毛毛的、不规则的感觉,可以用corner-shapeborder-radius组合拳。

mark {
  /* 混搭形状 */
  corner-shape: squircle bevel;
  /* 给每个角设置不一样的圆角值 */
  border-radius: 50% / 1.1rem 0.5rem 0.9rem 0.7rem;
  /* 防止背景在换行时断开 */
  box-decoration-break: clone;
}

这里corner-shape: squircle bevel只给了两个值,意思是左上角用超椭圆,右上角用切角,剩下的右下和左下根据继承逻辑自动生成,结果就得到了一个不对称的形状。然后border-radius那一长串,分别给每个角的水平和垂直半径设置了不同值,最终效果就是每个角的弯曲程度都不一样,看起来就像随手画的。box-decoration-break: clone很重要,因为高亮文字跨行时,如果不加这个,背景会在行与行之间断开,加了之后每一行的高亮都会独立应用这个形状,看起来更自然。

结尾

corner-shape这玩意儿真的是个宝藏,从工业风的斜切角,到电商的促销标签,再到软萌的气泡提示框,甚至还能模拟手绘质感,玩法多得是。只要脑洞够大,配合上border-radius那个有点复杂的语法,就能把之前需要图片或者复杂伪元素才能实现的形状,用几行CSS搞定。当然,目前还得在Chrome 139以上才能跑起来,但尝鲜嘛,图的就是个乐子。