Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use commas in a CSS variable fallback?

How can one use commas in the fallback value of a CSS variable?

E.g. this is fine: var(--color, #f00), but this is weird var(--font-body, Verdana, sans-serif).

The idea is to be able to set a font-family using a variable with a fallback value of say Verdana, sans-serif.


Edit: This actually works pretty well for browsers that support CSS properties, but the issue seems to come from Google Polymer's polyfills.

For future reference, I ended up using variables for both the font and the font family fallback like so (seems to be the cleanest way of doing it for now):

font-family: var(--font-body, Verdana), var(--font-body-family, sans-serif)
like image 425
Tony Bogdanov Avatar asked May 25 '16 16:05

Tony Bogdanov


People also ask

Why do we use fallback fonts in CSS?

CSS font Fallbacks provide a backup for the fonts i.e. if one font doesn't work properly then the browser will try the other one. For good coding practice write a generic font family at the end of the list and choose the font fallback within the same font family.

Can we use VAR in CSS?

The var() CSS function can be used to insert the value of a custom property (sometimes called a "CSS variable") instead of any part of a value of another property.


2 Answers

The below is an extract from the W3C spec: (emphasis is mine)

Note: The syntax of the fallback, like that of custom properties, allows commas. For example, var(--foo, red, blue) defines a fallback of red, blue; that is, anything between the first comma and the end of the function is considered a fallback value.

As you can see from the above statement, if your intention is to set Verdana, sans-serif as fallback value when --font-body is not defined then the syntax given in question is expected to work. It does not require any quotes as per spec.

I don't have a browser that supports CSS variables and hence I couldn't test the following code but it should work based on the spec:

.component .item1 {
  --font-body: Arial;
  font-family: var(--font-body, Verdana, sans-serif); 
  /* should result in font-family: Arial */
}
.component .item2 {
  font-family: var(--font-body, Verdana, sans-serif);
  /* should result in font-family: Verdana, sans-serif */
}
<div class=component>
  <p class=item1>Arial
  <p class=item2>Verdana, sans-serif
</div>
like image 199
Harry Avatar answered Sep 30 '22 18:09

Harry


As Harry mentions, what you have should already work in browsers that implement custom properties.

But if you're using custom properties with font-family, there is a major caveat: var() does not allow you to modify or add to an existing font-stack, due to the fact that custom properties cascade in exactly the same way as all other properties. That is to say, the expression

var(--font-body, Verdana, sans-serif)

results in one of two possible values:

  1. If a --font-body custom property declaration exists, var(--font-body)
  2. Otherwise, Verdana, sans-serif

The "Verdana, sans-serif" is not part of the font-stack that's defined in --font-body, and should the family defined in --font-body be missing or otherwise unavailable to the browser, it will not fall back to Verdana or sans-serif; it will instead fall back to an arbitrary default font of the browser's choosing.

Worst of all, if the value of --font-body causes the entire font-family declaration to be invalid, that font-family declaration will have no effect.

If you're looking to build font-stacks dynamically in a stylesheet, you cannot use custom properties. You will need a CSS preprocessor.

like image 28
BoltClock Avatar answered Sep 30 '22 19:09

BoltClock