Re: [csswg-drafts] [css-values] add "attr" test to if() (#12519)

Maybe with attr in if, more complex conditions should be possible?


## Proposal: Allow `attr()` and comparisons in CSS `if()` conditions

### What problem are you trying to solve?

The `if()` function, defined in [CSS Values and Units Module Level 5](https://drafts.csswg.org/css-values-5/#if-function), allows authors to express conditional logic using semicolon-separated branches:

```css
if(condition1: value1; condition2: value2; else: fallback)
```

However, the current specification limits conditions to only boolean-returning functions (like `supports()`, `media()`, `style()`).

This proposal seeks to **expand `if()` conditions to support**:
- Comparison expressions (`==`, `!=`, `<`, `>`, etc.)
- Typed `attr()` values in those expressions

This would make conditional logic based on element attributes or variables far more powerful and expressive.

---

### Why is this a problem?

Many use cases require styling based on dynamic attributes or custom properties. For example, switching color, layout, or visibility based on a `data-status` attribute or `var()` value.

Currently, this requires:
- Repeating values in selectors or classes
- Using nested `if()` calls
- Maintaining logic outside of CSS

Allowing `attr()` and comparisons in `if()` would solve these limitations and enable clean, declarative multi-case logic.

---

### Suggested Change

Allow comparison expressions in `if()` conditions:

```css
if(attr(data-foo string) == "bar": red; else: black);
```

Support these operators:
- Equality: `==`, `!=`
- Numeric: `<`, `<=`, `>`, `>=`

Examples:

```css
/* Example 1: Match attribute value */
color: if(attr(data-status string) == "error": red; else: black);

/* Example 2: Multi-case conditional with attr */
color: if(
  attr(data-status string) == "error": red;
  attr(data-status string) == "warning": orange;
  attr(data-status string) == "success": green;
  else: gray
);

/* Example 3: Numeric comparison */
width: if(
  attr(data-level number, 0) >= 3: 300px;
  attr(data-level number, 0) >= 1: 200px;
  else: 100px
);
```

This builds on typed `attr()` from [CSS Values & Units Level 4](https://drafts.csswg.org/css-values-4/#attr-notation), using it inside the `if()` condition.

---

### Relation to existing CSS

- `if()` already supports multiple branches with semicolon-separated syntax.
- Comparison expressions are already allowed in `@media if(...)`, so this is consistent.
- `attr()` with types (`string`, `number`, etc.) is already spec’d for value contexts.
- This is a natural extension, not a breaking change.

---

### Implementation notes

- Conditions would be evaluated at **computed-value time**.
- Logic would follow existing behavior from `@media` and `@supports`.
- This would unify condition handling across CSS.

---

### Summary

Extend the `if()` function to support:
- **Comparison expressions** in condition clauses
- **Typed `attr()` values** inside those expressions

This enables readable, multi-branch logic based on dynamic values—especially attributes—without nested `if()`s or JS hacks.



-- 
GitHub Notification of comment by jogibear9988
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/12519#issuecomment-3122648590 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Saturday, 26 July 2025 19:21:52 UTC