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-shapes-2] Consider allowing <position> for the from and some other points #10644

Open
smfr opened this issue Jul 30, 2024 · 11 comments
Open

Comments

@smfr
Copy link
Contributor

smfr commented Jul 30, 2024

Splitting from #5841.

The shape() function in CSS Shapes Level 2 is specified with the from position being a coordinate-pair, but this doesn't allow for keywords like top left.

Similarly, you can't use <position> arguments as the to point or control points on the various commands. Maybe we could allow if it's an absolute (to) point. This would enable very natural shapes like shape(from center top, line to right center, line to center bottom, line to left center, close).

@noamr
Copy link
Collaborator

noamr commented Jul 31, 2024

Considering also #10649 , one option for using is to not use a keyword for this at all, and to change the curve/smooth syntax to give all the points, with an option to switch from by to to in the middle (but not the opposite):

clip-path: shape(from top left,
  hline by 100px,
  curve by 100px 50px / to right bottom,
  curve by 50px 50px / 10% 20% / var(--x) var(--y),
  curve by 50px 50px / 10% 20% / to bottom 50%,
  smooth to bottom left / 0 0,
)

It's probably nonsensical/confusing to give an absolute position as a control point and then continue to a relative one for the next control point or end point.

Also added / as a separator because having lots of lengths in succession can be confusing

@tabatkins
Copy link
Member

Hm, so is that back to a definite order for the points? aka control points first, then destination at the end? I'm not a fan of the implicit by/to, matching whatever's earlier behavior - I don't think it's obvious that someone would want to switch from by to to mid-command, but never the other way. Plus, if we're no longer putting the entire command in one mode (in which case the by/to is just another keyword component for the whole curve, effectively), I think it's clearer for each point to state what mode it's in. It's only two characters, after all.

@noamr
Copy link
Collaborator

noamr commented Aug 5, 2024

Right, I think having the control points first makes more sense given relative positions (by) and it was a mistake to allow any order. It's confusing to go all the way to the end point and then jump to the control points.

I'm also fine with keeping by/to for every point. Something like this?

clip-path: shape(from top left,
  hline by 100px,
  curve by 100px 50px / to right bottom,
  curve by 50px 50px / by 10% 20% / by var(--x) var(--y),
  curve by 50px 50px / by 10% 20% / to bottom 50%,
  smooth to bottom left / to 0 0,
)

@tabatkins
Copy link
Member

I disagree it's a mistake; it reads perfectly fine, to me, to say you curve "to" some position, "using" some control points, versus curving "using" some points "to" some destination. Both seem fine in English, and read reasonably in code I think. In your code, for example, I think it would look reasonable to have all the commands specify their endpoint immediately so the vertical reading gives a point-to-point path, and the stuff after the endpoints specifies command-specific info. We allow that in arc, after all. (But I also don't feel strongly about this and am fine with a fixed order - either one - if doing so makes some other issues work a lot better.)

And, hm, if we have enforced keywords, that solves the "too many lengths in a row" by itself:

clip-path: shape(from top left,
  hline by 100px,
  curve by 100px 50px to right bottom,
  curve by 50px 50px by 10% 20% by var(--x) var(--y),
  curve by 50px 50px by 10% 20% to bottom 50%,
  smooth to bottom left / to 0 0,
)

But if we continued to allow reordering by requiring using, then:

clip-path: shape(from top left,
  hline by 100px,
  curve using by 100px 50px to right bottom,
  curve using by 50px 50px using by 10% 20% by var(--x) var(--y),
  curve using by 50px 50px using by 10% 20% to bottom 50%,
  smooth to bottom left / to 0 0,
)

Hm, kinda hate that, gotta say.

@noamr
Copy link
Collaborator

noamr commented Aug 6, 2024

Yea, using by or with by doesn't read well... and my issue with having the control points after the end point was not so much about readability, but that it's ambiguous where by starts from, the end point or the start point? e.g.
you have to read the docs to understand what curve by 100% 100% using -10px -10px does.

I guess if we allow segh / segv like in #10667 it does make a bit more sense to have the end point first, but I think it's a solvable problem. e.g.:

curve by 10segh 30segv by 80px 80px can be interpreted as seg=0,0 when computing the next point, and then recomputed to the actual segment width/height when computing the control point.

So until now I don't see a better alternative than:

  • ordered, control points first
  • explicit by/to with every point
  • with by, each control point starts from the previous point that is not seg***.

@smfr
Copy link
Contributor Author

smfr commented Sep 25, 2024

I think we need to collapse all the shape syntax issues together:

@smfr
Copy link
Contributor Author

smfr commented Sep 25, 2024

I'm not a fan of "control points first". Mentally, you describe the point you want to get to, and then how to get there. I think SVG paths made a mistake with the "c1x c1y c2x c2y x y" ordering.

@smfr
Copy link
Contributor Author

smfr commented Sep 25, 2024

Can't we use from start and from end to deal with the relative control points? I think curve by 20px 20px using 10px 10px 15px 15px in the current syntax could be curve by 20px 20px with 10px 10px from start / 15px 15px from start.

@tabatkins
Copy link
Member

tabatkins commented Oct 1, 2024

Yeah, that looks pretty good, imo. So from start/from end would be relative positions; does that mean that omitting the coord would be absolute by default? Or do we still want to implicitly match the endpoint's relative mode when omitted, and have something like from origin to indicate absolute-ness?

That is, curve by 20px 20px with 10px 10px / 15px 15px would make both of the control points implicitly from start, while curve to 20px 20px with 10px 10px / 15px 15px would make them implicitly from origin?

I do prefer that second one; I think having everything using the same coord system is usually what you want, so it should be the easiest thing to say.

@noamr
Copy link
Collaborator

noamr commented Oct 1, 2024

Yeah, that looks pretty good, imo. So from start/from end would be relative positions; does that mean that omitting the coord would be absolute by default? Or do we still want to implicitly match the endpoint's relative mode when omitted, and have something like from origin to indicate absolute-ness?

That is, curve by 20px 20px with 10px 10px / 15px 15px would make both of the control points implicitly from start, while curve to 20px 20px with 10px 10px / 15px 15px would make them implicitly from origin?

I do prefer that second one; I think having everything using the same coord system is usually what you want, so it should be the easiest thing to say.

Yea I think that from start / from origin allows you to change the coordinate affinity, but the default retains the initial affinity. I did think though that by default by would imply "from last point provided", but perhaps from start makes more sense as a default.

@tabatkins
Copy link
Member

Yeah, the by keyword is already relative to the start point (aka from start), so it makes sense to me to carry that forward as a default for the other points (and similar, to is from origin).

And having the from X specifier come after the point makes it easier to read it as applying to just the one point, so having the default always draw from the by/to keyword (rather than the mode of whatever the preceding point is) makes more sense to me (and, I think, works better for future-compat with whatever new commands we add).

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

3 participants