Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to interpolate CSS variables with url()?

I want to store my background URLs in custom properties (CSS variables) and use them with the background property. However, I couldn't find a way to interpolate the string when using it as a parameter in url().

Here is my sample code:

:root {     --url: "https://download.unsplash.com/photo-1420708392410-3c593b80d416"; }  body {     background: url(var(--url)); } 

I know that this can be easily done in Sass or LESS using the interpolation function but I'm curious if there is a way to do it without any pre-processor.

like image 602
YashArora Avatar asked Feb 19 '17 16:02

YashArora


People also ask

What is URL () in CSS?

The url() CSS function is used to include a file. The parameter is an absolute URL, a relative URL, a blob URL, or a data URL. The url() function can be passed as a parameter of another CSS functions, like the attr() function.

How do you reference a variable in CSS?

To declare a variable in CSS, come up with a name for the variable, then append two hyphens (–) as the prefix. The element here refers to any valid HTML element that has access to this CSS file. The variable name is bg-color , and two hyphens are appended.

How do I give an image a URL in CSS?

Usage is simple — you insert the path to the image you want to include in your page inside the brackets of url() , for example: background-image: url('images/my-image. png'); Note about formatting: The quotes around the URL can be either single or double quotes, and they are optional.


1 Answers

You can perform interpolation with most CSS functions, including rgba() (see an example here). In fact, interpolation is one of the main features of custom properties.

But you cannot do this with url(), as url(var(--url)) is parsed not as a url( function token followed by var(--url) followed by a ), but a single url() token that is invalid because the var(--url) is being treated as a URL itself, and unquoted URLs in url() tokens cannot contain parentheses unless they are escaped. This means the substitution never actually occurs, because the parser never sees any var() expressions in the property value — indeed, your background declaration is completely invalid.

If you didn't understand any of that, that's fine. Just know that you cannot use var() interpolation with url() due to legacy reasons.

Even though the problem depicted in the question is related to the legacy url() token, you cannot do this by building URL tokens out of several var() expressions either, in case you were thinking of trying something like --uo: url(; --uc: ); or --uo: url("; --uc: ");, and background: var(--uo) var(--url) var(--uc);. This is because custom properties cannot contain unmatched string delimiters or parts of url() tokens (called bad URL tokens).

If you want to specify a URL in a custom property, you need to write out the entire url() expression, and substitute that entire expression:

:root {   --url: url("https://download.unsplash.com/photo-1420708392410-3c593b80d416"); }  body {   background: var(--url); } 

Or, use JavaScript instead of var() to perform the interpolation.

like image 169
BoltClock Avatar answered Sep 27 '22 21:09

BoltClock