csswg-drafts
csswg-drafts copied to clipboard
[css-borders-4] Use cases for `corner-shape`
The point of this thread is to collect designs from existing websites where corner-shape would make web developers jobs easier. Current live sites are preferred to demos.
Some related links:
Similar thread from 2013 when the idea of corner-shape was first introduced (note: most use case example from this thread now are dead or link to pages that have been redesigned):
https://lists.w3.org/Archives/Public/www-style/2013Mar/0505.html
Lea's original svg corner-shape demo: https://projects.verou.me/corner-shape/
The working draft spec in it's current state: https://drafts.csswg.org/css-backgrounds-4/#corner-shaping
corner shape related paintAPI worklets:
- scoop (Surma): https://houdini.how/#demo-@houdini-modules/border-radius-reverse
- all 4 corners scooped and same size for each
- Corner shapes (iamvdo): https://css-houdini.rocks/corner-shape
- all 4 corners same shape and size. Round/bevel/scoop/notch options
- angled-corners (Una Kravets) https://houdini.how/#demo-angled-corners
- border only no fill. option for different corner sizes per corner but only corners with same width and height
- squircle (PavelLaptev) https://pavellaptev.github.io/squircle-houdini-css/
- CSS corner-shape (jsnkuhn) https://github.com/jsnkuhn/corner-shape
- filled and stroked background-image supported
--corner-shapeallows per corner shaping including mixing of shapes (angle/scoop/notch/round)--corner-sizeoptions for fullborder-radius8 value slash syntax (allows for each corner to have different width and height)
Example Index:
Angle/Bevel
https://www.marvel.com/ (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1020198847) https://www.zelda.com/ (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1020198847) https://thewitcher.com/en/witcher3 (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1020198847) https://www.leagueoflegends.com/en-us/ (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1020198847) https://nierautomata.square-enix-games.com/en-us/home/ (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1023357465) https://www.guerrilla-games.com/play/horizon (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1023357465) https://www.animal-crossing.com/new-horizons/ (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1023357465) https://squoosh.app/ (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1041536065) https://www.polygon.com/ (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1041536065) https://www.starwars.com/news/brian-volk-weiss-interview (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1041536065) https://festival.gamesforchange.org/ (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1041536065) opera GX new tab page (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1041536065) https://elderscrolls.bethesda.net/en/skyrim (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1146894704) https://www.videogameschronicle.com/ (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1152284666) https://www.monsterhunter.com/rise/us/ (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1155089608)
Angle/Bevel extended
https://www.xbox.com/en-US (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1020198847) https://metroid.nintendo.com/ (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1020198847) discord.com (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1041536065) https://www.smashbros.com/en_US/ (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1041536065) https://www.marcustheatres.com/ (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1095114477)
Scoop
https://diamondpearl.pokemon.com/en-us/ (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1023357465) https://playwonderlands.2k.com/ (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1080011720) Community Theater site using simple background for a ticket shape (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1081302026) https://www.residentevil.com/village/us/ (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1152284666) https://bethesda.net/en/game/starfield/media?type=video (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1154223456)
Scoop extended
Notch
https://www.zelda.com/links-awakening/ (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1020506746)
Notch extended
Squircle
Squircle extended
discord.com? (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1154223456)
Mixed shapes
https://playvalorant.com/en-us/ (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1020198847) https://unite.pokemon.com/en-us/ (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1023357465) VScode (https://github.com/w3c/csswg-drafts/issues/6980#issuecomment-1041536065)
ANGLE EXAMPLES
https://www.marvel.com/

- call to action buttons: one with flat red, another with white border
:beforeand:afterused w/ border hacks- corner-shape leads to considerably less code:
corners: angle 16px 0;
https://www.zelda.com/ (footer links)

- this is the prototypical example of angled corners. All four corners with the same angle size.
- currently done with
:beforeand:afterbackground-images on the left and right of the parent element. Similar to how we use to do rounded corners beforeborder-radiuswas a thing. - also includes a
border-radius... Guessing this was intended as a fallback? but never got removed? This implies there were a couple of attempts at how to do this. - corner-shape code is just a one-liner:
corners: angle 8px;
https://metroid.nintendo.com/

- long angle bottom edge and call to action buttons
- done with an absolute positioned inline SVG
- a little broken in Firefox
- long angle bottom edge
corners: angle 0 0 90% 10% / 0 0 70px 42px; - call to action buttons
corners: angle 16px / 100% 0;
https://thewitcher.com/en/witcher3

- corners: angle 28px 0 0 28px/ 50% 0 0 50%;
https://www.leagueoflegends.com/en-us/

- many different examples
- currently done with
canvas - many with hover animations that would be made trivial with corner-shape
button{
corners: angle 11px 0;
transition: corners .25s;
}
button:hover{
corners: angle 0 0;
}
https://www.xbox.com/en-US

- horizontal rule kinda thing
- appears to currently use an icon font
- corners: angle 9px 0 / 100% 0;
ANGLE AND NOTCH
https://playvalorant.com/en-us/

-
angled corner bottom left, notched corner bottom right
-
border-radius: 0 0 95px 95px / 0 0 6px 54px;corner-shape: none none notch(?) angle;
It seems to me that almost all of these examples are bevel corners and various types of polygons/parallelograms/trapezoids etc. None of them are using corner-shape: notch | scoop.
Furthermore, I feel that using corner-shape to create polygons, triangles etc is a bit of a hack. I wonder if what we actually need is something like element-shape: <shape>, and then borders, shadows etc would follow that shape.
This allows creating "bevel" corners like this:
--corner-size: 10px;
element-shape: polygon(
var(--corner-size) 0, calc(100% - var(--corner-size)) 0, /* top */
100% var(--corner-size), 100% calc(100% - var(--corner-size)), /* right */
calc(100% - var(--corner-size)) 100%, var(--corner-size) 100%, /* bottom */
0 calc(100% - var(--corner-size))
);
…which is admittedly a lot more involved than corner-shape: bevel; but also allows creating arbitrary shapes, even SVG paths.
From what I remember the tricky bit of implementing/specifying all of these is border geometry, especially when top, right, bottom, left borders all have different thicknesses and/or colors. Given that the use cases that actually require a non-uniform border AND a custom shape are practically nil, I wonder if there's an easy way to get this out of the way, even if the visual result in these rare cases is suboptimal. @fantasai would love your input.
Anothe useful, though not much used because of difficuilty of implementation, corner shape seems to be the "squircle" or "superellipse" shape, or at least its approximation with Bezier curves. Searching for "CSS squircles" shows quite a lot of attempts to solve it with existing tools (mostly complex clip-path or even Houdini).
Anothe useful, though not much used because of difficuilty of implementation, corner shape seems to be the "squircle" or "superellipse" shape, or at least its approximation with Bezier curves. Searching for "CSS squircles" shows quite a lot of attempts to solve it with existing tools (mostly complex clip-path or even Houdini).
That is yet another argument for element-shape above, which would allow this fairly easily.
@SelenIT wrote:
Anothe useful, though not much used because of difficuilty of implementation, corner shape seems to be the "squircle" or "superellipse" shape, or at least its approximation with Bezier curves. Searching for "CSS squircles" shows quite a lot of attempts to solve it with existing tools (mostly complex clip-path or even Houdini).
In #6296 I suggested cubic-bezier() as a way of getting squircular corners without needing syntax for arbitrary shapes:
How about allowing
cubic-bezier()as an alternative toround? Syntax would be the same as inanimation-timing-function, and it would be scaled and flipped appropriately for each corner.
Did run across a 4 corner notched example. Something like corners: notch 8px;:
https://www.zelda.com/links-awakening/

Very much agree that corner-shape for polygons gets messy. Once you start using the slash syntax to give corners different widths and heights things get hard to follow. And even more when you throw a 100% corner height or width in it kinda ceases to be a corner anymore.
Didn't @tabatkins post something on twitter not too long ago about an idea for a CSS syntax for creating SVGs?
What makes the polygon creating an issue is all the calc(100% - var(--corner-size)) repetition. Would it be possible to come up with a unit that was a 100% - value unit?
Maybe element-shape could (optionally) share the 9-slice scaling pattern with border-image/mask-border, making coordinates of corners independent from the size of the image itself?
Maybe
element-shapecould (optionally) share the 9-slice scaling pattern withborder-image/mask-border, making coordinates of corners independent from the size of the image itself?
They already are independent in everything but path() (and there are thoughts to extend path() in that direction).
found the tweet I mentioned above:
Working on this really makes me want to take up the "SVG embedded in CSS" project again, so you could write:@svg --bg {
— pascal's banger (@tabatkins) December 23, 2021
width: 200px;
height: 300px;
@rect {
x: 0; y: 0; width: 100%; height: 100%;
fill: green;
}
}
Then `background: svg(--bg);` to use it.
Also was just thinking that when border-radius was added I think it was just that folks wanted the rounded corners? but the ability to do circles with the border-radius: 50%; value just came along with it? It occurs to me that the same sort of things happens with the angled corner. Except it would be 2 shapes. corners: angle 50%; would gets you a diamond shape and corners: angle 25%; would give a fairly even octagon.
still not having a whole lot of luck finding scoop or notch examples. If anyone knows of places where these are common please don't hesitate to drop links or point in the right direction.
https://diamondpearl.pokemon.com/en-us/

corners: scoop 10px;
https://nierautomata.square-enix-games.com/en-us/home/

- the above mentioned diamond shape backgrounds
- i'm assuming corner-shape wouldn't clip the content overlapping the corners
corners: angle 50%;- also has an angle on the right side of the header
https://www.guerrilla-games.com/play/horizon

- triangle behind logo in header:
corner-bottom-right: angle 100%;(so that looks like it makes many of the border hack triangle shapes pretty easy at least the diagonally pointed ones) - top right corner bevel:
corner-top-right: angle 30px;
https://www.animal-crossing.com/new-horizons/

- call to action button
- first one of these that I've run into that is actually an SVG
corners: angle 30px / 20px;
https://www.pokemon.com/us/

- might be more a polygon and less a corner shape but could probably do a close approximation
https://unite.pokemon.com/en-us/

- square, angle, round, angle
Because someone is likely to ask... No you couldn't really do the twitter NFT shape with corner-shape. The general hexagon shape yes, but you'd need an SVG path to get all the detail.
corner-shape: bevel (angle)
border-radius: 25% / 50%
width: 400px
height: 300px
@LeaVerou wrote:
Furthermore, I feel that using
corner-shapeto create polygons, triangles etc is a bit of a hack. I wonder if what we actually need is something likeelement-shape: <shape>, and then borders, shadows etc would follow that shape.
I love the idea of being able to define individual shapes for elements. Though I believe this goes far beyond the use case of specifying a different shape for a corner defined via border-radius and therefore deserves its own discussion. So I've created #6997 for that.
Sebastian
I think the problem with finding scoop and notch examples is that there isn't an easy way to hack them. Using 'border-image' requires an image, and trying to do it a vector image (SVG) is complicated and slow-rendering and sometimes inconsistent. I think if 'corner-shape' existed and could do scoops, we'd see a lot more designs with scoops, as there are in print design.
If something is doable with an image, that's annoying but not enough to deter people from using it in production. People have been using images for effects they cannot do in CSS for decades.
I'm not keen on having yet another way to create polygons and paths. I'd rather we found a way to unite shape-outside and clip-path, and apply borders and box-shadows and filters to those shapes (maybe a keyword to shape-outside or clip-path that does that, with only border-top going all the way around the shape, and maybe with an extra control for how pointy or rounded the miters are).
I agree with Brad's comments above - we already have these concepts in CSS, we shouldn't be trying to reinvent an (arbitrarily-shaped) wheel.
Someone mentioned border-image above - I think this is the model to follow for several reasons:
-
When specified it overrides all the border properties, and defines the entire outline in one go. The alternative is deciding where "left" stops and "top" starts, which is impractical for arbitrary shapes.
-
It explicitly has no impact on the box-sizing calcs, which is going to be really important.
-
Because of the previous point, it introduces the concept of expanding the visible outline of the box by a certain number of pixels - i.e. drawing outside the nominal border-box. This approach would work well for shapes too (every browser already has code to expand or contract a path, as we have to do it when clipping to SVG stroke outlines). And allowing shapes to be expanded or contracted means you can reuse existing outlines like the
shape-outsideorclip-path.
So, personally, I'd go with something more like a single border-shape property. Like border-image it completely overrides all the border properties if specified, it has no-impact on box-sizing at all, and as well as the style/color/width it takes both:
- a path or the keywords
shape-outsideand/orclip-pathto reference those shapes. - the number of pixels to expand/contract that path.
As this builds on the conceptual models of border-image we'd be able to implement it using the same approach without too much trouble.
VScode

- as i understand it vscode is written with css?
- top left corner star background
discord.com

- how many peeps in a room counter
https://squoosh.app/

- inline svg
https://www.polygon.com/

- was hoping that they'd be using clip-path: polygon(); on ploygon.com but nope border hack.
corner-top-right: angle 30px;
https://www.smashbros.com/en_US/

- lots of angles, so many I couldn't get them all in 1 screenshot
- so... many... border... hacks
https://www.starwars.com/news/brian-volk-weiss-interview

- author image
https://festival.gamesforchange.org/

- currently just an images but could be div with corner-shape
corners: angle 0 32px 32px 32px;
opera GX new tab page

corners: angle 14px 4px;
some observations from this so far:
-
no use of
border-image- This aligns with my general experience that most web Devs still don't seem to know that
border-imageis a thing. - Or they know about it but think it's super complicated and therefore avoid it (may have never even tried it).
- This aligns with my general experience that most web Devs still don't seem to know that
-
little use of
clip-path- honestly always more fiddly than you think it'll be
- mostly have to use a generator (like clippy - https://bennettfeely.com/clippy/ ) at least for starters
calc(100% - var())to be responsive- if you've never used it and check support it's honestly kinda confusing because of how piece meal browser implementation was
-
in both above cases you have to draw out the entire shape excluding the corner shape(s) you want. Which feels like using a hammer to put a thumb-tack in a cork-board.
- This is the opposite of the corner-shape/border-radius approach where you would deal with just the corners.
-
devs will still work really hard (sometime to extremes) to not download an image.
Maybe the start of a more complete paint API polyfill for corner-shape? Currently supports only angled corners but with the option for the full 8 value border-radius/corner-size syntax (ie border-radius: 0 50% 50% 0 / 0 25% 25% 0;). Currently a Codepen but can throw this up on github if anyone else is interested in helping out?:
https://codepen.io/jsnkuhn/pen/NWgBBdO?editors=1100
no use of
border-image
This aligns with my general experience that most web Devs still don't seem to know that
border-imageis a thing.Or they know about it but think it's super complicated and therefore avoid it (may have never even tried it).
I think you are probably right. As one of the authors of that spec, it is disappointing, but I also don't use it much. With raster images:
- Have to make a new image every time you want to change shape, color, etc.
- Have to make it at least twice the size in order to make sure it looks good on high resolution (Retina) displays.
- Have to deal with moving more files around, deploying to server, etc.
- Fun times hoping you have the PhotoShop (or whatever) color space settings right in order for the color in the image match the same color in the browser.
SVG can be used, but that adds different complications. It can be super complicated, depending on what you are trying to achieve, and it can render slowly, and there are browser differences.
- devs will still work really hard (sometime to extremes) to not download an image.
I think I tend to be in that camp, especially with raster images.
Another scooped corners example
https://playwonderlands.2k.com/

- made with circles at the corners with radial gradients that are then masked
- corner-shape equivalent:
corners: scoop 8px;

Community Theater site using simple background for a ticket shape.
Don't really know how many more angle/bevel examples we really need but thought this was notable because its a rather big named site:
https://www.marcustheatres.com/

- done with border triangle as ::after
- corner-shape: angle;
- corner-size: 0, 100% 20px, 0 0;
A few days ago someone in Kevin Powell's discord asked about creating the below shape in CSS. corners: scoop 50%; would make this super easy.

Update on the paint API polyfill for corner-shape I was making: it now mostly works! Supports angle, notch, scoop, square and round shapes. No % support yet for sizes.
Demo page can be found here (chromium only for now): https://jsnkuhn.github.io/corner-shape/
So this is a little bit different but still use case related:
note the styling difference between the promo image from a blog post (on the top) https://www.starwars.com/news/star-wars-celebration-live-2022
and the way the same thing is styled on the website (on the bottom) https://www.starwarscelebration.com/en-us/home/announcement.html
This is just speculation on my part but i'm guessing they would be more similar if it would be easier to do:


Was just getting caught up on Westworld and found it interesting how many of these "futuristic" looking UI things would be easy with something like corner-shape:
corners: 20px angle round round;
This includes a live take on the keyboard interface with my in process paintAPI polyfill (chrome only for now) https://codepen.io/jsnkuhn/pen/oNpeyow?editors=1100

Finally found an example of a site that uses clip-path for this wide hexagon shape instead of border hacked triangles

https://elderscrolls.bethesda.net/en/skyrim
the clip-path being used:
clip-path: polygon(calc(100% - 20px) 0, 100% 50%, calc(100% - 20px) 100%, 20px 100%, 0 50%, 20px 0%);
vs
corners: angle 40px;
https://www.residentevil.com/village/us/


- we have not only an example of scooped corners but finally (after half a year) have a use of
border-image! corner-shape: scoop;could save the http request
https://www.videogameschronicle.com/

- an example of a bottom right angle across multiple components that is currently implemented in different ways for each component. A simple syntax for the
corner-shapecould save this headache.
discord.com

- icons transition form circles to, I think, squircles on hover (But could just be
border-radius... i'm not sure).
But this brings up the idea of animating between different corner-shape values ie round to scoop, notch to angle.
I assume that square 20px would also animate to square 40px and angle 0 to angle 10% like border-radius currently does. It's the morphing of the shapes that seems like it could be an issue.
https://bethesda.net/en/game/starfield/media?type=video

- the little stars on the left and the right are currently inline svg
- a ::before and ::after with
scoop 50%could do the same thing