[csswg-drafts] [mediaqueries-5] Introduce `@size` rule for defining reusable media query size values (#10487)

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

== [mediaqueries-5] Introduce `@size` rule for defining reusable media query size values ==
## Abstract

This proposal introduces the `@size` rule, a new CSS at-rule, that allows authors to define variable sizes which can be referenced in `@media`, `@custom-media`, and `@container` queries alike. This feature offers an easier and more maintainable method to manage responsive design breakpoints across CSS files.

<blockquote><sub>

**Related proposal:** [[mediaqueries-5] [css-env] Replace @custom-media with custom environment variables? #6698](https://github.com/w3c/csswg-drafts/issues/6698)

</sub><sub>

☝🏼 this proposal shares a similar goal, but using a different approach

</sub></blockquote>

## Motivation

Responsive design often involves repeatedly using the same viewport breakpoints across multiple media queries. This can lead to cumbersome, error-prone code and make global updates to breakpoints tedious. The `@size` rule aims to solve this by allowing developers to define and reuse named sizes that can be referenced consistently across all media queries.

The introduction of [`@custom-media`](https://www.w3.org/TR/mediaqueries-5/#custom-media-query) aids in this effort as well, but it stores an entire query, where even in the definition of a `@custom-media` query, the use of a reusable variable value would prove useful, as pointed out by @adamwathan on X [here](https://x.com/adamwathan/status/1805288051901428023):

> It's a shame to me that the `@​custom-media` spec offers no way of removing the duplicate `500px` value in this sort of situation like you'd expect to be able to do with a plain old variable 😕
> **Adam Wathan**

## Syntax / Example

### Defining Sizes

The `@size` at-rule allows developers to declare named sizes using standard CSS units:

```postcss
@size {
  --small: 480px;
  --medium: 768px;
  --large: 1024px;
  --extra-large: 1440px;
}
```

### Usage in `@media` and `@container` Queries

The named sizes can be used in `@media`, `@custom-media`, `@container` queries:

```css
@media (min-width: size(--small)) {
  /* Styles for small and above */
}

@media (width > size(--medium)) and (width <= size(--large)) {
  /* Styles for medium to large */
}

@custom-media --custom-medium (width > size(--medium));
@media (--custom-medium) {
  /* Styles using custom media query */
}

@container some-container (min-width: size(--small)) {
  /* Styles for small and above */
}
```

## Specification

### Grammar

The `@size` rule must contain a block of rules, each defining a single named size. Each named size must be a valid CSS identifier followed by a colon, a valid CSS length (e.g., px, em, rem, %) or viewport width/height (e.g., vw, vh), and a semicolon.

### Semantics

- **Defining Sizes**:
  - The `@size` at-rule must appear at the outermost level of the style sheet and cannot be nested inside other at-rules or selectors.
  - Each named size defined within the `@size` block is treated as a global variable that can be referenced using the `size()` function.

- **Referencing Sizes**:
  - The `size()` function takes one argument: the name of the size defined via `@size`.
  - The argument for `size()` must match one of the identifiers defined within an `@size` rule.
  - If an undefined name is used within `size()`, the rule is invalid and should be ignored by the browser.

## Benefits

- **Maintainability**: Centralized definition of media sizes allows for easier updates and maintenance of responsive design breakpoints.
- **Readability**: Named sizes improve the readability and semantics of media queries.
- **Consistency**: Ensures consistent breakpoint usage across different parts of the stylesheet.

## Specification Considerations

- **Alternative name**: I originally considered the at-rule name `@media-size` but renamed it to `@size` to make this arbitrarily supported in `@container` queries as well as `@media` and `@custom-media` queries.
- **Alternative syntax**: I can see an argument being made for an alternative syntax like this:
    
    ```postcss
    @size --small 480px;
    @size --medium 768px;
    @size --large 1024px;
    @size --extra-large 1440px;
    ```
- **Expanded scope of usage:** I could see these sizes being very useful in styles as well, so it may be worth considering allowing the `size()` function to be used within property values, enabling styles to reference the defined sizes directly. This would provide a consistent way to use the named sizes across both queries and properties (e.g. `width: size(--medium);`).

## Implementation Considerations

- **Browser Compatibility**: A new at-rule and function needs to be implemented across all browsers; feature detection should be considered.
- **Tools and Validators**: CSS authoring tools and validators will need to be updated to support and recognize the new `@size` rule and the `size()` function.

## Conclusion

The `@size` rule introduces a method for defining reusable responsive design breakpoints. By enabling the reuse of named sizes across `@media`, `@custom-media`, and `@container` queries, this proposal aims to simplify the process of maintaining consistent, flexible, and readable responsive styles.

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


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

Received on Monday, 24 June 2024 19:01:51 UTC