Dipublikasikan: 19 Februari 2026
Salah satu fitur CSS yang diluncurkan Chrome pada tahun 2025 adalah
corner-shape.
Hal ini memungkinkan Anda menentukan bentuk sudut yang memiliki border-radius menggunakan
kata kunci seperti bevel dan scoop. Anda juga dapat menggunakan fungsi superellipse
yang menerima nilai antara -Infinity dan Infinity.
Lihat artikel lengkap Amit Sheen di Frontend Masters untuk mengetahui ringkasan yang bagus tentang fitur ini dan cara kerjanya.
Saat menerapkan fitur ini pada awal tahun 2025, saya menghadapi beberapa tantangan menarik dengan kompleksitas yang bervariasi. Saya belajar banyak hal tentang superelips, lukisan batas di Blink, dan penggunaan matematika vektor untuk grafis 2D.
Dokumen ini membagikan beberapa hal yang saya pelajari, yang mungkin juga menarik bagi orang lain.
Simetri bentuk cembung dan cekung
Meskipun nilai superellipse (k) biasanya berada di antara 0 dan Infinity, dengan
nilai antara 0 dan 1 bersifat cekung dan sisanya bersifat cembung (1 adalah bevel),
nilai superellipse dalam spesifikasi CSS berada di antara -Infinity dan Infinity, dan
merepresentasikan 2k. Tindakan ini akan menciptakan simetri karena setiap nilai positif akan terlihat seperti
gambar cermin dari nilai negatifnya.
Namun, secara default, formula superellipse tidak berfungsi seperti itu.
Rumus superellipse adalah: xk + yk = 1. Formula inversi, x1/k + y1/k = 1, tidak menghasilkan kurva yang simetris secara visual.
Misalnya, dengan k 2:
- Kurva biru merepresentasikan putaran
superellipse(y=xn). - Kurva merah merepresentasikan
scoopsuperellipsedengan formula kanonis (y=x1/n). - Kurva kuning merepresentasikan kurva yang simetris secara visual dengan kurva biru (
y=1-(1-x)n).
Seperti yang ditunjukkan pada diagram, bentuknya tidak sama.
Saya tidak akan membahas lebih dalam matematika di baliknya, tetapi hal ini berkaitan dengan norma ganda dan cara kita mempersepsikan kelengkungan.
Dari segi spesifikasi dan penerapan, kita merepresentasikan sesuatu yang
visual di sini, jadi kita menggunakan padanan simetris saat menghitung bentuk
cekung. Perhitungan matematika lainnya dilakukan pada bentuk cembung (k>=1, atau nilai superelips positif).
Formula bentuk tertutup
Tantangan berikutnya adalah merepresentasikan kurva, atau perimeter
superellipse, dalam bentuk tertutup, sebuah formula yang terdiri dari operasi aritmatika sederhana.
Hal ini penting untuk performa, yang memungkinkan sistem menyerahkan superellipse rendering ke mesin grafis.
Mesin grafis seperti Skia sudah memahami kurva Bezier, sehingga merepresentasikan superellipse dengan sejumlah kecil kurva Bezier yang mendekati perimeternya akan membuat rendering kurva superellipse lebih berperforma.
Untungnya, dengan menggunakan regresi simbolik, kita dapat menemukan formula yang merepresentasikan setengah sudut cembung sebagai kurva Bezier kubik tunggal.
Kurva Bezier kubik memiliki empat titik:
- Titik pertama adalah (
0, 1). - Titik terakhir adalah setengah sudut superelips yang sebenarnya:
0.51/k,0.51/k. - Titik kontrol pertama meregang pada tingkat yang sama dengan titik
awal: (
a, 1). - Titik kontrol kedua adalah diagonal setengah sudut:
(0.51/k - b,0.51/k + b).
Nilai setengah sudut yang digunakan di sini ternyata merupakan koordinat yang sangat penting yang akan kita gunakan untuk komputasi lainnya di masa mendatang.
Dengan a dan b dihitung dari k menggunakan regresi simbolik.
Menghitung keempat titik ini dan merender kurva Bezier kubik di antaranya akan memberikan setengah sudut cembung bentuk tertutup dengan k tertentu. Kemudian, kita dapat memutar hasil untuk mengisi sudut lainnya, menerapkannya ke sudut lain, dan membaliknya untuk
merender hasil yang cekung.
Tanpa membahas lebih lanjut matematika, formula untuk menghitung a
dan b adalah sebagai berikut:
p0 = 1.2430920942724248
p1 = 2.010479023614843
p2 = 0.32922901179443753
p3 = 0.2823023142212073
p4 = 1.3473704261055421
p5 = 2.9149468637949814
p6 = 0.9106507102917086
s = log2(k)
slope = p0 + (p6 - p0) * 0.5 * (1 + tanh(p5 * (s - p1)))
base = 1 / (1 + exp(slope * p1))
logistic = 1 / (1 + exp(slope * (p1 - s)))
a = (logistic - base) / (1 - base)
b = p2 * exp(-p[3] * (s ^ p4))
Batas dan bayangan
Selain menghitung jalur perimeter sudut, sistem juga menghitung tampilannya saat diimbangi ke dalam (batas atau inset box-shadow) atau ke luar (outline atau box-shadow normal). Di library grafis konvensional, hal ini dilakukan dengan stroking.
Namun, batas dan bayangan dalam CSS memiliki karakteristik rendering yang berbeda dari goresan:
- Batas tidak seragam.
- Misalnya, batas atas dapat berupa 10 piksel dan batas kanan 5 piksel, dengan sudut yang diinterpolasi di antaranya.
- Selain itu, mereka bergerak ke dalam, bukan ke kedua sisi.
- Bayangan dan garis luar tidak dirender persis seperti goresan.
- Sebaliknya, sudut akan disesuaikan agar terlihat tajam.
Meskipun jalur rendering bayangan dan batas yang biasa berfungsi dengan baik untuk nilai corner-shape yang bulat atau lebih cembung dari itu (misalnya,
squircle), dan dapat diputar 90 derajat untuk bentuk yang lebih cekung dari
scoop, default ini tidak berfungsi untuk nilai corner-shape antara -1 dan 1,
karena mengimbangi batas atau bayangan yang sejajar dengan tepi akan menghasilkan sudut yang
tampaknya memiliki lebar yang tidak merata.
Misalnya, mengambil sudut bevel dan mengimbangi batas dengan beberapa piksel ke kedua sisi akan menciptakan efek "perut", di mana bagian tengah sudut terlihat lebih lebar daripada sisi-sisinya.
Untuk memperhitungkannya, tujuannya adalah membuat efek yang berfungsi seperti goresan—temukan
normal kurva sudut di awal, dan buat sepanjang lebar
border atau shadow-spread.
Untungnya, hal ini hanya diperlukan untuk sub-elips (antara bevel dan bulat), karena hiper-elips seperti squircle berfungsi seperti yang diharapkan.
Untuk menemukan normal kurva sub-elips, cukup menemukan normal kurva kuadratiknya, karena sub-elips dan kurva kuadratiknya hampir sama.
Dengan menggunakan setengah sudut yang sama yang dihitung sebelumnya, Anda dapat menemukan kurva kuadrat yang memiliki titik tengah yang sama, mendapatkan titik kontrol kuadratnya, dan dari sana menghitung normalnya menjadi mudah.
Normal berlanjut dengan panjang yang sama seperti border-width atau shadow-spread, lalu memangkas kurva yang dihasilkan dengan tepi (tepi dalam untuk batas, tepi luar untuk bayangan) untuk membuat jalur berkelanjutan.
Ada cara yang lebih akurat secara matematis untuk menghitung garis singgung superellipse, tetapi metode ini efisien dan menghasilkan hasil yang memadai untuk merender batas dan bayangan.
Sambungan warna
Bagian menarik dari proses menggambar yang terjadi di browser ternyata tidak ditentukan dalam CSS. Merender batas yang memiliki warna atau gaya yang tidak seragam. Misalnya, elemen Anda memiliki batas atas solid berwarna hijau dan batas kanan putus-putus berwarna kuning. Dalam kasus ini, miter adalah garis sayatan yang berada di antara sudut tepi batas yang relevan dan sudut tepi padding yang relevan. Hal ini menciptakan batas antara tepi yang berdekatan.Meskipun tidak ditentukan, rendering agak konsisten di antara browser.
Cara ini diimplementasikan di Blink (dan di browser lain) adalah sebagai berikut. Tepi yang akan digambar dipangkas secara kasar seperti poligon yang melintasi di sudut miring, dihitung sedemikian rupa sehingga akan menyertakan tepi yang relevan, tetapi tidak menyertakan tepi lainnya. Hal ini menghindari kebocoran, yang melukis salah satu tepi lainnya dengan gaya dan warna yang salah.
Poligon ini sejauh ini relatif mudah dihitung, karena dengan sudut bulat
reguler, area sudut tidak akan pernah tumpang-tindih. Namun, hal ini berubah dengan
hipo-elips dan khususnya dengan superelips cekung (nilai
superellipse negatif). Hal ini dapat menciptakan bentuk yang cukup menarik yang membuat poligon persimpangan sederhana sangat rentan terhadap tumpang-tindih dan "kebocoran".
Pertimbangkan CSS berikut:
.weird {
width: 200px;
height: 200px;
corner-shape: scoop round;
border-radius: 80% 20% / 50% 50%;
border-width: 10px;
border-color: orange purple black blue;
border-style: solid dotted;
}
Kita ingin memangkas setiap tepi (oranye, putus-putus ungu, hitam, putus-putus biru) secara terpisah, lalu menggambar jalur.
Untuk mencapainya tanpa tumpang-tindih dengan tiga sudut lainnya, diperlukan pemangkasan yang cermat.
Misalnya, perhatikan tepi oranye (atas).
Sulit untuk menemukan poligon yang tepat yang mencakup seluruh tepi tersebut dan tidak melebihi tepi ungu, kuning, atau bahkan hitam. Bentuk lain lebih sulit.
Proses ini melibatkan tiga klip.
Klip pertama mencakup seluruh tepi, dengan sudut penuh (tanpa sambungan miring). Contoh:
Ini terdiri dari dua sudut (satu scoop, satu bulat), dengan tepi minimal di antaranya, yang terhubung di ujungnya.
Memulai dari bentuk ini akan menghilangkan tumpang-tindih dengan tepi yang berlawanan, dan kini hanya dua sudut miring yang menjadi masalah.
Hal ini dicapai dengan memotong dari sudut ini, poligon yang melewati antara sudut tepi batas dan sudut tepi padding, dan berhenti pada saat akan berpotongan dengan tepi:
Sistem menemukan titik tempat garis dari tepi batas ke tepi padding berpotongan dengan garis singgung kurva dari titik awal yang relevan (jika kurva cekung).
Jika titik tersebut berada di dalam area yang dirender, proses akan berhenti di sana dan berlanjut di sepanjang garis singgung tersebut hingga bertemu dengan kotak batas lagi, sehingga melengkapi quad.
Jika tidak, segitiga sederhana dapat diklip.
Ringkasan
Platform web memberikan kemampuan ekspresif yang signifikan bagi desainer dan developer web. Terkadang, properti CSS yang mengambil satu nilai numerik menyembunyikan kompleksitas signifikan di baliknya untuk merendernya secara akurat dan konsisten.
Fitur corner-shape memiliki kompleksitas yang mengejutkan. Dokumentasi ini bertujuan untuk membantu developer di masa mendatang yang mengerjakan fitur ini, di Blink, browser lain, atau spesifikasi.