Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.Sign up
[css-values] String concatentation #542
As discussed with @tabatkins during TPAC last week.
Now with variables (custom properties), string concatenation is coming up in more and more use cases. Constructing URLs from variables for instance (see #541) is useless without concatenation.
Tab suggested a
I'm intrigued by the idea of automatic concatenation of consecutive string tokens, but I'm worried that this might derail the general possibility of concatenation.
I personally don't think one extra layer of function notation will create an overwhelming number of parentheses. But maybe I've just been programming too long.
One thing I've mentioned elsewhere (and Lea seems to be assuming it, as well) is the idea that a concatenation function could do double-duty as a string coercion function, forcing any number or other non-string variables inside it into string version. This is very important for building SVG path data from variables. I'm worried that if you combine this with the default concatenation option you'd really make a mess of parsing.
So my vote is for a
I'm strongly against the proposal to just make adjacent
I'm supportive of
Also +1 to Tab's suggestion that string serialization of numbers and lengths be independent of the formatting of the initial value. If there is demand in future, separate number formatting options could be considered, based on the number formatting options in
Some printing tools have already implemented the behaviour from that working draft. I believe it's not really a good idea to have some new
referenced this issue
Feb 26, 2019
The CSS Working Group just discussed
The full IRC log of that discussion<fantasai> Topic: String Concatenation
<astearns> github: https://github.com//issues/542
<fantasai> leaverou: There's a bunch of string value accepting proeprties in CSS, and can't use variables in there
<fantasai> leaverou: paths
<fantasai> leaverou: Lots of places where concatenation would be useful
<fantasai> leaverou: and don't have a way to do it
<fantasai> leaverou: Didn't recall any objections to the propsoal, just questions about what it's called
<fantasai> leaverou: I don't care, we just need a way to do it
<fantasai> chris: ppl using preprocessors take string concatenation for granted, it's simple there
<fantasai> chris: they're astounded when they find it's not available in raw CSS
<fantasai> leaverou: Primarily useful in URLs, but also useful in other places like paths
<fantasai> TabAtkins: I agree with the need for a function here, prefer concat() but fine with anything else
<fantasai> leaverou: We've also had suggestions for a function that converts things to strings,
<xfq> ack AmeliaBR
<fantasai> leaverou: text() is generic enough to do both
<fantasai> string() sgtm
<fantasai> AmeliaBR: Problem with that is that for string coercion you often also want number formatting
<fantasai> AmeliaBR: so that might need to be a separate function
<fantasai> AmeliaBR: butwould need to be partof the system if you are going to make useful path dat from numeric variables
<fantasai> AmeliaBR: need to concatenate not just letters but numbers from variables
<fantasai> AmeliaBR: calc expressions
<dbaron> q+ to ask what the inputs to this function can be, and where it can be used
<fantasai> AmeliaBR: etc.
<fantasai> TabAtkins: What are the use cases for coercion? Debugging ovviousl, anything else?
<fantasai> leaverou: ...
<fantasai> Am Big in dataviz
<leaverou> s/.../generated content to display a variable value in the UI/
<fantasai_> AmeliaBR: e.g. bar graphs, want to use value in drawing but also labelling
<fantasai_> AmeliaBR: don't want to duplicate content
<fantasai_> TabAtkins: I really don't want to get into string formatting
<fantasai_> TabAtkins: otherwise do see the value in do see value in displaying 50% on bar chart while 50% also used to size the bar chart
<fantasai_> AmeliaBR: So if we want to leave the generic number formatting issue for later, that's fine
<fantasai_> AmeliaBR: So long as we still have idea that basic concat function can take non-string values and simply print them out
<fantasai_> AmeliaBR: so you can use them for path data
<fantasai_> AmeliaBR: In path data you generally want to preserve maximum precision anyway
<fantasai_> leaverou: example ... interpolation
<fantasai_> leaverou: Don't want to define how concat() interpolates with each other
<xfq> ack db
<Zakim> dbaron, you wanted to ask what the inputs to this function can be, and where it can be used
<fantasai> dbaron: Reading the proposal wasn't clear to me what the inputs of this function is and what the output is in terms of types
<fantasai> dbaron: What CSS value types can be used in here?
<fantasai> TabAtkins: output tpe is tring
<fantasai> TabAtkins: input type is any thing, standard serialization of the token
<fantasai> dbaron: There will be a spec defining standard serialization of a token?
<leaverou> s/example ... interpolation/yes, that simplifies interpolation as well, if types of arguments were not coerced we'd need to define interpolation between two concat() calls
<fantasai> TabAtkins: Need that for variables anyway
<fantasai> TabAtkins: If it doesn't exist yet, some othe rspec is implicitly relying on it and it needs to be defined
<fantasai> astearns: Wrt used, it's anywhere with a string?
<fantasai> fremy: Exception for url?
<fantasai> TabAtkins: No, works in url()
<xfq> ack lea
<fantasai> TabAtkins: url() can take a string
<TabAtkins> s/take a string/take only a literal string, there's another issue for generic <string> input/
<fantasai> astearns: I'm hearing lots of nods on having this thing. Any implementer interest?
<fremy> (to clarify what tab said, url() can take a string but not a <string>)
<fantasai> astearns: From silence sounds like, yes this would be a good thing, no it's not a priority
<fantasai> emilio: Expectation is that you can do like sth(var(--whatev))?
<fantasai> emilio: Then how can you define it to be any token?
<fantasai> TabAtkins: var() is processed at a higher level than any value
<fantasai> fremy: If you want a string, you do text("string")
<TabAtkins> (It's specific as taking a <string> in the syntax, but in Syntax we handle url() in special ways that prevent it from taking string-producing functions.)
<fantasai> emilio: If it takes any token
<fantasai> fremy: If it's not a string, then you convert
<fantasai> TabAtkins: I think Emilio got it
<fantasai> astearns: OK, naming. What do we call the thing?
<fantasai> AmeliaBR: Lea suggested text(), but there's already a text() function in paged content
<fantasai> fantasai: How about string? was in Lea's original proposal
<fantasai> leaverou: sounds fine
<fantasai> chris: sounds fine
<fantasai> AmeliaBR: Sorry, confused things. It's the string() function that exists, text() does not
<fantasai> AmeliaBR: and already implemented
<chris> I care more that it exists, than what precisely it is called
<tantek> I for one an all for the cat() function, I bet it would poll well on Twitter
<fantasai> astearns: Any objections to text()?
<chris> Lets go with text
<fantasai> dydz: Prefer concat(), but ...
<fantasai> AmeliaBR: Want names that are understandable by non-programmers in CSS
<fantasai> AmeliaBR: Also, we tend not to truncate identifiers in CSS
<chris> concat is not immediately obvious to non programmers either. both cat and concat are abbreviations
<fantasai> TabAtkins: We are not using cat(), tantek!
<fantasai> bkardell_: I don't have a better suggestion, but text() is not very clear to me
<Rossen> +1 to bkardell_
<fantasai> bkardell_: There are so many ways that I coudl interpret "text"
<tantek> +1 to bkardell_
<fantasai> flatten() :P
<fantasai> chris: I think it's pretty clear
<fantasai> myles__: We should think about whether concatenation or coercion is more common use case
<TabAtkins> url(text("http://example.com", var(--foo)))
<florian> echo() ?
<fantasai> AmeliaBR: text() is clear for coercion, maybe less clear for concatenation
<TabAtkins> No unixisms!
<TabAtkins> y'all weirdos!
<chris> and text(var(--foo)) with one param is clearer than concat(var(--foo))
<dbaron> hopefully everybody has forgotten XPath by now?
<tantek> Time for a Twiter survey!
<fantasai> iank_: Spreadsheets use concatenate and concat
<fantasai> TabAtkins: It's terrible and hard to spell
<fantasai> TabAtkins: These are all great names, except for all the ones that are bad.
<fantasai> TabAtkins: Let's table this and put together a non-binding Twitter poll
<fantasai> florian: Make sure you include an international audience
<fantasai> bkardell_: That works best if we all promote it so let us know
<fantasai> leaverou: Twitter doesn't have enough space for examples, and based on what examples you use can get different reactions
<fantasai> TabAtkins: I'll put together coercion example and concat example, and you can review them
<fantasai> astearns: Sounds like we'll do this and decide the name later, would be interested in implementer interest
<fantasai> astearns: Any objections?
<fantasai> RESOLVED: work on astring-coercion-and-concatenation function
One thing I want to mention: what would be really nice if that future string concatenation could work with anything that accepts strings, especially, grid-template-areas, to allow generating named areas from other variables, for example.
Of course, this should work also by allowing converting idents into strings, so those could be reused both inside
And this also brings me to another kinda related topic: ident concatenation. Probably also related to converting anything into anything, and related to the
Converting a string to a non-string (string to ident, string to parsed number or length) would be a separate issue. But I agree that adding a general parse function for that case is tied in with the unimplemented second parameter to
referenced this issue
Mar 2, 2019
I don’t buy the argument that CSS authors don’t know what “string” means. If that was the case, we shouldn’t have used it for GCPM. We have it there now, it exists, and it can be the single tool that authors reach for when they need a string.