[csswg-drafts] [css-values-5] Boolean Values in CSS Custom Properties (#10593)

brandonmcconnell has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-values-5] Boolean Values in CSS Custom Properties ==
## Abstract

This proposal aims to introduce native support for boolean values in CSS custom properties by allowing a new `<boolean>` type in the `@property` rule. This enhancement aligns with existing boolean handling mechanisms in the CSS engine and extends them to user-defined custom properties. It enables developers to leverage true boolean logic within CSS for more readable and maintainable styles.

## Motivation

Currently, CSS custom properties support a range of data types including numbers, lengths, colors, and strings, but they lack native support for boolean values. One common technique to work around this is to emulate boolean values using integers (`0` and `1`) or toggles using empty values ([`The -​-var: ; hack...`](https://lea.verou.me/blog/2020/10/the-var-space-hack-to-toggle-multiple-values-with-one-custom-property/)), which can be both error-prone and less intuitive.

Introducing a reusable `<boolean>` type will streamline conditional styling and improve readability and type safety.

## Syntax

### Declaring a Boolean Custom Property

```css
@property --selected {
  syntax: "<boolean>";
  initial-value: false;
  inherits: true;
}
```

Using `@property` is optional here, but it does yield some benefits in terms of type safety.

### Using Boolean Custom Properties

```css
label {
  --selected: false;
  &:has(:checked) { --selected: true; }
  grid-template-columns: auto if(var(--selected) ? 20px : 0);
  svg { opacity: if(var(--selected) ? 1 : 0); }
}
```

In this example, the custom property `--selected` is declared as a boolean type, simplifying its use in conditional logic.

Without this, a developer might resort to using mathematical expressions that—while equally dry and even shorter-form in this case—are not as intuitive and may take time to recognize that the math is essentially acting as a boolean switch.

Here is how that same example might look using a "math-based switch":

```css
label {
  --selected: 0;
  &:has(:checked) { --selected: 1; }
  grid-template-columns: auto calc(var(--selected) * 20px);
  svg { opacity: var(--selected); }
}
```

This is a simple example, but this mathematical approach can easily become more complex depending on the use case.

## Benefits

### Type Safety

By introducing a native boolean type, the CSS engine can ensure that only valid boolean values are assigned to boolean custom properties, thus reducing errors.

### Reusability and Maintainability

Boolean custom properties can be reused across multiple styles, reducing redundancy and making stylesheets more maintainable.

### JavaScript Interoperability

Boolean custom properties can be easily manipulated through JavaScript, allowing for dynamic and interactive style changes. The type safety can be enforced using the CSS `@property` rule.

Using JavaScript, developers can interact with and manipulate boolean custom properties while benefiting from type safety.

### Example with JavaScript

```html
<label id="checkbox-label">
  <input type="checkbox" id="checkbox">
  Check me
  <svg>Icon</svg>
</label>

<script>
  const checkbox = document.getElementById('checkbox');
  const label = document.getElementById('checkbox-label');

  checkbox.addEventListener('change', (event) => {
    label.style.setProperty('--selected', checkbox.checked);
  });

  // Observing boolean custom property changes
  const observer = new MutationObserver(() => {
    const selected = label.style.getPropertyValue('--selected') === 'true';
    console.log('Selected:', selected);
  });

  observer.observe(label, { attributes: true, attributeFilter: ['style'] });
</script>
```

In this example, the `--selected` custom property is directly manipulated using JavaScript, and changes are observed to reflect the dynamic state of the checkbox.

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/10593 using your GitHub account


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

Received on Thursday, 18 July 2024 21:36:28 UTC