Author Information

Brian Kardell
  • Developer Advocate at Igalia
  • Original Co-author/Co-signer of The Extensible Web Manifesto
  • Co-Founder/Chair, W3C Extensible Web CG
  • Member, W3C (OpenJS Foundation)
  • Co-author of HitchJS
  • Blogger
  • Art, Science & History Lover
  • Standards Geek
Follow Me On...
Posted on 03/01/2019

Intuition Bikeshed and Standards Challenges

One thing that's been on my mind quite a lot for the last few years is how we can better communicate both in and out of standards bodies. This past week some things happened which I think make for an interesting review and some thought about whether we did the right things, and how we can do better.

This week, the CSS Working Group tweeted an informal Twitter poll that looked like this (below) - if you haven't voted or replied to it yet, I would ask that you read this before you do:

It includes two examples attempting to show a couple of hypothetical uses of a new function in CSS that coerces/concatenates strings and asks what authors what they expect it would be called, offering the following choices in the poll:

A not insignificant number of folks, some friends and standards people themselves were kind of appalled that string() wasn't in the list. I mean... Of course it should be string(), right? Hurriedly, some of us tried to provide some context but I feel like it really deserves some more words and it has me thinking more about how we can do better (and what that would even mean).


CSS doesn’t (currently) really "do" string concatenation "generally". However, it now has constructs like CSS Custom Properties which seem to make this sort of thing very desirable. Based on some feedback and discussions an issue was opened in late 2016 by Lea Verou to consider how to make that work.

Note: Yes, it is now 2019 and while this seems to many of us like a really long time for such a small, basic thing, in standards time, that is nothing. The CSS Working Group has hundreds of issues of all shapes and sizes and doesn’t get to actually prioritize anyone’s actual time (some priorities are set by the company that employs you, and some of us do this in our "spare" time), and... sometimes there are non-immediately obvious complexities. More on all that later.

In it, she points out that content: currently does a fairly simple form of concatination. If you are unfamilliar with this, allow me to use Lea's Prism to illustrate it with an example from MDN below:

a::after {
  content: " (" attr(id) ")";

Great. She suggests that perhaps for a few other "stringy" properties, we should just do that - just make it able to smash those things together into one string. That would be "best" for authors - less "Lispy" and easier to read (the Lisp family of languages are somewhat famous for its use of lots of parenthesis and how it is read)

But... authors want this ability in a lot of contexts where it isn't so simple or obvious. Having a general thing which gets authors more power, in more places, sooner, also seems good for authors. So, let's start there - powers first, maybe sugar later.

Without going any further, I'd like to point out that this is a decision - a weighing of values of outcomes. It means that if/when these powers ship, they will be kinda "Lispy". Some authors, lacking the context as to why might that decision was made, might just think that this was a bad decision. Even with that context, some authors would disagree with the choice.

Anywho.. Discussions progressed about which use cases and constraints there were around a way to say “smash these two things together” as strings and one of the early names proposed for this was “string()”.

Sure, makes sense to me. Don't all programmers know string? Seems pretty universal. What else would it be even? Obviously it should be string.

Well, here too, it seems that context matters a lot, in more ways than one.

It turns out that another spec CSS Generated Content for Paged Media Module (GCPM) has already defined a function called string() and does... not this.

Still, a lot of us (yes, me too) are sort of like "Yo wait... what? what's that spec? No browser seems to implement it -maybe we could just change that? Surely this is a better use of string()? Seems last updated in 2014, and if no one has implemented it, it's probably dead. This is like... clearly a string, it feels bad that we can't use string for dumb reasons.""

Yes, all of that is mostly true, and... these things are also true:

The ideas and work of GCPM, like a lot in CSS, have a long history. Bert Bos (one of the creators of CSS) made the announcement on the mailing list of its first working draft with that title in 2006. In it, he said:

It describes features typically only used when printing: running headers and footers, footnotes, references to page numbers, floats to the top and bottom of a page, etc. Indeed, we may define explicitly that these features *don't* work in interactive media. (Although I already heard people ask for footnotes to work interactively as well, possibly as a light-weight form of hyperlink, opening a pop-up.)

In fact, in many ways the ideas of both markup documents and stylesheets originated with print, not screens and a lot of people continued to see that potential of stylesheets to be important way beyond Web browsers. The editor of that spec was Håkon Wium Lie, the other creator of CSS.

So, part of that is to point out that in the context of framing this, they wanted this concept of, well, kind of named strings and then a way to refer to and use those strings. Strings, strings, strings, and so, well, string() seemed like a perfectly rational name. I mean... Obviously it is a string.

Then, as you might expect, people from those industries began implementing non-browser implementations. Several supported string, some "forever" by the time this 2014 spec was published.

But, Brian... This is all stuff doesn't work in browsers. It's for print and it seems almost like Bert was suggesting it might be kinda good to split them? Let's just split them because this is obviously a string!

Maybe... but there is also this:

In between the birth of CSS and now, we've also increasingly popularized this "not print really" but also "not currently web browsers" uncanny valley that are things like PDFs or EBooks.

These have to work on various... er... screens. With different sizes and orientations and now can even be interactive. You know, kind of like a web browser.

At the same time, Web browsers have evolved too: Ideas like Web Packaging address, in a more general way, ideas in publishing around, for example, distributing an ebook. Ideas like ServiceWorkers make it possible to now take that offline. You know, kind of like an ebook.

And so on.

And so, as much as possible, to common ends, we are all try to work together within the W3C, and especially in CSS.

CSS has never (to the best of my knowledge) overloaded an existing function with a radically different signature/meaning depending on the media. To do so would certainly mean just agreeing that we would never adopt this, which, meh, I don't know? In any case, for at least some authors who have to deal with both it might be really confusing... None of that seems "great" if it is all easily avoided.

Except, dammit, I am going to be honest: this really feels like a string() to me. How can it not be? That is definitely the best one.

Resolving and Bikesheds

And so, all that back story set: There were discussions on this in the face to face meaning. In this context, it seemed we had pretty general agreement on the use cases and how it would work, but we didn't have a name.

However, there were a few ‘finalist’ suggestions and cogent arguments about why some other names were actually better than string(). Hmm... maybe?

In the end, weighing all of the things, I think that we just decided it was probably best to just take string() off the table if there was something else that could work -- and people were even making compelling arguments that not only would they work - they were actually better. Meh. I dunno.

It seemed that the really serious contenders were “concat()” and “text()” and at some point I think people were just trying to move on and it seemed to be settling around text(). The chair asked “Any objections to text()?”

I squirmed.

There I really don't want to be "keep the dumb bikeshed going guy" (if you are not familliar with the term, here's an explanation of bikeshedding). I was at this point entirely willing to accept "not string()" but I just found text actually confusing and thought that most of the same problems of "looks good in this light... as well as many others" might apply here... But, you know... maybe that's just me? Should I say something?

So I finally chimed in and offered simply “I don’t have a better suggestion, but text() is not very clear to me… There are so many ways that I could interpret “text” in the context of CSS” and "sorry".

It wasn’t a formal objection, I just wanted to see if maybe others felt the similarly. And, well... some did. And... some didn't.

Everyone, including me, seemed pretty sure that other people would surely find a thing either more intuitive, or actively unintuitive and we didn't agree on what those were.

This is a hard problem, because I think we all sometimes think that other people will surely see it 'like us'. It's very hard to do otherwise. But, people are diverse. CSS is used by people from many backgrounds, with many perspectives, different primary languages, cultures and so on and, really, it's just very hard to know.

There was some more discussion. There were a few other suggestions made (some minuted, some not, some serious, some not). One idea that seemed to be perhaps popular was something vaguely “like string, but not exactly string”. Any of these felt kind of more intuitive to me - but again, that's just me. I could imagine even that perhaps "more different" was actually potentially less confusing to potential future developers? I don’t know, honestly.

But, deep down, I just kind of secretly wish it could be string() because that's the one I just know everyone would get. Dammit.

All this said, I would like to put this in some actual perspective: No one was remotely cross about any of this. It was not a heated argument. Everyone was perfectly aimiable and all of the rationales were, I believe, entirely 'teachable'. I believe that all parties agreed that we would celebrate getting this power interoperably implemented regardless of which one it wound up being.

Unfortunately this meant that all we could agree to regarding the name was that we couldn't decide today. Yeah, idk, maybe that's on me. I'm honestly not sure how I feel about it.

Regardless, because there were good points and different perspectives all around, and because developers have even broader perspectives than the folks in that room - we thought that perhaps asking developers for input would help us clarify our thoughts, so Tab put together a poll.

Optimization Problem Problems

The thing is, the most interesting thing in this poll to me is just how many actual users of CSS thought concat() was actually the best one, even without all of this context, and how few chose all of the others.

Realistically, text() is the only 100% clear, readable, requires no context alternative in that poll and yet, as it currently stands, a mere 1 in 5 people chose it.

Unfortunately to-string() was just one of several possible 'almost strings' and several people who chose other also said something string or string-like -- but... even still - it's not that many actually. My manual efforts to tally them up as well as I can still seem to indicate that concat() has still way more support than all of the others combined.

It honestly wouldn't have been my guess going into all this. But... really, the more I look at it... maybe that is better, even without all the context. That is exactly what this function does.

Anyways.. I think that it is impossible to optimize something like “intuitiveness” without actual input from developers themselves and the really tough thing here is that there is that at best it is still merely optimization. There is no clearly defined 'perfect' that will make everyone happy, especially without context or being heard.

As I have argued before, I also believe that we really haven’t figured out how to do that well yet.

In order to give good input, any of us require at least a good framing of context. That's hard because, often there is a lot and it's hard to know what matters and what doesn't. The higher the "tax" of participating, the less likely it is that we will even get a good sampling of average users. Our time is just pulled in too many directions. It takes 2 seconds to read the poll and vote, many minutes to read this post.

Further, to give really quality feedback and input, probably you need the ability to ask some questions or something. But, even then: even if you sink in time and ask questions, the truth is, it is impossibly difficult to really weigh vapor.

That is, until we really sit down to use things, get some actual experience with it, try to apply it, stretch it, pull it, live with it a while and so on… it’s just… really hard to say. This is part of why I have advocated for the Extensible Web and Houdini work, and, why I argue that it is important to:

I feel like we’re making progress on all of these fronts, but I think we still have a very long way to go. Things like Custom Functions, for example, might go a long way toward answering future questions of similar ilk. It might be very plausible to get value quickly and have it compete and fail and adapt and grow and, maybe settle in in some ground we haven't quite defined yet that is "not part of CSS proper" but "widely used in publishing". I don't know.

I am very happy to say (and will probably write about) the fact that Houdini had some really good discussion in these meetings and, actually, I'm very pleasantly suprised by who I heard arguing what.

So... that's where we are, how we got there and some of the problems... How can we manage all of this better? Is there more we could do?

Thanks to my friends Amelia Bellamy-Royds and Jon Neal for their talks and helpful comments in reviewing some iteration of this piece.