[csswg-drafts] [css-background-4] Issues with listifying border-color

LeaVerou has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-background-4] Issues with listifying border-color ==
In the [2017 Tokyo F2F](https://lists.w3.org/Archives/Public/www-style/2017May/0049.html) we resolved on listifying `border-color` with the design allowing for future listification of `border-width` and `border-style`.
We decided on `border-color` being the property that sets the number of borders, since a common case is having multiple borders with the same width and we didn't want authors to have to repeat the width of each stripe.

However, this has very unexpected and confusing repercussions. It means that setting `border-color` can increase the total border width. In the following:

```css
border-width: 10px;
border-color: red, black, white;
```

the resulting border width is actually 30px! (since `border-width` is expanded, per usual listification rules) This has never arisen before because none of our other listified properties stack this way, they are all independent layers.

Furthermore, another issue is that listification typically repeats the same syntax that a property already has. Since `border-color` accepts 1-4 colors for each side, this results in very weird listified syntax that inverts the relative power of space and comma to the exact opposite of how it would be expected to work. Something like `border-color: skyblue orange yellowgreen indianred, black yellow` would have this result:

![image](https://user-images.githubusercontent.com/175836/38607092-1198f110-3d78-11e8-9982-ad39e0faf6d4.png)

which is a completely nonsensical way to specify border colors. People think of all colors for a side as a group, they don't group colors by whether they are innermost or outermost.

For these reasons, @fantasai and I are exploring alternative syntaxes that cover most use cases with a more intuitive syntax.

The primary use cases we must definitely cover are:

- Multiple border stripes of equal width should be effortless, with no width duplication.
- Different width stripes with fixed ratios between them (e.g. two 1fr stripes with one 2fr color between them)
- A mix of fixed and flexible width stripes (e.g. two 1px black borders with blue between them that occupies the entire rest of the border). `fr` units deal very nicely with this.
- We don't think different styles are particularly useful here. Almost all use cases we've seen are about solid borders. Therefore, we're ok with having multiple colors for different styles just be defined as a cutout of the solid case.
- Are different colors per side useful?

## Idea 1: Making `border-color` accept a list of color stops

While this may sound like a convenient re-use, it has several issues. Unlike gradients, in borders stripes are more often desired (are gradients even that useful here?) so we'd need to change how the syntax behaves anyway. Re-using a concept from somewhere else (like gradients) but subtly changing it is confusing.
Also, color stops are specified with absolute positions across the gradient line, whereas with borders you more often than not want them to "stack" and define widths instead of starts and ends (also so you can use `fr` units, which would be convenient here, as discussed above).

## Idea 2: Adding a `border-stripes` (name TBB) property that accepts a *1-dimensional image* or a list of colors and widths.

The main problem with this is the way it interacts with `border-color`. Unless there is a transparent stripe, `border-color` will have no effect when this property is set. One of the most confusing things about CSS is when a property enables/disables another property. I'd rather not introduce even more of that.

## Idea 3: `stripes()` + `border-image-side` (name TBB) or `border-color`

This would define a `stripes((<color> <length>?)#)` function that creates a one dimensional image. Lengths would also accept `fr`. This can be used anywhere that images are accepted, including backgrounds, as long as there is handling for 1-dimensional images.

Why 1-dimensional? Because otherwise, it would be problematic when combined with `border-radius`. It's tricky to define something reasonable for how a 2D image curves around the corner, and ignoring `border-radius` is suboptimal for most use cases.

There would also be a property that applies an image on each border side individually, rotating it as necessary.

So, the original use case of equal width black and white borders would be `border-image-side: stripes(black, white)`. Alternatively, we could extend `border-color` itself to accept 1-dimensional images, which reads even more nicely:

```css
border-color: stripes(black, white);
```

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/2532 using your GitHub account

Received on Wednesday, 11 April 2018 11:33:57 UTC