Why is an unsupported CSS value still overriding its fallback declarations? [duplicate]

I set up some CSS rules like:

.example {
  color: white;
  background-color: darkgray;
  background-color: var(--bg-color);
  background-color: rgb(from var(--bg-color) r g b  / 0.5);
}

in the expectation that if a browser didn’t understand the fairly new relative color syntax (or the fairly old but not ancient var() syntax) that my element would still be legible. But in older browsers I still end up with a transparent (getComputedStyle($0).backgroundColor === rgb(0,0,0,0)) background rather than the darker one I need for legibility.

Why are both of these true?

  • the browser doesn’t understand the syntax (as evidenced by it not using the relative color)
  • the browser uses the rule anyway (as evidenced by the fallback rules going unused)

The CSS Values spec says re. “Partial implementations” that:

So that authors can exploit the forward-compatible parsing rules to assign fallback values, CSS renderers must treat as invalid (and ignore as appropriate) any at-rules, properties, property values, keywords, and other syntactic constructs for which they have no usable level of support. In particular, user agents must not selectively ignore unsupported component values and honor supported values in a single multi-value property declaration: if any value is considered invalid (as unsupported values must be), CSS requires that the entire declaration be ignored.

So my understanding is that a browser which doesn’t understand or support my relative color syntax should be ignoring that entire declaration. So why isn’t it using one of the earlier fallbacks?

3

When using a valid var syntax and the syntax after substituting var is invalid, the value will be the same as using unset. This behavior is mentioned in the customer properties spec.

As per 3.1 Invalid variables:

A declaration can be invalid at computed-value time if it contains a var() that references a custom property with the guaranteed-invalid value, as explained above, or if it uses a valid custom property, but the property value, after substituting its var() functions, is invalid. When this happens, the computed value is one of the following depending on the property’s type:

And under that section:

Either the property’s inherited value or its initial value depending on whether the property is inherited or not, respectively, as if the property’s value had been specified as the unset keyword.

With the reasoning of why it can’t fall back to other declarations:

The invalid at computed-value time concept exists because variables can’t “fail early” like other syntax errors can, so by the time the user agent realizes a property value is invalid, it’s already thrown away the other cascaded values.

You can see this behavior in a simpler example, where the value results like unset:

body {
  color: green;
}

.example {
  --bg-red: red;
  color: blue;
  color: var(--bg-red) I am a invalid syntax;
}
<div class="example">test</div>

These are the only 3 ways I can think of to provide fallbacks for unsupported value syntax that includes the use of var(), ordered by how widely supported they are.

  1. Make use of inheritance and set the fallback color in the parent, though this is not viable in your case since background-color is not inheritable, and has major drawback of the need to modify the parent element:
.parent {
  color: blue;
}

.example {
  --bg-color: red;
  color: rgb(from var(--bg-color) r g b / 0.5);
}
<div class="parent">
  <div class="example">test</div>
</div>
  1. Use feature query and replace the var in the supports-condition:
/*First Method*/
.example {
  --bg-color: red;
  background-color: darkgray;
  background-color: var(--bg-color);
}
@supports (background-color: rgb(from red r g b / 0.5)) {
  .example {
    background-color: rgb(from var(--bg-color) r g b / 0.5);
  }
}
<div class="example">example 1</div>
  1. Use custom @property to define the initial-value as the fallback value. This has the major drawback that the initail value must be hard coded:
@property --bg-relative {
  syntax: "<color>";
  inherits: false;
  initial-value: blue;
}

.example {
  --bg-color: red;
  --bg-relative: rgb(from var(--bg-color) r g b / 0.5);
  background-color: var(--bg-relative);
}
<div class="example">Example 2</div>

1

As another user pointed out in a (now-deleted?) comment on my question, this only happens when var() is used in the troublesome selector. If I try to use a relative color like rgb(from red r g b / 0.5) then my desired fallbacks are used.

I believe the answer lies in the spec re. invalid CSS variables which says:

A declaration can be invalid at computed-value time if […] the property value, after substituting its var() functions, is invalid.

which results not in discarding the rule but rather it will behave:

[…] as if the property’s value had been specified as the unset keyword.

There’s even a note that further reinforces this (after giving a very similar example to mine using background-color even 😁):

variables can’t “fail early” like other syntax errors can, so by the time the user agent realizes a property value is invalid, it’s already thrown away the other cascaded values.

I don’t know why the user agent has to have necessarily thrown away the other values (that seems like an implementation or at least design choice?), but regardless it does explain it!

In short:

The presence of the var() means the browser uses the rule hoping it will resolve to something valid. But then if it turns out not to be valid in the end, it’s too late to discard it and it resets the property instead.

you could try the following, some browsers do not accept var or rgb so it does not return anything (something transparent) this should work since you have a backup color.

.example {
  color: white;
  background-color: darkgray; 
  background-color: var(--bg-color, darkgray); 
  background-color: rgb(from var(--bg-color) r g b / 0.5);
}

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật