w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.52k stars 673 forks source link

[css-borders-4] Use cases for `corner-shape` #6980

Open jsnkuhn opened 2 years ago

jsnkuhn commented 2 years ago

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:

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)

jsnkuhn commented 2 years ago

ANGLE EXAMPLES

https://www.marvel.com/

marvel

https://www.zelda.com/ (footer links)

zelda

https://metroid.nintendo.com/

metroid

https://thewitcher.com/en/witcher3

whitcher3

https://www.leagueoflegends.com/en-us/

lol2 lol1

button{
    corners: angle 11px 0;
    transition: corners .25s;
}
button:hover{
    corners: angle 0 0;
}

https://www.xbox.com/en-US

xbox

ANGLE AND NOTCH

https://playvalorant.com/en-us/

val

LeaVerou commented 2 years ago

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.

SelenIT commented 2 years ago

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).

LeaVerou commented 2 years ago

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.

Lorp commented 2 years ago

@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 to round? Syntax would be the same as in animation-timing-function, and it would be scaled and flipped appropriately for each corner.

jsnkuhn commented 2 years ago

Did run across a 4 corner notched example. Something like corners: notch 8px;:

https://www.zelda.com/links-awakening/

image

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?

SelenIT commented 2 years ago

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?

LeaVerou commented 2 years ago

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?

They already are independent in everything but path() (and there are thoughts to extend path() in that direction).

jsnkuhn commented 2 years ago

found the tweet I mentioned above:

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.

jsnkuhn commented 2 years ago

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/

Screenshot 2022-01-26 at 16-29-00 Pokémon Brilliant Diamond and Pokémon Shining Pearl Official Website Pokémon

https://nierautomata.square-enix-games.com/en-us/home/

Screenshot 2022-01-26 at 08-47-11 Nier Automata SQUARE ENIX

https://www.guerrilla-games.com/play/horizon

horizon

https://www.animal-crossing.com/new-horizons/

Screenshot 2022-01-26 at 16-06-30 Animal Crossing™ New Horizons for the Nintendo Switch™ system – Official Site

https://www.pokemon.com/us/

Screenshot 2022-01-26 at 16-17-49 The Official Pokémon Website Pokemon com

https://unite.pokemon.com/en-us/

Screenshot 2022-01-26 at 16-25-33 Pokémon UNITE Pokémon UNITE official website

jsnkuhn commented 2 years ago

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
SebastianZ commented 2 years ago

@LeaVerou wrote:

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.

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

bradkemper commented 2 years ago

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.

LeaVerou commented 2 years ago

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.

bradkemper commented 2 years ago

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).

faceless2 commented 2 years ago

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:

  1. 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.

  2. It explicitly has no impact on the box-sizing calcs, which is going to be really important.

  3. 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-outside or clip-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:

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.

jsnkuhn commented 2 years ago

VScode

vscode

discord.com

discord

https://squoosh.app/

Screenshot 2022-01-28 at 13-43-11 Squoosh

https://www.polygon.com/

Screenshot 2022-01-30 at 07-10-01 Polygon

https://www.smashbros.com/en_US/

Screenshot 2022-01-31 at 13-00-45 Super Smash Bros Ultimate for the Nintendo Switch system

https://www.starwars.com/news/brian-volk-weiss-interview

Screenshot 2022-01-31 at 16-03-52 From Kenner to Star Wars Galaxy’s Edge StarWars com

https://festival.gamesforchange.org/

Screenshot 2022-02-08 at 17-09-29 2022 Games for Change Festival July 12 - 15

opera GX new tab page

Screenshot 2022-02-15 at 17-11-13 Opera GX Gaming Browser Opera

jsnkuhn commented 2 years ago

some observations from this so far:

jsnkuhn commented 2 years ago

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

bradkemper commented 2 years ago
  • no use of border-image

    • This aligns with my general experience that most web Devs still don't seem to know that border-image is 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:

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.

jsnkuhn commented 2 years ago

Another scooped corners example

https://playwonderlands.2k.com/

image

bradkemper commented 2 years ago

image

Community Theater site using simple background for a ticket shape.

jsnkuhn commented 2 years ago

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/

Screenshot 2022-04-08 at 11-07-34 Marcus Theatres Find Movie Times and Buy Tickets Online

jsnkuhn commented 2 years ago

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.

unknown

jsnkuhn commented 2 years ago

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/

jsnkuhn commented 2 years ago

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: SWCALive-Hosts-1280

webpage-guests

jsnkuhn commented 2 years ago

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

WW_SS004-1024x576

jsnkuhn commented 2 years ago

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

image

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;
jsnkuhn commented 2 years ago

https://www.residentevil.com/village/us/

Screenshot 2022-06-05 at 18-22-41 Resident Evil Village CAPCOMreviii

https://www.videogameschronicle.com/

image image

jsnkuhn commented 2 years ago

discord.com

GIF

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

starfield

jsnkuhn commented 2 years ago

https://www.monsterhunter.com/rise/us/

image

jsnkuhn commented 2 years ago

added an "example index" to the OP to give a better idea of what we have at a glance and links to existing cornershape related paintAPI worklets

jsnkuhn commented 2 years ago

https://www.nintendo.com/store/products/live-a-live-switch/

Screenshot 2022-06-28 at 15-35-52 LIVE A LIVE for Nintendo Switch - Nintendo

https://www.ign.com/articles/stranger-things-season-4-part-2-review

Screenshot 2022-07-01 at 08-51-02 Stranger Things Season 4 Part 2 Review - IGN

https://www.theverge.com/2022/6/16/23171447/activision-blizzard-investigation-sec-filing

Screenshot 2022-06-18 at 17-05-38 Activision Blizzard investigated Activision Blizzard and found Activision Blizzard didn’t do anything wrong

SelenIT commented 2 years ago
  • this would be one of those border-radius: 999999999px; situations I think?

I suppose that regular hexagon could be done with something like corners: angle 50%/25% along with aspect-ratio: calc(sqrt(3)) / 2.

jsnkuhn commented 2 years ago

a 25 minute video of Kevin Powell explaining how to do angled corners with borders in current CSS... https://www.youtube.com/watch?v=aW6qEAQSctY

jsnkuhn commented 2 years ago

https://www.espn.com/

Screenshot 2022-07-19 at 13-23-28 ESPN Serving sports fans  Anytime  Anywhere

 corner: none none angle none 20px / 100%;
jsnkuhn commented 2 years ago

appears that round and angle corner shapes are doable in android already:

https://twitter.com/googledevs/status/1550571429787308034

jsnkuhn commented 2 years ago

another not a webpage thing but thought it worth pointing out that my local branch of the US national weather service uses angled corners in their info graphics. The point being when the option is easily available this is what they want to do and I don't see why it would be any different on the web.

FZJt8L7VQAAsOov

jsnkuhn commented 2 years ago

just ran across a screen shot that reminded me that Chrome itself had trapezoid shaped tabs for a while

iRmBZ

    --corner-size: 16px / 100%;
    --corner-shape: angle angle none none;
LeaVerou commented 2 years ago

just ran across a screen shot that reminded me that Chrome itself had trapezoid shaped tabs for a while

iRmBZ

    --corner-size: 16px / 100%;
    --corner-shape: angle angle none none;

Except these have rounding at the corners, which this wouldn't do.

jsnkuhn commented 2 years ago

https://www.birmingham2022.com/results/day-by-day

image

jsnkuhn commented 2 years ago

https://www.littleleague.org/world-series/2022/llbws/

little-league

jsnkuhn commented 2 years ago

https://nierreincarnation.com/

image

SebastianZ commented 2 years ago

Just for reference, because I think it wasn't mentioned so far, notch and scoop were previously removed from the spec. due to a resolution in #3457.

That said, there are obviously several use cases for them as @jsnkuhn pointed out. So my vote would be to add those keywords back to cover the most common use cases. And anything more complex should be discussed in #6997.

Sebastian

LeaVerou commented 2 years ago

Idea: There are far more use cases for irregular polygons with some rounding on their corners, than for scoop and notch alltogether. So I wonder if perhaps we need a separate, orthogonal property for the bevel aspect of these corners, with border-radius continuing to apply for their corners.

jsnkuhn commented 2 years ago

angled corner found on a surgery center website of all places

http://www.mfasc.com/

image

jsnkuhn commented 2 years ago

Might a good place to first introduce corner-shape be inside clip-path: inset();. It already has an optional round keyword for rounding corners. It also has no concern for borders because it is independent of the box model.

the syntax would be similar to the corners shortcut:

clip-path: inset(0 angle 12px);

the use case here would be to simplify all the calc(100% - ) needed in polygon to get at the corner shape look.

clip-path: polygon( 12px 0, calc(100% - 12px) 0, 100% 12px, 100% calc(100% - 12px), calc(100% - 12px) 100%, 12px 99%, 0 calc(100% - 12px), 0 12px);

Would be nice if this ultimately could be turned into something like clip-path: corners(angle 12px); as I don't think most of the use cases would actually require the insetting.

jsnkuhn commented 1 year ago

image

testing my corner-shape paintAPI polyfill for this one with an SVG sprite fallback

background: url('images/staff-back-all.svg') no-repeat 0 0 / 394px 300%;
background: paint(cornerShape);
--background-color: rgb(0,0,0,.3);
--border-color: #40ff00;
--border-width: 2px;
--corner-size: 26px / 22px;
--corner-shape: angle;
jsnkuhn commented 1 year ago

change.org petition progress bar is the pill shape on the left and angles meeting in the middle on the right

https://www.change.org/p/city-of-florence-government-bring-back-the-old-florence-logo

image

--corner-size: 9999px; --corner-shape: round angle angle round;

LeaVerou commented 1 year ago

@jsnkuhn the examples with borders etc are better, the change.org petition bar can be done with clip-path without any loss of maintainability or any compromise in the visual result.