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-images-4][css-backgrounds-4] Added stripes() function #7029

Merged
merged 13 commits into from
Nov 5, 2022

Conversation

SebastianZ
Copy link
Contributor

This change is meant to convert the resolution of #2532 into spec. text.

It adds the stripes() function as a generally usable function as discussed in #2532 to CSS Images 4.

Note that I changed the syntax slightly to incorporate the fr unit mentioned in @LeaVerou's description. I did that by adding the <flex> value defined in CSS Grid 1, though the definition there currently focuses on the usage within grid layout. So its description either might need to be changed/generalized or the unit needs to be defined again within CSS Images 4. I'd prefer to generalize it (and maybe even move it to CSS Values 4).

The stripes() function is then used as a replacement for the colors list defined for border-*-color in CSS Backgrounds 4.

Reading through the discussions, a few things were still unclear to me or were discussed but not resolved on.

  1. What's the behavior when the width of the image the stripes() function is used in is smaller or bigger? I've defined that the rest is transparent when the stripes thickness is smaller and that the stripes are clipped when they are bigger than the image, as that seems to be what people were in favor of in the discussion.
  2. Should the stripes be painted inwards or outwards? For now I kept the definition of "starting outwards", though to me it seems a bit counter-intuitive that the borders go inwards. Also, the wording may be clarified further.
  3. Should there be a description of how stripes (or generally border-color) interact with border-style? Clipping was mentioned in the discussion, also treating inset, outset, groove, and ridge as solid.

Also note that this change is based on #7014, because without those changes Bikeshed won't compile the spec.

Sebastian

@svgeesus
Copy link
Contributor

@LeaVerou @fantasai we resolved to add stripes() ages ago and the edit was not made, this PR looks like a good way forward?

@LeaVerou
Copy link
Member

Hi Sebastian,

Thank you for working on this.
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.

@SebastianZ
Copy link
Contributor Author

Thank you for reviewing the PR! There are obviously some open questions, so let's continue the discussion in the issue before we continue with this PR.

Sebastian

@SebastianZ SebastianZ force-pushed the stripes-function branch 2 times, most recently from c1ce848 to 119070c Compare March 16, 2022 10:06
@SebastianZ
Copy link
Contributor Author

@LeaVerou @tabatkins I went ahead and interpreted your statements in the issue to make the relevant changes. That means, I added <stripes()> to <image> and changed its description.

I also added it to outline-color as previously resolved on. I've kept the reference to <flex> for now. Though as pointed out earlier, I think its definition should be generalized and moved to a more general place to make it clear that it doesn't only apply to grid layout anymore.

I am awaiting your feedback on these changes.

Sebastian

@SebastianZ
Copy link
Contributor Author

As noted by @LeaVerou, I've now put stripes() behind a <1d-image> type, so it can easily be reused and extended.

Open questions:

  • Is it ok to allow different orders in the syntaxes?
  • What to do with <flex>?

Sebastian

@LeaVerou
Copy link
Member

I don't understand either of the two questions, could you please elaborate?

@SebastianZ
Copy link
Contributor Author

* Is it ok to allow different orders in the syntaxes?

I used the double pipe in the syntaxes, i.e. <color> || <1d-image>. This allows the two values to be in any order.

That allows to specify something like border-color: red stripes(white, silver) stripes(white, silver) yellow lime stripes(black, gray) blue;.

We might use juxtaposing instead, i.e. <color> <1d-image> to force the order of first <color> then <1d-image>.

* What to do with `<flex>`?

As noted in a previous comment, I reused <flex> from CSS Grid 1 because I agree with you that it fits very well this use case.

Though, as it is now used in two completely different places, should it's description be generalized and be moved somewhere else? And if so, should that be done in this PR already?

Sebastian

@LeaVerou
Copy link
Member

* Is it ok to allow different orders in the syntaxes?

I used the double pipe in the syntaxes, i.e. <color> || <1d-image>. This allows the two values to be in any order.

That allows to specify something like border-color: red stripes(white, silver) stripes(white, silver) yellow lime stripes(black, gray) blue;.

We might use juxtaposing instead, i.e. <color> <1d-image> to force the order of first <color> then <1d-image>.

Oh no, you need to use a single pipe: [ <<color>> | <<1d-image>> ]. It's a <color> OR <1d-image> but not both. It doesn't make sense to have border-color: red stripes(white, silver) stripes(white, silver) yellow lime stripes(black, gray) blue; because you can't tell what is for what side.

* What to do with `<flex>`?

As noted in a previous comment, I reused <flex> from CSS Grid 1 because I agree with you that it fits very well this use case.

Though, as it is now used in two completely different places, should it's description be generalized and be moved somewhere else? And if so, should that be done in this PR already?

Yeah, it should go to css-values. @fantasai @tabatkins ?

@tabatkins
Copy link
Member

tabatkins commented Apr 20, 2022

Yeah we can move <flex> out to the general V&U spec now that it's being used in more than just Flexbox. (I'll wait for merging of this PR tho.)

@LeaVerou
Copy link
Member

Yeah we can move <flex> out to the general V&U spec now that it's being used in more than just Flexbox. (I'll wait for merging of this PR tho.)

Great, should we call it something else in that case? <fraction>?

Copy link
Collaborator

@fantasai fantasai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks pretty good. Posted some specific things to fix.

Also, the line-breaking convention for our specs is https://rhodesmill.org/brandon/2012/one-sentence-per-line/ (This is why the lines look so ragged, there's a method to the madness.)

(You might also find https://lists.w3.org/Archives/Public/spec-prod/2018OctDec/0011.html a useful read as background context, though nothing else there is particularly relevant to this PR.)

css-backgrounds-4/Overview.bs Outdated Show resolved Hide resolved
css-backgrounds-4/Overview.bs Outdated Show resolved Hide resolved

The stripes are painted above a given <<color>>. This allows the <<color>>
value to serve as a fallback, so any transparent stripes let the color
shine through.

When interpolating between borders with the same number of colors,
interpolation is performed individually per color band as <a href="https://www.w3.org/TR/css3-transitions/#animtype-color">color</a>.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interpolation should probably be defined in the definition of the stripes() function, rather than here. And it should match what we do for gradients.

Copy link
Contributor Author

@SebastianZ SebastianZ May 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've moved it to the "Interpolation" section in CSS Images 4 and tried to align its definition with the one for gradients. @fantasai As those changes are bigger, please have a detailed look at it and let me know whether something needs to be changed!

Sebastian

css-images-4/Overview.bs Outdated Show resolved Hide resolved
css-images-4/Overview.bs Outdated Show resolved Hide resolved
css-images-4/Overview.bs Outdated Show resolved Hide resolved
css-images-4/Overview.bs Show resolved Hide resolved
css-ui-4/Overview.bs Outdated Show resolved Hide resolved
css-backgrounds-4/Overview.bs Outdated Show resolved Hide resolved
css-backgrounds-4/Overview.bs Outdated Show resolved Hide resolved
@tabatkins
Copy link
Member

I've done what turned out to be a decent bit of rearranging and rewording on the Images part. Largely editorial; the only normative changes are to handle sums of flexes < 1 the same way flexbox does, and define the painting area when used as a 2d image.

@SebastianZ
Copy link
Contributor Author

SebastianZ commented Apr 21, 2022

* Is it ok to allow different orders in the syntaxes?

I used the double pipe in the syntaxes, i.e. <color> || <1d-image>. This allows the two values to be in any order.
That allows to specify something like border-color: red stripes(white, silver) stripes(white, silver) yellow lime stripes(black, gray) blue;.
We might use juxtaposing instead, i.e. <color> <1d-image> to force the order of first <color> then <1d-image>.

Oh no, you need to use a single pipe: [ <<color>> | <<1d-image>> ]. It's a <color> OR <1d-image> but not both. It doesn't make sense to have border-color: red stripes(white, silver) stripes(white, silver) yellow lime stripes(black, gray) blue; because you can't tell what is for what side.

I deliberately chose to allow both, so <color> serves as a fallback, as you noticed in an inline comment. border-color is one place where slashes would make it easier to distinguish between the different values like we have it for grid-area. So we could also express the syntax as:

<<color>>{1,4} | [ <<color>>? <<1d-image>>? ]! [ / [ <<color>>? <<1d-image>>? ]! ]{0,3}

That means, authors have to add the slashes when using <1d-image>, while the existing <color>-only syntax without slashes is still supported as legacy syntax. Applied to my example above, this would then look like

border-color: red stripes(white, silver) / yellow stripes(white, silver) / lime stripes(black, gray) / blue;

Sebastian

@SebastianZ
Copy link
Contributor Author

Yeah we can move <flex> out to the general V&U spec now that it's being used in more than just Flexbox. (I'll wait for merging of this PR tho.)

Great, should we call it something else in that case? <fraction>?

As even Tab obviously mixed it up being part of Flexbox and not Grid, I'd say yes. 😉 Though I don't have a strong opinion on that.

And I agree with him that this should be done in a separate PR.

Sebastian

@SebastianZ
Copy link
Contributor Author

Overall looks pretty good. Posted some specific things to fix.

Also, the line-breaking convention for our specs is https://rhodesmill.org/brandon/2012/one-sentence-per-line/ (This is why the lines look so ragged, there's a method to the madness.)

(You might also find https://lists.w3.org/Archives/Public/spec-prod/2018OctDec/0011.html a useful read as background context, though nothing else there is particularly relevant to this PR.)

Thanks for the links! I'll correct the line-breaking.

Sebastian

@SebastianZ
Copy link
Contributor Author

I've done what turned out to be a decent bit of rearranging and rewording on the Images part. Largely editorial; the only normative changes are to handle sums of flexes < 1 the same way flexbox does, and define the painting area when used as a 2d image.

I missed that when answering the previous comments. @tabatkins Thank you for the changes! With those you obviously already covered a few things noted by @fantasai.

I'll incorporate the rest of the changes and we can discuss the points that are still open afterwards.

Sebastian

@LeaVerou
Copy link
Member

* Is it ok to allow different orders in the syntaxes?

I used the double pipe in the syntaxes, i.e. <color> || <1d-image>. This allows the two values to be in any order.
That allows to specify something like border-color: red stripes(white, silver) stripes(white, silver) yellow lime stripes(black, gray) blue;.
We might use juxtaposing instead, i.e. <color> <1d-image> to force the order of first <color> then <1d-image>.

Oh no, you need to use a single pipe: [ <<color>> | <<1d-image>> ]. It's a <color> OR <1d-image> but not both. It doesn't make sense to have border-color: red stripes(white, silver) stripes(white, silver) yellow lime stripes(black, gray) blue; because you can't tell what is for what side.

I deliberately chose to allow both, so <color> serves as a fallback, as you noticed in an inline comment. border-color is one place where slashes would make it easier to distinguish between the different values like we have it for grid-area. So we could also express the syntax as:

<<color>>{1,4} | [ <<color>>? <<1d-image>>? ]! [ / [ <<color>>? <<1d-image>>? ]! ]{0,3}

That means, authors have to add the slashes when using <1d-image>, while the existing <color>-only syntax without slashes is still supported as legacy syntax. Applied to my example above, this would then look like

border-color: red stripes(white, silver) / yellow stripes(white, silver) / lime stripes(black, gray) / blue;

Sebastian

What kind of fallback? If stripes() is not supported, the entire declaration would be dropped, including the color.
If we want stripes() to accept an optional color to paint the stripes over, it should probably be part of the syntax for stripes(), not in each individual property's grammar as separate tokens. @fantasai any thoughts on this?

@tabatkins
Copy link
Member

I don't know what the "color to paint the stripes over" is for, tbh.

@LeaVerou
Copy link
Member

I don't know what the "color to paint the stripes over" is for, tbh.

No idea, but I assume that's what @SebastianZ intended for the fallback, a color to paint underneath any semi-transparent stripes. FWIW I don't think it's that necessary and complicates the syntax, so I'd be fine removing it.

@SebastianZ
Copy link
Contributor Author

SebastianZ commented Apr 21, 2022

I don't know what the "color to paint the stripes over" is for, tbh.

No idea, but I assume that's what @SebastianZ intended for the fallback, a color to paint underneath any semi-transparent stripes. FWIW I don't think it's that necessary and complicates the syntax, so I'd be fine removing it.

Yes, the meaning of this "fallback color" was to let the color is drawn below any (semi-)transparent stripes. So, basically the same interaction as background-color with background-image. The idea behind that was that authors might expect that the <color> value still has an influence even when using stripes().

Though I'm happy to change the syntaxes to <color> | <1d-image> if we agree that this won't be the case and there are only use cases to have either <color> or stripes().

If we decide to use the either-or syntax instead, we should also clarify whether it's ok to stick with "transparent black" as fill color. See also @fantasai's related comment.

Sebastian

@SebastianZ
Copy link
Contributor Author

As the comment list on this PR got quite long, let me summarize the pending points:

@fantasai @tabatkins Could you please give this another review so the changes can be merged?

Sebastian

@SebastianZ SebastianZ requested review from tabatkins and fantasai and removed request for LeaVerou, tabatkins, fantasai and bert-github October 9, 2022 19:48
Animation type: see prose
</pre>

<pre class="propdef shorthand">
Name: border-color
Value: <<color>>#{1,4}
Value: [ <<color>> | <<1d-image>> ]{1,4}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tabatkins @fantasai What do you think about my suggestion to distinguish the values for the different borders by adding slashes between them like in grid-area?

This makes the syntax more future proof, in my opinion.

Sebastian

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For reference, here's the suggested syntax again:

<<color>>{1,4} | [ <<color>>? <<1d-image>>? ]! [ / [ <<color>>? <<1d-image>>? ]! ]{0,3}

And here's an example using that syntax:

border-color: stripes(white, silver) / stripes(white, silver) / stripes(black, gray) / blue;

Comment on lines 1920 to 1928
The function represents a 1-dimensional image generated by a list of colors
and an optional thickness for each of them.

A <<percentage>> or <<flex>> value refers to the total length of the image
in the used context.
The <<percentage>> must be between ''0%'' and ''100%'' inclusive;
any other value is invalid.

If the thickness of a stripe is omitted, it is interpreted as ''1fr''.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is still needed but please let me know if it is!

css-ui-4/Overview.bs Outdated Show resolved Hide resolved
Comment on lines +1975 to +1976
If used generically as an <<image>>,
the |painting area| is the height of the [=concrete image size=].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does "If used generically as an <image>" mean, if <1d-image> is no longer an <image>?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was just a left-over. I've removed the whole paragraph now as it didn't add any additional information anymore.

Thanks for the hint!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You removed another used generically as an <<image>>, but not this one.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SebastianZ SebastianZ merged commit 426ae64 into w3c:main Nov 5, 2022
@SebastianZ
Copy link
Contributor Author

I went ahead and merged the changes now as I believe all feedback was addressed and I waited for half a year for review.

I'll create separate issues for my suggestion to change the syntax of border-color and for generalizing the <flex> value. For reference, see my previous comment.

If there is still anything left, please let me know and I'll change it.

Sebastian

If the thickness is omitted,
it defaults to ''1fr''.

In each entry, a <<percentage>> is relative to the |painting area|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is very confusing, the "painting area" is never defined but since it's an area it seems to be 2D. How to resolve a 1D <length-percentage> relatively to a 2D area?

Should this refer to the "length of the paint line" instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +1975 to +1976
If used generically as an <<image>>,
the |painting area| is the height of the [=concrete image size=].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You removed another used generically as an <<image>>, but not this one.


2. Neither image uses a combination of <<length>>, <<percentage>>, and <<flex>> stripes.

If the two image satisfy both constraints,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the two images

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

first match each stripe in the start image
to the corresponding stripe at the same index in the end image.
Then, for each pair of stripes,
interpolate the <a href="https://www.w3.org/TR/css3-transitions/#animtype-length">thickness</a>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How to interpolate a <length-percentage> with a <flex>?

Rather than checking that each image doesn't mix different types, should the requirement be that each pair of matched stripes have the same type?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Successfully merging this pull request may close these issues.

6 participants