Öste Hörn 2018

0
44

När jag såg Chris’ artikel om skårad lådor, jag kom ihåg att jag fick en utmaning för ett tag sedan till en CSS design som den nedan i en cross-browser sätt:

Vad utmaningen såg ut.

Det ser ganska lik konceptet spårat lådor, utom i hörnen är nu öste och vi bara oroa dig för att ett hörn per box. Så låt oss se hur vi kan göra det, hur vi kan utvidga tekniken till flera hörn, vilka problem vi stött på och hur vi kan komma runt dem med eller utan att göra webbläsaren stöd för kompromisser.

Den ursprungliga tanken: box-shadow!

Vi börjar med en låda element:

<div class= ” box ” ></div>

Vi kan ge detta några mått eller låt dess dimensioner beslutas av innehållet—det spelar egentligen ingen roll. För enkelhetens skull har vi bara är att sätta en max-bredd och en min-height på det. Vi är dessutom ger den en översikt så kan vi se dess gränser.

.box {
utkast: solid 2px;
max-width: 15em;
min-height: 10em;
}

Nästa, vi är absolut position en kvadrat : på:innan pseudo-element vars kant längd är lika med diametern (eller två gånger radien $r) av scoop i hörnet. Vi ger också denna pseudo-element en röd box-shadow och en dummy bakgrunden (som vi kommer ta senare) bara så att vi kan se det bättre:

$r: 2em;

.box {
position: relative;
/* samma stil som innan */

&innan {
position: absolute;
stoppning: $r;
box-shadow: 0 0 7px #b53;
bakgrund: #95a;
innehåll:”
}
}

Och detta är vad vi har hittills:

Se Pennan genom att thebabydino (@thebabydino) på CodePen.

Tja, det ser inte så spännande… ännu! Så låt oss gå vidare och göra detta torg en skiva genom att ställa border-radius: 50% på det och ge det en negativ marginal lika med dess radie $r, så att dess centrala punkt sammanfaller med (0,0) punkt (övre vänstra hörnet) av sin förälder box. Vi ställer också overflow: hidden om förälders box, så att oavsett vad som i denna pseudo-element är utanför .lådan blir att klippa ut.

$r: 2em;

.box {
overflow: hidden;
/* samma stil som innan */

&innan {
/* samma stil som innan */
marginal: -$r;
border-radius: 50%
}
}

Nu börjar vi se den form vi har varit siktar på:

Se Pennan genom att thebabydino (@thebabydino) på CodePen.

Men det är fortfarande inte riktigt vad vi vill. För att komma dit använder vi den fjärde längd värde för box-shadow fastighet: sprida radie. Om du behöver en repetition på hur box-shadow arbetar med dessa fyra värden, du kan kolla in den interaktiva demo nedan:

Se Pennan genom att thebabydino (@thebabydino) på CodePen.

Du kanske redan har gissat vad vi ska göra härnäst. Vi tar bort dummy bakgrund, vi noll de första tre box-shadow värderingar (x-och y-förskjutning och oskärpa radie) och använd en ganska stor numret för den sista (spridning radie):

box-shadow: 0 0 0 300px;

Interaktiv demo nedan visar hur en ökad spridning radie gör att det täcker upp mer och mer av sin förälder .box:

Se Pennan genom att thebabydino (@thebabydino) på CodePen.

Så tricket här är att ha en spridning radie tillräckligt stor så att den täcker resten av det överordnade elementet. Det häftiga med detta är att vi kan göra box-shadow semi-transparent eller har rundade hörn på den överordnade .box:

.box {
/* samma stil som innan */
border-radius: 1em;

&innan {
/* samma stil som innan */
box-shadow: 0 0 0 300px rgba(#95a, .75);
}
}

Se Pennan genom att thebabydino (@thebabydino) på CodePen.

Naturligtvis, precis som Chris påpekade i artikeln om skårad lådor, vi kan göra scoop radie en CSS rörliga och kan då enkelt att ändra från JavaScript. Då allt uppdateringar fint, även med textinnehåll i vår låda:

:root { –r: 50px }

.box {
/* samma stil som innan */
stoppning: var(–r).

&innan {
/* samma stil som innan */
marginal: calc(-1*var(–r));
stoppning: inherit;
}

Observera att när vi har även sms: a innehåll, måste vi ställa en negativ z-index på ::före pseudo-element och uttryckligen placera den i hörnet som vi nu också har en stoppning på .rutan för att kompensera för de senaste nyheterna.

.box {
/* samma stil som innan */

&innan {
/* samma stil som innan */
z-index: -1;
top: 0;
till vänster: 0
}

Se Pennan genom att thebabydino (@thebabydino) på CodePen.

Att använda den här tekniken

Låt oss nu gå vidare och se hur vi kan använda detta begrepp för att återge den design jag visade i början. I det här fallet, den centrala punkter i pseudo-element-skivor som inte sammanfaller med box hörn, men utanför, i mitten av utrymmet mellan rutorna.

Den struktur som används är ganska enkelt, bara en <header> – element följt av fyra <artikel> – element jag har genererat i en Mops loop:

medan n–
artikel
h3 #{data[n].name}
avsnitt
p #{data[n].citat}
en(href=’#’) gå

Vi använder ett omslag flexbox layout på <body> med <header> riktigt bred och med en eller två <artikel> – element på varje rad, beroende på hur brett det virtuella är.

Landskap (till vänster) vs porträtt (höger) – läge.

Om vi har en gemensam <artikel> på varje rad, vi har inte öste hörn, så att deras radie är 0px. Annars kan vi ge denna radie –r en icke-noll värde.

$m-w: 15rem; /* min bredd av en artikel element. * /
$m: 1rem; /* marginal av ett sådant element. * /

html { –r: 0px; }

artikel {
marginal: $m;
min-width: $min-w;
bredd: 21em;
}

@media (min-width: 2*($min-w + 2*$m) /* räcker till 2 per rad */) {
html { –r: 4rem; }

artikel { width: 40%; }
}

Låt oss nu fundera på situationen när vi har två <artikel> – element per rad (och naturligtvis en scooped hörnet för alla, eftersom det är vad som är av intresse för oss).

I fallet av den första, vi börjar med den vänstra gränsen för discen längs med den högra kanten av sin förälder. Som är kvar: 100% så långt. För att flytta x-koordinat för den skiva centrala punkt på högra kanten av sin förälder, vi subtrahera skivans radie, vilket leder oss till vänster: calc(100% – var(–r)). Men vi vill inte ha det på den högra kanten, vi vill att den förskjutning till höger av <artikel> rörelsemarginal musd, vilket leder oss till det slutliga värdet:

vänster: calc(100% – var(–r) + #{$m});

Se Pennan genom att thebabydino (@thebabydino) på CodePen.

Längs y-axeln, vi börjar med den översta gränsen för skivan längs den nedre kanten av sin förälder—det är topp: 100%. Att sätta skivan är central punkt på den nedre kanten av den förälder box, vi flyttar den upp med en radie som ger oss toppen: calc(100% – var(–r)). Slutligen, vi vill ha denna centrala punkt för att vara $m under den förälder nedre kant, vilket ger oss den slutliga vertikal förskjutning av:

topp: calc(100% – var(–r) + #{$m});

Se Pennan genom att thebabydino (@thebabydino) på CodePen.

För det andra <artikel> (andra på samma rad), vi har samma värde i fall av vertikal förskjutning.

Se Pennan genom att thebabydino (@thebabydino) på CodePen.

Horisontellt men vi börjar med skivan till vänster gräns längs dess överordnade vänster kant—som är kvar: 0%. Att sätta skivan centrala punkt på sin förälders vänstra kanten, vi flyttar den till vänster med en radie –r, och därmed komma vänster: calc(0% – var(–r)). Men den slutliga positionen är $m till vänster om förälderns vänster kant:

vänster: calc(0% – var(–r) – #{$m});

Se Pennan genom att thebabydino (@thebabydino) på CodePen.

För det tredje <artikel> (först på sista raden), vi har samma värde för skillnaden längs x-axeln som i fallet med den första.

Se Pennan genom att thebabydino (@thebabydino) på CodePen.

Vertikalt, vi börjar med skivans övre gräns längs den övre kanten av sin förälder—det är top: 0%. Att sätta skivan centrala punkt på moderbolagets övre kanten, vi flyttar upp det med en radie –r, och därmed komma upp: calc(0% – var(–r)). Men vi vill ha det $m över förälder övre kant, så att den slutliga top offset är:

topp: calc(0% – var(–r) – #{$m});

Se Pennan genom att thebabydino (@thebabydino) på CodePen.

För den sista (näst sista raden), vi har samma horisontell offset som i fallet av en ovanför och samma vertikal förskjutning som för en till vänster på samma rad.

Se Pennan genom att thebabydino (@thebabydino) på CodePen.

Så, vår förskjutningar kan skrivas:

artikel:n: te-av-typ(1) { /* 1 */
vänster: calc(100%/* 2*50% = (1 + 1)*50% = (1 + i)*50% * / var(–r) + /* i=+1 */#{$m});
topp: calc(100%/* 2*50% = (1 + 1)*50% = (1 + j)*50% * / var(–r) + /* j=+1 */#{$m});
}

artikel:n: te-av-typ(2) { /* 2 */
vänster: calc( 0%/* 0*50% = (1 – 1)*50% = (1 + i)*50% * / var(–r) – /* i=-1 */#{$m});
topp: calc(100%/* 2*50% = (1 + 1)*50% = (1 + j)*50% * / var(–r) + /* j=+1 */#{$m});
}

artikel:n: te-av-typ(3) { /* 3 */
vänster: calc(100%/* 2*50% = (1 + 1)*50% = (1 + i)*50% * / var(–r) + /* i=+1 */#{$m});
topp: calc( 0%/* 0*50% = (1 – 1)*50% = (1 + j)*50% * / var(–r) – /* j=-1 */#{$m});
}

artikel:n: te-av-typ(4) { /* 4 */
vänster: calc( 0%/* 0*50% = (1 – 1)*50% = (1 + i)*50% * / var(–r) – /* i=-1 */#{$m});
topp: calc( 0%/* 0*50% = (1 – 1)*50% = (1 + j)*50% * / var(–r) – /* j=-1 */#{$m});
}

Detta innebär att positionerna av de centrala punkterna av skivor, beroende på skillnaden mellan vår <artikel> – element (detta gap är dubbelt marginalen: $m vi satt på dem), på skivan radie r och på ett par av horisontella och vertikala multiplikatorer (–och jag –j respektive). Båda dessa multiplikatorer initialt -1.

För de två första <artikel> – element (på den första raden i 2×2 grid), vi ändra den vertikala multiplikator –j 1 eftersom vi vill att y-koordinaten för de skivor som ” central poäng att ligga under den nedre kanten, medan det för den udda (i första kolumnen), vi ändra den horisontella multiplikator –jag till 1 för att vi vill ha x-koordinat för att vara till höger om den högra kanten.

html { –jag: -1; i –j: -1 } /* multiplikatorer från början inställda på att -1 */

h3-avsnitt {
&innan {
/* ställ generiska förskjutningar */
topp: calc((1 + var(–j))*50% – var(–r) + var(–j)*#{$m});
vänster: calc((1 + var(–i))*50% – var(–r) + var (- jag)*#{$m});
}
}

@media (min-width: 2*($min-w + 2*$m)) {
artikel {
/* ändra vertikal multiplikator för de två första (på 1: a raden av 2×2 ikoner) */
&:n: te-av-type(-n + 2) { –j: 1 }

/* ändra horisontell multiplikator för udda (på 1: a kolumnen) */
&:n: te-av-typ(udda) { –jag: 1 }
}

Observera att vi endast har synliga skiva hålen på <del> – element för de två första <artikel> – element, och endast på <h3> för de två sista. Så de första två <artikel> – element, radie –r på rubriken är ::före pseudo-element är 0, medan det för de två sista, denna radie är 0 för avsnittet ::före pseudo:

@media (min-width: 2*($min-w + 2*$m)) {
artikel {
&:n: te-av-type(-n + 2) h3,
&:n: te-av-typ(n + 3) avsnitt { &:innan { –r: 0 ; } }
}
}

På ett liknande sätt, vi lägger till differentierade stoppningar till barn <artikel> – element:

$p: .5rem;

h3-avsnitt { padding: $p; }

@media (min-width: 2*($min-w + 2*$m)) {
artikel {
&:n: te-av-type(-n + 2) avsnitt
&:n: te-av-typ(n + 3) h3 {
padding-right: calc(.5*(1 + var(–i))*(var(–r) – #{$m}) + #{$p});
padding-left: calc(.5*(1 – var(–i))*(var(–r) – #{$m}) + #{$p});
}
}
}

Detta hjälper oss att få de resultat som vi letar efter:

Se Pennan genom att thebabydino (@thebabydino) på CodePen.

Ovanstående demo fungerar i nuvarande versioner av alla större webbläsare, och om vi kan göra med vissa upprepningar i stället för att använda CSS variabler, kan vi utöka stöd hela vägen tillbaka till IE9.

Eventuella problem med ovanstående metod

Även om detta var en snabb och enkel cross-browser sätt att få det önskade resultatet i det här fallet, vi kan inte alltid vara så lycklig med denna strategi.

Först och främst behöver vi en pseudo-element för varje öste hörnet, så om vi vill att denna effekt för alla hörn, vi måste ta in ett extra element. Ledsen panda.

För det andra, kan vi inte alltid vill ha en enfärgad bakgrund. Vi kanske vill ha en semi-transparent (vilket blir jobbigt att få om vi vill ha mer än en scooped hörnet), en gradient en (samtidigt som vi kan efterlikna en del radiell gradienter med box-shadow, det är en mindre än idealisk lösning) eller till och med en bild som bakgrund (knappast genomförbart med den enda lösningen är att använda mix-blandning-läge som skär ut Kanten stöd utan en elegant fallback).

Och vad sägs om riktigt stora lådor för vilken spridning vi har ställt är det inte tillräckligt? Usch.

Så, låt oss utforska andra, mer tillförlitliga metoder med olika grad av webbläsare.

Flexibilitet och bra webbläsare? SVG det!

Detta är nog ingen överraskning, men det full SVG-lösning biljettpriser bästa är om vi vill ha något som är flexibelt och tillförlitligt cross-browser idag. Det är en lösning som innebär att man använder en SVG-element innan innehållet i vår låda. Denna SVG innehåller en <circle>, som vi har satt en radie r attribut.

<div class= “box”>
<svg>
<cirkel r=’50’/>
</svg>
TEXTEN PÅ LÅDAN GÅR HÄR
</div>

Vi är absolut position denna SVG i rutan och storlek det så att det fullt ut täcker sina överordnade:

.box { position: relative; }

svg {
position: absolute;
width: 100%;
höjd: 100%;
}

Ingenting är för intressant så långt, så låt oss ge <cirkel> id och klona det i de andra hörnen:

<cirkel id=’c’ r=’50’/>
<xlink:href=’#c’ x=’100%’/>
<xlink:href=’#c’ y=’100%’/>
<xlink:href=’#c’ x=’100%’ y=’100%’/>

Observera att om vi vill utesluta ett hörn eller mer, kan vi inte bara klona det där.

Se Pennan genom att thebabydino (@thebabydino) på CodePen.

Okej, men vad vi har gjort här är att skapa cirklar i hörnen och vad vi egentligen vill ha är… raka motsatsen! Vad vi ska göra härnäst är att sätta dessa cirklar inom en <mask>, på toppen av en vit, full-storlek (som täcker hela SVG) rektangel och sedan använder vi denna mask på en annan full storlek rektangel:

<mask id=’m’ fyll i=’#fff’>
<rect id=’r’ width=’100%’ height=’100%’/>
<cirkel id=’c’ r=’50’ fyll i=’#000’/>
<xlink:href=’#c’ x=’100%’/>
<xlink:href=’#c’ y=’100%’/>
<xlink:href=’#c’ x=’100%’ y=’100%’/>
</mask>
<xlink:href=’#r’ fyll i=’#f90 ” mask=’url(#m)’/>

Resultatet kan ses nedan:

Se Pennan genom att thebabydino (@thebabydino) på CodePen.

Om vi har sms: a, vi måste anpassa rutan utfyllnad till vårt hörn radie, där det till samma värde som vi har satt radie av SVG cirkel, med hjälp av JavaScript för att hålla dem i synk:

Se Pennan genom att thebabydino (@thebabydino) på CodePen.

Naturligtvis fylla på vår bakgrund rektangel behöver inte vara en fast och en. Det kan mycket väl vara semi-transparent (som det är i demo ovan), eller så kan vi använda en SVG-gradient eller mönster för det. Det senare skulle också tillåta oss att använda en eller flera bakgrundsbilder.

Se Pennan genom att thebabydino (@thebabydino) på CodePen.

Men jag kom hit för CSS godis!

Tja, kul att du frågade! Det finns ett antal saker som vi kan göra här för att förskjuta vikten av maskering metod från SVG till CSS.

Tyvärr, ingen av dessa är cross-browser, men de förenklar saker och de är definitivt något att hålla ett öga för i den nära eller mer avlägsen framtid.

Använd CSS för maskering på HTML-element i stället

Vad vi gör här är att ta bort allt utanför masken från SVG. Sedan, från CSS, vi satt en bakgrund (som kan vara semi-transparent, en CSS-gradient, en bild, en kombination av flera bakgrunder… allt som CSS har att erbjuda) och mask egendom på den .box element:

.box {
/* någon typ av bakgrund vi önskar */
mask: url(#m).
}

Observera att ställa en infogad SVG-mask på ett HTML-element endast fungerar i Firefox för nu!

Versionen med hjälp av CSS maskering direkt på vår hemsida .box (demo, Firefox).

Ange cirkelns radie från CSS

Detta innebär att man tar bort de r-attribut från vår <circle>, och ställa det i CSS till samma variabel som en låda padding:

.box { padding: var(–r); }

[id=’c’] { r: var(–r); }

På detta sätt, när vi byter värdet av –r, både scoop radie och stoppning runt .box innehållet uppdateras!

Observera att ställa geometri egenskaper för SVG-element från CSS fungerar bara Blinka webbläsare nu!

Version med hjälp av en CSS-variabel för <cirkel> radie (live demo, Blink).

Kombinera de två föregående metoder

Även om detta skulle vara cool, det är tyvärr inte möjligt i praktiken i alla webbläsare som är just nu. Men den goda nyheten är att vi kan göra ännu bättre än så!

Använd CSS gradienter för maskering

Observera att CSS maskering på HTML-element som inte fungerar alls i Kanten på denna punkt, även om den är listad som “Under Utveckling” och en flagga för att det (som inte gör någonting för nu) har redan visat upp i ca:flaggor.

Vi dike SVG-delen helt och hållet och börja bygga vårt CSS lutning mask. Vi skapar ringar på hörnen med radiell gradienter. Följande CSS skapar en cirkel med radien –r i det övre vänstra hörnet av rutan:

.box {
bakgrund: radial gradient(cirkel på 0 för 0, #000 var(–r, 50px), transparent 0);
}

Det kan ses live i demo nedan, där vi har också gett rutan en röd kontur bara så att vi kan se dess gränser:

Se Pennan genom att thebabydino (@thebabydino) på CodePen.

Vi använda exakt samma lutning för vår mask:

.box {
/* samma som innan */
/* CSS bakgrund vi önskar */
mask: radial gradient(cirkel på 0 för 0, #000 var(–r, 50px), transparent 0);
}

Observera att WebKit webbläsare behöver fortfarande -webkit – prefix för mask egenskaper.

Vi lägger sedan till cirklar på de andra hörnen:

$grad-lista: radial gradient(cirkel på 0 för 0 , #000 var(–r, 50px), transparent 0),
radial gradient(cirkel på 100% 0 , #000 var(–r, 50px), transparent 0),
radial gradient(cirkel vid 0 och 100%, #000 var(–r, 50px), transparent 0),
radial gradient(cirkel på 100% 100%, #000 var(–r, 50px), transparent 0);
.box {
/* samma som innan */
/* CSS bakgrund vi önskar */
mask: $grad-lista
}

Det är vansinnigt repetitiva, antingen en hel del att skriva eller mycket kopiera, klistra in, så låt oss se vad vi kan göra åt det.

Först ut, vi använder en CSS-variabel för att stoppa lista. Detta eliminerar upprepningar i den genererade CSS.

$grad-lista: radial gradient(cirkeln 0 0 , var(–stop-lista)),
radial gradient(cirkel på 100% 0 , var(–stop-lista)),
radial gradient(cirkel vid 0 och 100%, var(–stop-lista)),
radial gradient(cirkel på 100% 100%, var(–stop-lista));

.box {
/* samma som innan */
/* CSS bakgrund vi önskar */
– stoppa-lista: #000 var(–r, 50px), transparent 0;
mask: $grad-lista;
}

Men det är ändå inte mycket bättre, så låt oss skapa hörn i en loop:

$grad-listan: ();

@$jag från 0 till 4 {
$grad-lista: $grad-lista,
radial gradient(cirkel i ($i%2)*100% våningen($i/2)*100%, var(–stop-lista));
}

.box {
/* samma som innan */
/* CSS bakgrund vi önskar */
– stoppa-lista: #000 var(–r, 50px), transparent 0;
mask: $grad-lista;
}

Mycket bättre att så långt som koden går eftersom vi nu inte har för att skriva något flera gånger och riskerar inte att uppdatera överallt senare. Men resultatet så här långt är inte vad vi går för:

Resultatet av koden ovan (demo, ingen avancerad support för nu).

Här ska vi skära ut allt men hörnen, vilket är motsatsen till vad vi vill.

En sak vi kan göra är att vända gradienter, göra hörnet cirklar transparent och resten svart med:

– stoppa-lista: transparent var(–r, 50px), #000 0;

Detta gör susen när vi använder bara en lutning för bara ett hörn:

Resultat när du använder bara en gradient (demo, ingen avancerad support för nu).

Men när vi stack upp alla fyra av dem (eller bara två), får vi en svart rektangel med storleken på vår box för mask, vilket innebär att ingenting blir egentligen maskerade ut längre.

Skiktning mask gradienter (demo, ingen avancerad support för nu).

Så, vi begränsa var och en av dessa gradienter att en fjärdedel av vår box – 50% av bredden och 50% av höjden, vilket få 25% (en fjärdedel) av området för varje:

Vår mask, delas in i fyra kvartal (live).

Det betyder också att vi måste ställa in en mask-storlek av 50% 50%, en mask-upprepning av no-repeat, och position varje mask-bilden i önskad hörnet:

$grad-listan: ();

@$jag från 0 till 4 {
$x: ($i%2)*100%;
$y: e våningen($i/2)*100%;
$grad-lista: $grad-lista
radial gradient(cirkel på $x $y, var(–stop-lista)) /* mask bild */
$x $y; /* mask position */
}

.box {
/* samma som innan */
/* CSS bakgrund vi önskar */
– stoppa-lista: transparent var(–r, 50px), #000 0;
mask: $grad-lista;
mask-size: 50% högst 50%.
mask-repeat: no-repeat;
}

Observera att WebKit webbläsare behöver fortfarande -webkit – prefix för mask egenskaper.

Men det stora problemet här är… problemet med division och avrundning i allmänhet—och våra fyra kvartalen behöver inte alltid klarar av att göra upp en helhet igen, så vi sluta med luckor i mellan dem.

Tyvärr, vi kan få luckor i mellan fyra kvartal (demo).

Nåja, det är inte som att vi inte kan täcka upp de luckor med tunna linear-gradient() remsor eller öka mask-storlek för att låt oss säga att 51%:

Öka mask-storlek för varje lutning lager fixar problemet med luckor (demo).

Men är inte det ett mer elegant sätt?

Tja, det är en mask-komposit egendom som kan hjälpa oss att om vi sätter det att korsas när de återgår tillbaka till full storlek, lutning lager.

$grad-listan: ();

@$jag från 0 till 4 {
$grad-lista: $grad-lista,
radial gradient(cirkel i ($i%2)*100% våningen($i/2)*100%, var(–stop-lista));
}

.box {
/* samma som innan */
/* CSS bakgrund vi önskar */
– stoppa-lista: transparent var(–r, 50px), #000 0;
mask: $grad-lista;
mask-komposit: uteslut;
}

Detta är extremt coolt eftersom det är en ren CSS, ingen SVG-lösning, men inte-så-bra nyheter är att stödet är begränsat till Firefox 53+ här.

Resultat med hjälp av mask-komposit: intersect (demo).

Men, det är fortfarande bättre än ett stöd för det sista alternativet vi har när det gäller öste hörn.

Hörnet-form alternativet

Lea Verou kom upp med denna idé för omkring fem år sedan och även skapat en förhandsgranskningssida för det. Tyvärr är det inte bara inte genomföras av alla webbläsare ännu, men spec har inte avancerat så mycket under den tiden. Det är fortfarande något att hålla i åtanke för framtiden, eftersom det ger en stor flexibilitet med väldigt lite kod – att återskapa våra effekt skulle endast kräver följande:

stoppning: var(–r).
hörn-form: scoop;
border-radius: var(–r).

Ingen markup spyor, ingen lång gradient listor, bara detta mycket enkel del av CSS. Det är… när det äntligen blir stöds av webbläsare!