Skip to content

[css-shapes] Overload path() for CSS-y SVG path syntax instead of taking up shape() #10647

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

Open
LeaVerou opened this issue Jul 31, 2024 · 15 comments
Labels

Comments

@LeaVerou
Copy link
Member

Apparently WebKit is implementing shape() so this is somewhat urgent.

SVG paths don't have the best ergonomics, and there have been long discussions about how to improve on the ergonomics as well, not just expose the existing model with CSS syntax. See #9889 for one discussion on this

Can we perhaps overload path() for the API that is mapped closely to SVG paths so that shape() is free to host something better without having to worry about disambiguation?

The current signature of path() is very weird anyway, so it would be good to make it sensible.

@smfr
Copy link
Contributor

smfr commented Aug 1, 2024

Do you thoughts for what a future shape() might be used for?

I think we'll be able to map SVG paths to the new shape syntax losslessly, but will not be able to map in the other direction.

@astearns astearns moved this to TPAC/FTF agenda items in CSSWG Agenda TPAC 2024 Sep 13, 2024
@astearns astearns moved this from TPAC/FTF agenda items to Regular agenda items in CSSWG Agenda TPAC 2024 Sep 13, 2024
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-shapes] Overload `path()` for CSS-y SVG path syntax instead of taking up `shape()` .

The full IRC log of that discussion <dbaron> lea: As mentioned many times, SVG paths don't have the best ergonomics.
<dbaron> lea: Have been long discussions about improving.
<dbaron> lea: And not just expose the exsiting model with CSS syntax. Though there's value in exposing existing model in CSS syntax.
<TabAtkins> q+
<dbaron> lea: Seems like we're trying to do both with shape() function.
<dbaron> lea: But we already have a path() function which has a very strange syntax for CSS.
<dbaron> lea: It seems reasonable to me that we should overload that function to harmonize with rest of CSS functions
<dbaron> lea: That frees up shape() to do what we want, we don't have to be consistent with SVG.
<dbaron> lea: We don't have to be consistent with SVG at all without being bound by legacy/baggage of SVG.
<dbaron> lea: Seems like it's 2 birdds with one stone. Make path() a reasonable function and free up shape() to do something more reasonable without baggage().
<dbaron> lea: Lea is that path() is CSS specification of SVG paths whose model stays close to SVG aths, and shape() can be whatever.
<dbaron> TabAtkins: I don't agree with this.
<dbaron> TabAtkins: I don't think we need to do more reinvention while keeping close to SVG.
<dbaron> TabAtkins: I don't think the SVG starting point is particularly holding us back.
<dbaron> TabAtkins: what SVG does is mostly fine.
<lea> q?
<noamr> q+
<lea> q+
<dbaron> TabAtkins: We can engineer around the awkward bits. curve sucks but we can do better curvens.
<Rossen9> ack TabAtkins
<dbaron> TabAtkins: I don't think we're limited in a meaningful way.
<dbaron> TabAtkins: I don't like when functions have significantly divergent grammar paths.
<dbaron> TabAtkins: It's clearer when path() is the SVG syntax and shape() is the CSS nytax, more teachable.
<dbaron> TabAtkins: I like the current approach and think we shouldn't change.
<Rossen9> ack noamr
<dbaron> noamr: I t hink most useful thing about path() is that you can paste in strings from an SVG authoring tool.
<dbaron> noamr: It's a feature that can stay the way it is
<dbaron> noamr: Let sleeping dogs lie.
<Rossen9> ack lea
<dbaron> lea: I'm not proposing we drop the string argument of path(), just overload it.
<dbaron> lea: If you don't think the current shape() is a sigificant departure from SVG, then maybe we should just stick with path().
<dbaron> lea: All the other SVG shapes have CSS functions, path() is the odd one out that only takes a string.
<dbaron> lea: We should fix path to have a better design. Then question of if we need a new function. But I think we do -- fix how we specify control points, how we ??, fix arcs.
<dbaron> lea: We've discussing many improvements, many of which we can't backport.
<dbaron> TabAtkins: 2 things to repsond to -- all other SVG shapes are just elemnts with attributes, there's no data format to port over to CSS.
<dbaron> TabAtkins: path is the execption where the data are in a string
<dbaron> lea: polygon!
<dbaron> TabAtkins: Aside from the whitespace rules it's identical to CSS grammar.
<dbaron> TabAtkins: path() has nontrivial syntax that can be dropped into other contexts. Taking that is still useful.
<lea> q?
<lea> q+
<dbaron> TabAtkins: but also useful to take advantage of CSS and its gfull abilities.
<dbaron> TabAtkins: Second, I don't understand how points about gradually making shape better than what SVG can do suggest putting it into path(). If anyhting, I think shows separate function is better to underline that it's different.
<Rossen9> ack lea
<dbaron> lea: That's not what I was suggesting. If was saying that if we're significantly different it should be a separate function, but there's still value in a CSS serialization of path.
<dbaron> lea: I think you could do a CSS-if-ication of path syntax and allow that in path().
<dbaron> lea: Having to reach for a different function that has nothing to do with paths makes it difficult to learn.
<dbaron> TabAtkins: I don't see great value to users in a direct cssification of the path syntax.
<dbaron> TabAtkins: if people are using path syntax, they want to ureuse it, just take te string and go.
<dbaron> TabAtkins: If they're rewriting then rewriting into shape syntax which gives substantially more ???.
<dbaron> lea: I don't think it should be mapped that closely, but I'd take thit af itis' the only way.
<dbaron> lea: ???
<dbaron> lea: Taking a path from SVG and sticking it into CSS has limited utility because SVG paths are fixed sizes... current path odesn't deal with percentages, units.
<dbaron> TabAtkins: it's well defined
<dbaron> lea: It's well defined but not useful.
<dbaron> TabAtkins: are you asking to drop path() entirely?
<dbaron> lea: no
<dbaron> lea: I'm saying what either what we have now in shape() in which case it should be in the path() function, or it's far enough and we should improve the path() function and have the shape() function separately.
<dbaron> TabAtkins: I agree with second point except I don't think there's value with improving path syntax and I think we should stick with current approach.
<dbaron> Rossen9: I think we should take this back to the issue. Two contrasting opinions here.
<noamr> I think this proposal should be a bit more specific
<dbaron> Rossen9: Sounds like we should get closer together on the issue before trying to resolve.

@ydaniv
Copy link
Contributor

ydaniv commented Sep 27, 2024

I think it's good that path() and <path> are interchangeable. If anything, I'd prefer that in the future we would get a <shape> in SVG (setting aside how realistic that is for now).

@astearns astearns removed the Agenda+ label Sep 27, 2024
@jyasskin
Copy link
Member

I don't know anything about the need to improve the shape language in the future, but I'm concerned about the sentence in the spec that "The shape() function defines a path". shape() should define a shape, and path() should define a path.

These naming issues are sometimes inevitable, but it seems like this one isn't.

@noamr
Copy link
Collaborator

noamr commented Jan 27, 2025

I don't know anything about the need to improve the shape language in the future, but I'm concerned about the sentence in the spec that "The shape() function defines a path". shape() should define a shape, and path() should define a path.

Sure, we can change the wording.

@noamr
Copy link
Collaborator

noamr commented Jan 27, 2025

#9889 is closed and we have no specific proposals being discussed around doing something different with path(). We've implemented shape() in chromium as well and almost ready to ship. @LeaVerou do you still want to pursue this? If not, can we close this issue?

@LeaVerou
Copy link
Member Author

Well, I still think path() only supporting a <string> argument is inconsistent with all other shape functions, so no, I'm not in favor of closing this with no WG resolution.

@noamr
Copy link
Collaborator

noamr commented Jan 27, 2025

Well, I still think path() only supporting a <string> argument is inconsistent with all other shape functions, so no, I'm not in favor of closing this with no WG resolution.

Are you seeing this as something that should affect the direction we ended up taking with shape()?
shape() is close to being shipped in two engines so it would be good to get clarity on this issue.

Referring to the initial comment on the issue:

Apparently WebKit is implementing shape() so this is somewhat urgent.

@LeaVerou
Copy link
Member Author

I think it would be fine if that direction ended up becoming a path() overload.

@noamr
Copy link
Collaborator

noamr commented Jan 28, 2025

I think it would be fine if that direction ended up becoming a path() overload.

So the issue was not so much with the details of 'shape()', but with giving it a new name rather than exposing it as a 'path' overload? I don't have a strong opinion about this, happy to hear from others or resolve at the WG one way or another.

@noamr
Copy link
Collaborator

noamr commented Jan 28, 2025

btw I think what would make path useful is not overloading it to be like shape, but to give it a viewBox argument and allow it to scale to the reference box. I find that having non-scalable SVG is not the most useful, but it's less about the fact that it's an unmodified SVG string, which is useful for SVG interop.

@smfr
Copy link
Contributor

smfr commented Jan 28, 2025

I think the shape syntax fulfills many of the issues raised in #9889, but maybe not all of them. I'd like to see a list of potential features of a separate shape function that are currently not supported, so we can judge whether it's worth saving shape() for a different thing in future.

@noamr
Copy link
Collaborator

noamr commented Jan 28, 2025

I think the shape syntax fulfills many of the issues raised in #9889, but maybe not all of them. I'd like to see a list of potential features of a separate shape function that are currently not supported, so we can judge whether it's worth saving shape() for a different thing in future.

We can also have potential shape() overloads in the future. But I don't think that means that the current shape() proposal should be a path() overload. shape() is a set of commands that are a recipe to generating a path given a context (e.g. custom CSS properties, the reference box). If we can maintain these definitions, we can expand both in different directions using overloads.

Also, from a discoverability perspective, I like the distinction between something that tries to maintain the SVG path syntax and something that's not bound to it, even if partially interoperable.

@noamr
Copy link
Collaborator

noamr commented Feb 11, 2025

For the weekly meeting, the discussion is about whether to keep the shape() name for shape, or change it to be an overload of path.

I am in favor of keeping the separate shape() word, to maintain the expectation that path is directly related to SVG. See #11628. A shape() is a set of rules that end up creating a path().

Responding to #10647 (comment), there could be future enhancement to shape() in the future, but nothing is stopping us from overloading shape() at that point if needed.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-shapes] Overload `path()` for CSS-y SVG path syntax instead of taking up `shape()` , and agreed to the following:

  • RESOLVED: shape() remains as-is, spec subset that is more tightly tied to SVG <path> for a path() overload
The full IRC log of that discussion <lea> on it
<noamr> yay
<TabAtkins> lea: there's been dsicussion around making paths easier in CSS
<TabAtkins> lea: so far it's still very closely mapped to SVG paths
<TabAtkins> lea: taking the design of paths, with its concepts, segments, commands, args, and supporting a CSS syntax for them
<TabAtkins> lea: that's what we've done with the other shapes already too
<TabAtkins> lea: polygon(), circle(), etc
<noamr> q+
<kbabbitt> q-
<Rossen6> ack kbabbitt
<TabAtkins> lea: so it seems weird that we leave path() as this weird function that just takes a string of SVG, and make a different shape() function for the cssy one
<TabAtkins> lea: less discoverable and inconsistent
<TabAtkins> lea: when i filed this issue, thought we might leave shape() for another feature
<TabAtkins> lea: but now I think overloading path() is better even disregarding that
<Rossen6> ack noamr
<TabAtkins> noamr: shape() does already ahve a few features that SVG doesn't, or does it differently
<TabAtkins> noamr: order of control points, you can combine rel/abs in the same shape
<TabAtkins> noamr: now adding corner shapes, that'll probably get added to shape()
<lea> q+ You can combine relative and absolute in the same shape in `<path>` too? Also, the idea was that we'd eventually backport corner rounding to `<path>` too
<TabAtkins> noamr: but also, I think path() can still be extended to make it actually usable, by giving it viewbox and fit
<lea> q_
<lea> q+
<TabAtkins> (lea, he meant combining in one command)
<TabAtkins> noamr: i don't have a strong opposition to calling this path(), but I do think they're a bit different
<TabAtkins> noamr: shape() is a recipe to create a shape
<TabAtkins> noamr: once you combine the shape with a reference box, the path you get can be vastly different from what svg coudl make
<TabAtkins> noamr: so i think keeping shape() separate makes sense as it's a recipe to create paths rather than the path itself
<TabAtkins> noamr: also the mental model fo path() is closely related to SVG, and if it's extended as I propose it'll stay close to SVG
<TabAtkins> lea: you mention rounding
<Rossen6> ack lea
<TabAtkins> lea: i think we eventually want to backport some of these improvement to path, at least those that are feasible
<TabAtkins> lea: but in general i think a better shape function is useful, it just worries me that we're leaving this gap
<TabAtkins> lea: authors will expect a CSS syntax for <path> like the other functions/elements have, and they'll find path() and shape() is a different thing
<noamr> q+
<Rossen6> ack noamr
<TabAtkins> noamr: we dont' have proposals to backport the new stuff to SVG, or filling in gaps
<smfr> +1
<TabAtkins> noamr: so right now, is this better to give a new name with the intention that it'll continue growing, or should we name it path() and say it's a CSS-ified <path> but with extensions
<lea> q+
<TabAtkins> noamr: I think it ends up just being a name thing
<TabAtkins> noamr: No strong opinion, but weak pref for shape()
<lea> q?
<smfr> q+
<Rossen6> acl lea
<TabAtkins> lea: replying to "no proposals for backport"
<Rossen6> ack lea
<TabAtkins> lea: when designing syntax, it's not just about what proposals exist now, bute what future direciton the language might go to
<TabAtkins> lea: that's the challenge with standards
<TabAtkins> lea: things like backporting rounding to <path> is a low-hanging fruit I think we could end up with
<TabAtkins> lea: so we shoudl plan around it
<TabAtkins> q+
<TabAtkins> smfr: I feel more strongly than Noam that shape() is right
<TabAtkins> smfr: it's more discoverable, search for "css shape function" you'll find it
<TabAtkins> smfr: I see it being used a lot with future border-shape, so shape() seems natural
<TabAtkins> smfr: i sympathize with lea that we shoudl design for the future, but we can choose a different name in the feuture if needed
<Rossen6> ack smfr
<Rossen6> ack TabAtkins
<noamr> TabAtkins: re any backporting/future extensions of path(), to the extent we want to backport anything into SVG, we'll still be spelling it in the SVG way and would probably want to maintain this in-string capability
<lea> q+
<noamr> TabAtkins: if we don't backport to SVG, but just add to the string that SVG defines, it would look quite different from what shape is doing, because you can't drop things as easily into a command because of the parsing
<noamr> TabAtkins: anything we add to SVG would probably not make it into the path itsself. I'm not hopeful
<noamr> lea: another benefit is that it's convertable
<noamr> lea: I'm convinced that the current design is good enough. I wonder how much can be backported to path?
<noamr> TabAtkins: what kind of improvements?
<noamr> lea: same segments with CSSified names, length-percentage etc
<Rossen6> ack lea
<noamr> smfr: a more restricted grammar of this
<noamr> lea: sounds perfect
<TabAtkins> noamr: i'm also okay with taht possibility, think it's doable to take the subset of shape() be ported back to path()
<lea> PROPOSED RESOLUTION: shape() remains as-is, spec subset that is more tightly tied to SVG <path> for a path() overload
<TabAtkins> Rossen6: so I'm hearing keep shape() as is... [basically restates lea's proposed resolution]
<noamr> +1
<TabAtkins> +1
<smfr> +1
<chrishtr> +1
<TabAtkins> RESOLVED: shape() remains as-is, spec subset that is more tightly tied to SVG <path> for a path() overload

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Friday morning
Status: FTF agenda items
Development

No branches or pull requests

7 participants