Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-borders-4] Issues with listifying border-color #2532

Closed
LeaVerou opened this issue Apr 11, 2018 · 17 comments
Closed

[css-borders-4] Issues with listifying border-color #2532

LeaVerou opened this issue Apr 11, 2018 · 17 comments

Comments

@LeaVerou
Copy link
Member

LeaVerou commented Apr 11, 2018

This is related to #1172.

In the 2017 Tokyo F2F 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:

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. Look at this code and visual result:

border-color: skyblue orange yellowgreen indianred, black yellow

image

This 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: stripes() + border-color

This would define a stripes((<color> && <length-percentage>?)#) 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. Possibly these could also be used in place of the gradient line in all our gradient functions.

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.

So, the original use case of equal width black and white borders would be:

border-color: stripes(black, white);

Other cases:

Code Meaning
stripes(2px white, black 1fr, 2px white) Two 2px white borders with black in between them
stripes(red, green, blue) 3 equal width stripes, starting from red on the outside, green in the middle, blue on the inside
stripes(red 1fr, green 2fr, blue 1fr) 25% red on the outside, 50% green in the middle, 25% blue on the inside.
stripes(red) Same as border-color: red
stripes(red 30%, green) Same as stripes(red 30%, green 1fr): 30% red and 70% green.

Idea 3: Adding a border-stripes (name TBB) property that accepts a 1-dimensional image (as described above) 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.

@css-meeting-bot
Copy link
Member

The Working Group just discussed Issues for listifying border-color, and agreed to the following:

  • RESOLVED: Add stripes() to border-color and outline-color
The full IRC log of that discussion <myles> Topic: Issues for listifying border-color
<myles> Github: https://github.com//issues/2532
<myles> leaverou: There’s a very detailed write up in the issue of everything I’m going to say
<myles> leaverou: Do people remember the issues with listifying border-color? A few meetings ago, we resolved to listifying border-colors, because 1) Authors wanted multiple borders, but primarily a11y needed borders that are both white and black so that they are visible over any background. So we listifying border-color with the goal of listifying alt he border properties
<myles> leaverou: BUt when I actually tried to listifying border-color, there were several issues.
<myles> leaverou: 1) Because of the way listified properties work, if the lists are mismatched, the shorter lists are padded with the last term, which means if you have a border-width of 10px, and say 3 border colors, then 10px becomes 10px, 10px, 10px, which gives you a width of 30px. So setting border-color has the effect of tripling your border width. Weird, and this is the first time
<myles> heycam: Wouldn’t this happen with any other listified properties?
<myles> leaverou: Others don’t stack. Backgrounds and animations are independent. But border-width, they stack, they aren’t independent.
<myles> tantek: Or you have to do weird math, which is worse.
<myles> leaverou: Other issue: based on how other properties were listified, the property got almost the same syntax it already had, but you could add more with commas. So, previously it accepted 4 colors, you could have 1-4 colors, then commas, then 1-4 colors, etc. This inverts the relative power of white space and commas, which is not how authors think
<myles> leaverou: You can see an example in the issue
<myles> leaverou: It’s quite unexpected.
<myles> leaverou: For those reasons, fantasai and I were thinking of an alternative way to do multiple border colors, because there aren’t many use cases of multiple colors with different styles. All use cases for multiple borders are essentially cases for multiple colors on a solid border. So we were thinking how can we have multiple colors on existing borders. The idea is to define a function, we called
<myles> it stripes(), which lets people define a 1-dimensional image which is weird but we already have 0-dimensional images, and it can be used in border-color, and it has to be 1-dimensional image because otherwise it would be difficult to define how it works around border-radius. To cover the most prominent use cases it would include lengths and percentages, and would work with fr values
<tantek> Lea's proposal looks like an improvement to me
<myles> leaverou: I have a list of the use cases we tried to cover in the issue, and a table of what the different syntaxes would look like. We also considered letting border-color accept a sequence of color stops, but that’s not convenient, because with borders, people usually wants stripes not gradients, and it’s hard to make stripes with the gradient syntax
<myles> fantasai: You don’t want absolute positions
<fantasai> s/positions the way gradient stops do them, but rather widths that stack/
<myles> leaverou: We also considered using a new border-stripes property. But it has weird affects. It combines with border-color in a confusing way, because unless there are transparent stripes, you dont’ see border-color. In general, having properties that disable other properties is some fo the most confusing parts of css
<myles> emilio: Firefox used to have multicolor border support, by using a new property
<myles> leaverou: Yep, and it was confusing
<myles> chris: We decided not to do it the Firefox way
<myles> dbaron: It was a hack to create a certain button style without making extra dives
<myles> leaverou: I used it 10 years ago to simulate box shadow
<myles> TabAtkins: I like it
<myles> astearns: What happens when the total sum of the width exceeds the border width?
<myles> TabAtkins: You just only render the border-width of the stripes
<myles> leaverou: We can just scale it down. We do it with border-radius, if the total radii overlap, then it gets clamped
<myles> S/clamped/scaled equally across the entire box/
<myles> astearns: That could work, but what about fractional widths? Those go to 0? So you have a 2px white fractional black, 2px white
<myles> TabAtkins: *describes another example*
<myles> fantasai: It’s better than clamping.
<myles> fantasai: It gives you reasonable behavior when you grow and when you shrink
<myles> TabAtkins: We already have mechanisms (percentages) to do this.
<myles> TabAtkins: This allows you from putting in more stripes than you need
<myles> TabAtkins: So if you alternating 1px stripes, you just make a super long one, and no matter how wide the border happens to be, it will just work (in the clamping situation)
<myles> frremy: Animations work better too
<myles> leaverou: If you want to reveal stripes, you could always animate them from 0
<myles> TabAtkins: Not if we scale the values
<myles> leaverou: Non-zero lengths will be scaled down, but if you want to progressively animate,
<myles> TabAtkins: You can alreadya chive accordian effect
<myles> fantasai: What if you want 2px red, 2px white, 2px red. If the border grows, you want the white to grow
<astearns> s/alreadya chive/already achieve/
<myles> fantasai: When you scale up, you want red on the outside, you preserve the red, white, red
<myles> TabAtkins: use min() and max() instead.
<myles> leaverou: What do we do if we want a thinner width than what we have? In fantasai, what if our border is 10px
<myles> TabAtkins: We follow gradients. The last color continues
<myles> fantasai: Or the last color could be transparent
<myles> TabAtkins: But then the border doesn’t look thick
<myles> fantasai: If you want it to be thick, put 1fr at the end
<myles> TabAtkins: When this is used in a 2 dimensional context, then this should be a gradient in some arbitrary direction
<myles> fantasai: I don’t think he testing and implementation effort of making stripes in 2d only for an arbitrary direction makes any sense
<myles> TabAtkins: Here we’re just talking about stretching and scaling
<myles> Rossen: What if we repeat the pattern?
<myles> leaverou: We can introduce that later. Let’s keep it simple.
<myles> fantasai: It answers the question of what to do if you dont’ have enough stripes
<myles> TabAtkins: Don’t be arbitrarily different. Do what gradients do
<myles> fantasai: no
<myles> TabAtkins: no
<myles> TabAtkins: be consistent
<myles> fantasai: this isn’t gradients
<myles> TabAtkins: this is gradients
<myles> fantasai: this is stripes
<myles> leaverou: Gradient color stops are defined absolutely, and there is no fr
<myles> Rossen: stop. Are we trying to add this to backgrounds-4?
<myles> All: yes
<myles> Rossen: We can work this out later
<myles> Rossen: Was there anything else you wanted to go over technically as part of the proposal?
<myles> leaverou: no
<myles> Rossen: Should we add this? Are there still too many open issues for it to be added?
<myles> TabAtkins: Using the stripes functions as a border color and not listifying border color makes more sense than what we already have
<tantek> agreed
<myles> fantasai: This is a better solution. My question: whether to use border stripes or to add this to border color. In general, colors cannot take a 1d image. Any property that ends in -color takes a color. This is not a color, it accepts a 1d image
<myles> astearns: border-color-stripes?
<myles> fantasai: border-stripes is okay
<myles> leaverou: What about the confusing interactions?
<myles> fantasai: its okay.
<myles> astearns: The behaviors fall out of the description
<fantasai> s/The/Some/
<fantasai> astearns: e.g. might answer question of what to do when you run out of stripes
<myles> frremy: That isn’t great because if you pad a border stripes with the border color, the issue is that the border color by default is non transparent, but your stripes may be transparent, then should you display the border-color under the stripes? If you do, you lose the whole point of having transparent stripes
<myles> fantasai: You should show border underneath this property
<myles> leaverou: You often want them to stack, to have a fallback that you don’t have to repeat it in your gradient
<myles> xidorn: I dont’ understand the integration here
<myles> fantasai: border stripes and border color will disappear when you use border-image
<myles> chris: This will need some good examples
<myles> TabAtkins: Or we just do stripes() and we don’t have to deal with this stuff
<myles> leaverou: yep
<myles> fantasai: yep
<myles> leaverou: If we do it with a stripes function and not a separate property, we can extend this to other properties
<myles> fantasai: The other properties need a 0-dimensional color, or a 2-dimensional image. If you applied stripes to those other places, you would need to also specify a direction and turn it into a 2-d thing
<myles> leaverou: i said “if it’s needed” and it may not be needed
<myles> fantasai: We could re-use the syntax. It doesn’t have to be a functional notation
<myles> leaverou: We would have to add a new property for each of those cases
<myles> fantasai: That’s okay
<myles> Rossen: Do we prefer the stripes functions? Or a new property
<myles> fantasai: border-stripe
<myles> TabAtkins: stripes function
<leaverou> stripes function
<tantek> stripes function
<myles> astearns: One reason to have the function is that we noted that listifying properties is confusing. Stripes() makes specifying these stripes more comprehensible. If we use a property, we’re back to a list.
<myles> leaverou: yes
<tantek> s/all a/allow a
<myles> Rossen: Another benefit is you can have the border color and the stripes in the same definition, so you can have your border color as defined green, but you can also define the stripes on top that may or not have green
<myles> leaverou: So you can do them both in the same property
<myles> Rossen: Yes.
<myles> TabAtkins: Why do you need that?
<myles> Rossen: So you can have the last value be transparent, and the default shows through
<tantek> Is stripes a subset of gradients?
<myles> fantasai: The main benefit of the border color being separate is so that they can cascade independently. If theyr’e not cascading independently, then there’s no point
<myles> chris: The original reason for this was because a11y wanted to have a black and a white outline, and outline is defined in term of border. With this syntax, you say “black white” and you’re done.
<myles> chris: Let’s not make a new property.
<myles> tantek: Is stripes just a subset of gradients?
<leaverou> tantek: No, gradients are 2D images. Also, gradient color stops define positions, not widths.
<myles> Rossen: Proposal: adding stripes() to border-color and outline-color
<myles> Rossen: Any additional concerns? Comments that would change this resolution, or objections?
<myles> florian: How does it interact with border-style: double
<myles> fantasai: You clip out the border shape.
<myles> Rossen: Just like it would work with gradients
<myles> leaverou: I think he’s asking about double borders ,not dotted and dashed.
<myles> chris: It’s a clip mask effectively.
<myles> leaverou: Double has two different colors, and inside and an outside
<myles> florian: nope, that’s something else
<myles> leaverou: You’re right
<myles> dbaron: We could say that inset outset groove and ridge would just get treated as solid because you’re picking your colors yourself now and that overrides those styles.
<myles> florian: You can use it as fallback.
<myles> leaverou: right!
<myles> leaverou: I like that
<myles> chris: yeah.
<myles> Rossen: Any objections?
<myles> RESOLVED: Add stripes() to border-color and outline-color
<TabAtkins> tantek: It's *substantially* more work, yes, *and* it doesn't work well with border-radius either.
<myles> Rossen: Do we now publish a new working draft?
<myles> fantasai: I don’t know what state the rest of the draft is in
<myles> leaverou: we’ve published a working draft before, right?
<myles> fantasai: nope
<TabAtkins> (You can't supply separate images for each border, just a single border-image that's 9-sliced to supply all the border regions.)
<myles> Rossen: This is level 4, right?
<myles> leaverou: yes, that needs lots of cleanup
<TabAtkins> And yeah, probably so, which is fine with em.
<myles> Rossen: Let’s not publish
<TabAtkins> Just "gradient(...)"

@SebastianZ
Copy link
Contributor

In my pull request to add stripes() I imagined it to be context sensitive, in contrast to 0-dimensional and 2-dimensional images.

@LeaVerou wrote in the PR:

It has been a long time, but IIRC the resolution of these discussions, we would define 1 dimensional images, and stripes() would just produce a 1 dimensional image. Right now in CSS we have 2d images (gradients, urls etc), and 0 dimensional images (image(<color>)). I see that in this PR, stripes() is defined as its own type, and can only be used in properties that explicitly allow it. We'd like to be a bit more general than that.

@LeaVerou How do you imagine stripes() to work more generally and still cover the use case of multiline borders and outlines? How would painting 1-dimensional images be defined? Should it be also added to <image> like 0-dimensional images were via image()? If so, how would that work together with border-color?

I imagine stripes() or genereally 1-dimensional images to behave differently for different properties. I.e. regarding the use case of multiline borders the stripes are painted around the border.
Though in other contexts they may be interpreted differently. E.g. they could be used in a radial gradient as a replacement for the existing color stop syntax like radial-gradient(stripes(red, yellow, lime, blue)) as an equivalent for radial-gradient(red 25%, yellow 25%, yellow 50%, lime 50%, lime 75%, blue 75%).

If stripes() should be defined as an image (and by that be included in <image>), I'd rather add a way to define it in border-image / border-image-source and disable the slicing there.

Though in any case it still requires to define for each context how the stripes should be painted.

Sebastian

@LeaVerou
Copy link
Member Author

Yes, 1 dimensional images are still <image>. The whole reason they are 1 dimensional is so they can be used in borders, and they are painted alongside the border (like a brush).
I seem to also remember discussing something like how gradient functions would also be augmented to accept a 1d image as the gradient line, so you could do linear-gradient(45deg, stripes(...)). I suppose we'd need to define some handling for when a 1d image is used raw in places that expect a 2d image. E.g. it could be converted to a 2d image via horizontal or vertical repetition (or stretching). 🤷🏽‍♀️

@svgeesus
Copy link
Contributor

How would painting 1-dimensional images be defined?

It is already common to use effectively 1D images on backgrounds (n x 1pixels), duplicating the image to fill the background. This can also be thought of as a brush.

This would be similar, except the brush is moved along the border, perpendicular to each edge.

@tabatkins
Copy link
Member

There's no "natural" way to tile a 1d image into 2d; at minimum, vertical or horizontal tiling are both completely reasonable. We could choose one way arbitrarily if we wanted, I suppose.

@SebastianZ
Copy link
Contributor

SebastianZ commented Feb 15, 2022

Yes, 1 dimensional images are still <image>.

I assume by that you mean to add stripes() to <image> but in properties like border-color and outline-color only stripes() is allowed, not the whole <image> syntax, right?

The whole reason they are 1 dimensional is so they can be used in borders, and they are painted alongside the border (like a brush). I seem to also remember discussing something like how gradient functions would also be augmented to accept a 1d image as the gradient line, so you could do linear-gradient(45deg, stripes(...)).

Ok, so that sounds like we agree on this.

I suppose we'd need to define some handling for when a 1d image is used raw in places that expect a 2d image. E.g. it could be converted to a 2d image via horizontal or vertical repetition (or stretching). 🤷🏽‍♀️

There's no "natural" way to tile a 1d image into 2d; at minimum, vertical or horizontal tiling are both completely reasonable. We could choose one way arbitrarily if we wanted, I suppose.

Tiling or stretching sounds reasonable. Just to be clear we're on the same page here, I have two examples for a 100px by 100px image using stripes(red, yellow, lime, blue):

Horizontal tiling:
stripes(red, yellow, lime, blue) interpreted with horizontal tiling

Vertical tiling:
stripes(red, yellow, lime, blue) interpreted with vertical tiling

Correct?

If so, I'd aim for the same behavior as for linear-gradient(), i.e. draw them from top to bottom, tiling (or stretching) them horizontally (like in the first example above). This will also allow to use it in linear-gradient() as mentioned earlier without surprises.

Sebastian

@SebastianZ
Copy link
Contributor

For the record, I have updated my PR to include the points discussed here.

Sebastian

@SebastianZ
Copy link
Contributor

I didn't hear back on my questions and changes to the PR, so I thought maybe that could quickly be clarified in the next call, because I'd love to finish up this change.

Sebastian

@LeaVerou
Copy link
Member Author

LeaVerou commented Apr 19, 2022

Yes, 1 dimensional images are still <image>.

I assume by that you mean to add stripes() to <image> but in properties like border-color and outline-color only stripes() is allowed, not the whole <image> syntax, right?

These properties should accept a 1 dimensional image, not stripes() specifically. That way, we can add more forms for creating 1 dimensional images in the future or functions that operate on them and not have to update a bunch of grammars. In general, defining input in terms of types is better than defining it in terms of syntax.

I suppose we'd need to define some handling for when a 1d image is used raw in places that expect a 2d image. E.g. it could be converted to a 2d image via horizontal or vertical repetition (or stretching). 🤷🏽‍♀️

There's no "natural" way to tile a 1d image into 2d; at minimum, vertical or horizontal tiling are both completely reasonable. We could choose one way arbitrarily if we wanted, I suppose.

Tiling or stretching sounds reasonable. Just to be clear we're on the same page here, I have two examples for a 100px by 100px image using stripes(red, yellow, lime, blue):

Horizontal tiling: stripes(red, yellow, lime, blue) interpreted with horizontal tiling

Vertical tiling: stripes(red, yellow, lime, blue) interpreted with vertical tiling

Correct?

If so, I'd aim for the same behavior as for linear-gradient(), i.e. draw them from top to bottom, tiling (or stretching) them horizontally (like in the first example above). This will also allow to use it in linear-gradient() as mentioned earlier without surprises.

Just to be clear, stripes() in linear-gradient() (or radial-gradient(), or conic-gradient()) would get the directionality of the gradient. The default directionality we are discussing here only applies when a 1 dimensional image is used by itself in contexts that expect a 2d image. E.g. when you do background: stripes(...);.

@SebastianZ
Copy link
Contributor

Yes, 1 dimensional images are still <image>.

I assume by that you mean to add stripes() to <image> but in properties like border-color and outline-color only stripes() is allowed, not the whole <image> syntax, right?

These properties should accept a 1 dimensional image, not stripes() specifically. That way, we can add more forms for creating 1 dimensional images in the future or functions that operate on them and not have to update a bunch of grammars. In general, defining input in terms of types is better than defining it in terms of syntax.

Good point! I've changed the definition accordingly.

Just to be clear, stripes() in linear-gradient() (or radial-gradient(), or conic-gradient()) would get the directionality of the gradient. The default directionality we are discussing here only applies when a 1 dimensional image is used by itself in contexts that expect a 2d image. E.g. when you do background: stripes(...);.

Yes, that's also how I expected it to work. Thanks for clarifying that! Once the function is added, I'll create a new issue to add it to the gradient functions.

Sebastian

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-background-4] Issues with listifying border-color.

The full IRC log of that discussion <fantasai> topic: [css-background-4] Issues with listifying border-color
<fantasai> github: https://github.com//issues/2532
<fantasai> lea: Let's wait until Sebastian can attend

@fantasai
Copy link
Collaborator

fantasai commented Apr 20, 2022

If we want stripes() to work in 2D, we should define 2D stripes functions, which can re-orient the stripes as appropriate. It's not worth the implementation/testing/documentation effort to have a stripes() function available in all 2D contexts that can only do horizontal stripes. IMHO.

@SebastianZ
Copy link
Contributor

SebastianZ commented Apr 21, 2022

The idea is to let one-dimensional images work in both one-dimensional and two-dimensional contexts.
In 1D contexts like border-color and outline-color they are context-sensitive.
In 2D contexts they are horizontal by default. We could additionally define a 2D variant of that function that allows rotating them. Though as pointed out earlier by @LeaVerou, the plan is to also allow 1D images in gradient functions. So re-orientation would be done via linear-gradient(). Another way to re-orient images (among other image manipulations) is discussed in #6807.

So I wonder whether a separate 2D stripes function would be worth the redundancy. We might remove <1d-image> from direct usage in <image>, though, and only allow to use 1D images in 2D contexts via the gradient functions.

Sebastian

@SebastianZ
Copy link
Contributor

topic: [css-background-4] Issues with listifying border-color
github: https://github.com/[/issues/2532](https://github.com/w3c/csswg-drafts/issues/2532)
lea: Let's wait until Sebastian can attend

Sorry for not attending! I'll try to be there on the next call.

Sebastian

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed listifying border color, and agreed to the following:

  • RESOLVED: Remove <1d-image> from <image> for now, open a separate issue to discuss it
The full IRC log of that discussion <TabAtkins> topic: listifying border color
<TabAtkins> sebastian: several years ago we resolved to add stripes() to let you define several border colors
<TabAtkins> sebastian: Idea was to allow this to be used in other contexts, so we introduced <1d-image> to Images 4.
<TabAtkins> sebastian: Now the feature is mostly complete; there's a PR ready for the specs.
<TabAtkins> sebastian: fantasai asked what to do with <1d-image> in 2d contexts
<TabAtkins> sebastian: Idea was to also allow it in other 2d contexts, so adding <1d-image> to the <image> type
<lea> Can someone link to the PR we are discussing?
<fantasai> PR https://github.com//pull/7029
<TabAtkins> sebastian: fantasai wasn't sure how that should be done. One idea was to add a new function for 2d stripes
<TabAtkins> sebastian: But the idea was that we could have linear-gradient(..., stripes())
<TabAtkins> fantasai: The original proposal is that we allow stripes() in 2d contexts, and default it to "down" (like a linear gradient)
<TabAtkins> fantasai: I dont think it's that useful (you often want something else), and it's not worht the testing/impl cost of doing it for the limited case
<lea> q+
<TabAtkins> fantasai: So if we *do* want the ability to do stripes()-like in 2d, we should have that addressed specifically with a proper 2d striping image, not this limited-direction 1d image
<astearns> ack lea
<TabAtkins> fantasai: Think it's more confusing than helpful otherwise
<TabAtkins> lea: Agree ethere's not much use in 1d-image in 2d contexts, primarily debugging
<TabAtkins> lea: Note tho that we do have 0d images (colors)
<iank_> what is an example of a 0D-image?
<TabAtkins> lea: So feels a little odd we can use 0d and 2d, but not 1d
<TabAtkins> lea: Also don't think we should add a new 2d stripes function; the gradients functions are already used for stripes and could use stripes() for their gradient line
<iank_> ok
<TabAtkins> fantasai: I don't agree that lack of 1d is confusing
<TabAtkins> fantasai: 0d is fine - you don't need any additional params to make it work
<TabAtkins> fantasai: 1d needs additional params - we have to *set* the direction
<TabAtkins> fantasai: for putting it in linear-gradient(), I don't think nesting the functions is easier to read. I think it's better to have a linear-stripes() or wahtever, that's more like how we do functions normally
<TabAtkins> sebastian: But we could use it for all the gradients
<TabAtkins> fantasai: Right, a linear-stripes(), radial-stripes(), conic-stripes(), that's just the same first arg as the gradient func but takes the stripes args after
<TabAtkins> fantasai: syntaxes are perfecty analogous
<TabAtkins> lea: Agree nesting isn't great, but reusing means you get all the gradient controls for free
<TabAtkins> fantasai: Right, we'll just copy the first arg.
<TabAtkins> lea: Do you suggest we abstract it to a separate type? otherwise we have to keep it in sync manually
<TabAtkins> fantasai: They're in the same module, we can do whatever we need. This is editorial, we can do that if we need.
<fantasai> TabAtkins: We already have that problem for the repeating variants as well
<TabAtkins> astearns: So I'm hearing two options - nested stripe() in gradient(), or a separate gradient()
<fantasai> s/gradient/stripes()/
<fantasai> e.g. linear-gradient(..) ~~ linear-stripes(...)
<TabAtkins> lea: One slightly weak arg - if we can use stripe as a gradient line, authors can use a single variable for both borders and backgrounds
<TabAtkins> astearns: You could put the args in a variable and then use them i both
<TabAtkins> lea: You can but it's awkward, same as putting color args in a variable so you can modify the alpha. Awkward
<TabAtkins> sebastian: we could also have a keyword that interprets the following args as stripes
<TabAtkins> fantasai: Or just add a new function name
<lea> q+
<TabAtkins> sebastian: But then we'd have to add 6 new functions
<TabAtkins> fantasai: That's not meaningfully different. We already have 2x3 variants of gradients, if they want stripes we can do another set
<astearns> ack lea
<iank_> Additional functions aren't particularly expensive from an implementation POV.
<TabAtkins> lea: Note that what I was proposing was speccing the gradient line as a 1d image, not as stripes() specifically
<TabAtkins> lea: I do think it's a little werid if we have a bunch of 1d images that we can't use as a gradient line, since the gradient lie is conceptually a 1d image itself
<TabAtkins> fantasai: I don't think of the gradient as being a generic 1d image stretching function. It's for making gradients, which it does. If we need different functions that do different things, we can do that.
<TabAtkins> fantasai: If you wanna do something complicated you can use the gradient functions, if you want stripes you can do stripes()
<TabAtkins> lea: This isn't mutually exclusive either
<TabAtkins> fantasai: I think we're bikeshedding syntax now, I just don't wnat the 1d-as-2d to be in the initial PR
<lea> q+
<TabAtkins> sebastian: So maybe leave that out for now, and only define it for border and outline, which is the initial use-case
<astearns> ack lea
<TabAtkins> sebastian: can discuss 2d contextsw in a separate issue
<TabAtkins> lea: Fine with not accepting, just need to define what happens
<TabAtkins> fantasai: Invalid
<TabAtkins> lea: Okay, that lets us change it in the future
<TabAtkins> astearns: So proposed resolution is to remove the stripes() as <image> for now
<fantasai> Literally, that's what falls out of the spec if we don't add it to <image>
<TabAtkins> astearns: Objections?
<TabAtkins> RESOLVED: Remove <1d-image> from <image> for now, open a separate issue to discuss it
<fantasai> scribeNick: fantasai

@SebastianZ
Copy link
Contributor

Just as reference, I've removed <1d-image> from <image> from my PR as we resolved on and split out the discussion about it into #7241. In addition to this, I've created #7244 to discuss adding stripes as gradients or as gradient-like functions.

Sebastian

SebastianZ added a commit to SebastianZ/csswg-drafts that referenced this issue Oct 9, 2022
jakearchibald pushed a commit to jakearchibald/csswg-drafts that referenced this issue Jan 16, 2023
@SebastianZ SebastianZ changed the title [css-background-4] Issues with listifying border-color [css-borders-4] Issues with listifying border-color Jul 27, 2023
@SebastianZ
Copy link
Contributor

The stripes() function is now defined as part of <image-ID> in CSS Images 4 and used for border-color in CSS Borders 4.

Therefore I believe this can be closed.

Sebastian

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants