TIL — Why Custom properties don’t work with the url() CSS function

Custom properties and CSS parsing are always good for surprises like !important behaving slightly differently or properties being “invalid at computed value time”.

Today I discovered yet another surprise — custom properties don’t work in combination …


This content originally appeared on DEV Community 👩‍💻👨‍💻 and was authored by Stefan Judis

Custom properties and CSS parsing are always good for surprises like !important behaving slightly differently or properties being "invalid at computed value time".

Today I discovered yet another surprise — custom properties don't work in combination with the url() function. 😲

.something {
  /* this doesn't work */
  --image: https://jo.com/image.jpg;
  background: url(var(--image));
}

Roman Dvornov describes the details quite well in a GitHub issue, but let me give you a condensed explanation.

The two modes of url()

Your url()-containing CSS will be parsed differently, depending on how you use url(). There's an old and a newer way:

  • Old: url(https://jo.com/image.jpg)
  • Newer: url('https://jo.com/image.jpg') or url("https://jo.com/image.jpg")

The problem of the legacy url() token

And these missing quotes of the old way might seem like a tiny detail, but they affect how your CSS is parsed.

Without quotes, the url() syntax looks like a CSS function, but it isn't. CSS parsers will treat it as a single token, as so-called url-token.

.something {
  background: url(https://ja.com/image.jpg);
  //          \---------------------------/
  //            without quotes this ☝️ is
  //               a single CSS token
}

And this entire token from url( to the closing ) enforces parentheses, whitespace characters, single quotes (') and double quotes (") to be escaped with a backslash.

url() with a quoted string, on the other hand, is a normal and flexible CSS function notation, which is parsed part by part and works as expected.

But now, guess what happens when you want to use a custom property in combination with url()?

.something {
  /* this doesn't work */
  --image: https://jo.com/image.jpg;
  background: url(var(--image));
//                ☝️ "No quotes? Cool, that's a url-token!
//                😢 "Too bad though, `(` isn't allowed in here..."
//                 "I'll throw everything away!"
}

Because there are no quotes, this declaration is parsed as a url-token. And unfortunately, the ( in var(--image) isn't escaped, so the parser throws an error and invalidates the entire CSS declaration.

And this legacy url-token parsing is why you can't use custom variables inside of url().

The solution to work around the legacy url()

What's the usual solution, when there's a problem with old web legacy? It's inventing new stuff because we can't break the web and just change things.

To enable custom properties in url() there's a new alias in town. The src() notation behaves the same way as url() but without this weird legacy url-token logic.

.something {
  /* this works! (theoretically) */
  --image: https://jo.com/image.jpg;
  background: src(var(--image));
}

Problem solved! But yet, no browser supports src() (I couldn't find browser support information but tested current Chrome, Safari and Firefox), so it's time for us to wait. 🤷‍♂️

CSS parsing and custom properties — always good for a surprise!

If you want to read more about this topic, here are some resources:


This content originally appeared on DEV Community 👩‍💻👨‍💻 and was authored by Stefan Judis


Print Share Comment Cite Upload Translate Updates
APA

Stefan Judis | Sciencx (2022-09-23T18:48:20+00:00) TIL — Why Custom properties don’t work with the url() CSS function. Retrieved from https://www.scien.cx/2022/09/23/til-why-custom-properties-dont-work-with-the-url-css-function/

MLA
" » TIL — Why Custom properties don’t work with the url() CSS function." Stefan Judis | Sciencx - Friday September 23, 2022, https://www.scien.cx/2022/09/23/til-why-custom-properties-dont-work-with-the-url-css-function/
HARVARD
Stefan Judis | Sciencx Friday September 23, 2022 » TIL — Why Custom properties don’t work with the url() CSS function., viewed ,<https://www.scien.cx/2022/09/23/til-why-custom-properties-dont-work-with-the-url-css-function/>
VANCOUVER
Stefan Judis | Sciencx - » TIL — Why Custom properties don’t work with the url() CSS function. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/09/23/til-why-custom-properties-dont-work-with-the-url-css-function/
CHICAGO
" » TIL — Why Custom properties don’t work with the url() CSS function." Stefan Judis | Sciencx - Accessed . https://www.scien.cx/2022/09/23/til-why-custom-properties-dont-work-with-the-url-css-function/
IEEE
" » TIL — Why Custom properties don’t work with the url() CSS function." Stefan Judis | Sciencx [Online]. Available: https://www.scien.cx/2022/09/23/til-why-custom-properties-dont-work-with-the-url-css-function/. [Accessed: ]
rf:citation
» TIL — Why Custom properties don’t work with the url() CSS function | Stefan Judis | Sciencx | https://www.scien.cx/2022/09/23/til-why-custom-properties-dont-work-with-the-url-css-function/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.