Sitemap

CSS corner-shape, the best partner of border

11 min readAug 20, 2025
Press enter or click to view image in full size
CSS corner-shape, the best partnerof border

Introduction

透過 CSS border 渲染,Web developers 總能將 element 點綴得更加雀躍活潑,從 border-radius 盤據 CSS 常用屬性的前幾名便可窺知一二。導圓角的使用總能讓基本的 element shape 多采多姿,不再只是一成不變的方正。除此之外,由於該渲染是屬於即時運算類型,所以不管是 element size 或者是 view scale 的變化,它…總能完美的呈現,銳利中不失柔和,更不會出現擾人的鋸齒補強現象。

CSS > corner-shape

Chrome VER.139 的更新支援了 CSS > corner-shape 這個屬性,更大大的擴展了 border 的使用時機,讓它能有更多元的呈現。它目前支援「round」、「squircle」、「scoop」、「bevel」、「notch」以及「square」等屬性。Web developers 可以依照不同情境進行設置。

以下為基本的設置方式,可以透過 border-radius 改變其「水平」以及「垂直」軸距,再搭配 corner-shape 改變兩點之間的邊線呈現即可。

<style>
.container {
inline-size: 100px;
aspect-ratio: 4/3;

border-radius: 16px;
corner-shape: round;
}
</style>

<div class="container"></div>

Understanding CSS corner-shape and the Power of the Superellipse 這篇文章有非常詳盡的介紹,是篇不容錯過的好文。

Example

既然知曉了這些新穎的變化,筆者自然想要透過實例中進行練習以及記憶刻印,恰巧最近浸淫在 PlayStation 的世界中。所以便以 PlayStation 著名的 controller button shape 進行繪製。亦會透過範例跟大家介紹實作方式~

Press enter or click to view image in full size
PlayStation controller button shape

圓形以及正方形單獨使用 border-radius 便可以完成,所以以下僅針對 △ 以及 ✖ 的 CSS 進行介紹。

△ style

<style>
.canvas {
--size: 80px;
--border-size-default: 8px;
--border-size: var(--border-size-default);
--border-color: rgba(236 135 195);
--border-radius: 0;
--corner-shape: initial;

inline-size: var(--size);
aspect-ratio: 1/1;
background-color: rgba(255 255 255/.05);
box-sizing: border-box;

border: var(--border-size) solid var(--border-color);
border-radius: var(--border-radius);
corner-shape: var(--corner-shape);

&.canvas--triangle {
--border-color: rgba(2 224 141);
--corner-shape: bevel;
--border-radius: calc(var(--size) / 2) / var(--size);

border-end-start-radius: 0;
border-end-end-radius: 0;
}
}
</style>

<div class="canvas canvas--triangle"></div>

筆者習慣將未來有機會異動的部分抽離成 custom properties,以便未來 maintain。所以可以看到範例把 border 相關屬性進行抽離。

樣式導讀:

  • 由於我們要繪製的是三角型,所以筆者先設定 corner-shape 為 bevel,因為想要端點直線連結的樣式。
  • 調整 border-radius 的水平以及垂直軸距,水平的部分僅需要容器 50% 寬度,垂直則需要 100% 容器高度。透過 shorthand 寫法,讓四個角都能套用該軸距。
  • 因為只需要左上以及右上的 border,所以直接取消左下以及右下的 border-radius。

以上,便可輕鬆繪出 △ 了~

✖ style

<style>
.canvas {
--size: 80px;
--border-size-default: 8px;
--border-size: var(--border-size-default);
--border-color: rgba(236 135 195);
--border-radius: 0;
--corner-shape: initial;

inline-size: var(--size);
aspect-ratio: 1/1;
background-color: rgba(255 255 255/.05);
box-sizing: border-box;

border: var(--border-size) solid var(--border-color);
border-radius: var(--border-radius);
corner-shape: var(--corner-shape);

&.canvas--cross {
--border-color: rgba(96 140 205);
--border-size: calc(var(--border-size-default) / 2);
--border-radius: calc((var(--size) - (var(--border-size) * 2)) / 2);
--corner-shape: notch;

rotate: 45deg;
}
}
</style>

<div class="canvas canvas--cross"></div>

和 △ 相比會略微複雜一點點。

樣式導讀:

  • 筆者先設定 corner-shape 為 notch,因為想要內凹矩形的呈現效果。
  • 由於是兩個 border 做結合,所以如果要維持我們需要的 border-size 就需要減半處理。
  • 水平以及垂直軸距均為容器尺寸減掉邊長寬度後再對分。
  • 完成上面設置後,我們便可以得到一個 + 的呈現。距離 ✖ 只差一步之遙,這時候對整體旋轉 45 度角後,便可以完成了。

以上便是 △ 以及 ✖ 的 CSS 樣式設置。呼應本文開頭所述,由於是即時運算,所以不管是 element size 或者是 view scale 的變化,它…總能完美的呈現不會出現鋸齒補強現象喔!

以下為完整 sample code,有興趣的朋友也可以點擊這裡一覽實際渲染效果。

<style>
.container {
--gap: 1em;
--size: 80px;

--border-size-default: 8px;
--border-size: var(--border-size-default);
--border-color: rgba(236 135 195);
--border-radius: 0;
--corner-shape: initial;

inline-size: fit-content;
display: flex;
gap: var(--gap);
flex-wrap: nowrap;

.startdust {
position: absolute;

inset-inline-start: attr(data-x type(<length>), 0px);
inset-block-start: attr(data-y type(<length>), 0px);

inline-size: attr(data-size type(<length>), 24px);
aspect-ratio: 1/1;
box-sizing: border-box;
box-shadow: 0 0 1px rgba(0 0 0 / 0.1), 0 2px 4px rgba(0 0 0 / 0.08);

corner-shape: scoop;
border: 8px solid rgba(255 255 255);
border-radius: var(--size);
background-color: rgba(255 255 255);
}

.canvas {
flex-shrink: 0;

inline-size: var(--size);
aspect-ratio: 1/1;
background-color: rgba(255 255 255/.05);
box-sizing: border-box;
border: var(--border-size) solid var(--border-color);
border-radius: var(--border-radius);
corner-shape: var(--corner-shape);

&[data-type=square] {
--border-color: rgba(236 135 195);
--border-radius: 0;
}

&[data-type=triangle] {
--border-color: rgba(2 224 141);
--corner-shape: bevel;
--border-radius: calc(var(--size) / 2) / var(--size); /* horizontal / vertical */

border-end-start-radius: 0;
border-end-end-radius: 0;
}

&[data-type=circle] {
--border-color: rgba(255 0 29);
--border-radius: var(--size);
}

&[data-type=cross] {
--border-color: rgba(96 140 205);
--border-size: calc(var(--border-size-default) / 2);
--border-radius: calc((var(--size) - (var(--border-size) * 2)) / 2);
--corner-shape: notch;

rotate: 45deg;
}
}
}
</style>

<div class="container">
<div class="canvas" data-type="triangle"></div>
<div class="canvas" data-type="circle"></div>
<div class="canvas" data-type="cross"></div>
<div class="canvas" data-type="square"></div>

<div class="startdust" data-size="16px" data-x="-36px" data-y="-38px"></div>
<div class="startdust" data-size="24px" data-x="-18px" data-y="-30px"></div>
<div class="startdust" data-size="6px" data-x="-30px" data-y="-14px"></div>
</div>

Feature detect

Web developers 可以透過 CSS 或是 JavaScript 偵測當前環境是否支援 CSS > corner-shape。實作方法如下所示:

CSS:

<style>
@supports (corner-shape: notch) {
/* corner-shape ready */
...
}
</style>

JavaScript:

<script type="module">
const supported = CSS.supports('corner-shape', 'notch');

if (supported) {
/* corner-shape ready */
...
}
</script>

Conclusion

有了新玩具的加持,相信大家對於 border render 有了更多想像空間,閒暇之餘不妨動手試試看,定會有不同意會。

以上便是筆者透過實作所做的一些分享,感謝您的閱讀亦希望以上內容對於你以及未來得我均能有所助益。 #CSS

Reference

--

--

Paul Li
Paul Li

Written by Paul Li

Paul is the lead programmer of the AMP project at Yahoo Taiwan and is always eager for modern web technologies. He is also focusing on UX for vivid user flow.

No responses yet