Skip to content

[css-backgrounds-4] Proposal: extend background-clip to support clip-path options #3140

@AmeliaBR

Description

@AmeliaBR

Inspired by a discussion with Amber Weinberg about a tricky design, in which she had non-rectangular element shapes that also needed a bit of a "border" around the shape. I thought:

Wouldn't it be convenient if you could do it with layered backgrounds, clipping each one to slightly different clip paths?

With background-clip as defined in Backgrounds & Borders 3, you can trim different background layers to different CSS boxes. But you can't inset/outset the backgrounds to something e.g., halfway through the padding space. And you can't change the border-radiusing on the clipped background to anything other than what will be generated automatically from the outer border-radius. And you definitely can't clip it to any shapes other than radiused rectangles.

But all major browsers now support the text value (standardized in Backgrounds & Borders 4), and most of them support it for a single layer in a stack of backgrounds. Level 4 also defines a keyword for clipping a background layer to the defined border-shape.

So if you can implement that, I'm fairly certain it wouldn't be too much more complicated to implement arbitrary background clips using CSS shapes or even SVG clipping paths. The calculation of the clipping area would be the exact same as for the clip-path property, but would only apply to one layer in the stack.

And it just so happens that where the syntax of background-clip and clip-path overlap (that is, when the value is single box keyword, like border-box or content-box), that calculation would be the same as currently.

As an example, the arrow shapes in the design Amber was tackling would be coded something like this (using the image() function notation to represent multiple solid-color layers, but solid-color gradients could be used as a more universal fallback):

.donate-link {
  padding: 20px 60px 20px 85px;
  background: image(blue), image(white), #444;
  background-clip:
    border-box polygon(4px 0, 24px 50%, 4px 100%, 100% 100%, 100% 0), /* inner blue arrow */
    border-box polygon(0 0, 20px 50%, 0 100%, 100% 100%, 100% 0), /* outer white arrow */
    border-box; 
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions