[csswg-drafts] [css-values]: Expose `n` as a `<calc-constant>` (#8981)

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

== [css-values]: Expose `n` as a `<calc-constant>` ==
# Introducing `n` as a new `<calc-constant>` with reference access to `n` value from `:nth-child()` and similar

## 1. Introduction

This proposal presents a concept for accessing the `n` variable as a `<calc-constant>` for use in CSS math functions like `calc()`/`min()`/`max()`/`clamp()`/etc. This feature would allow developers to achieve dynamic computation of styles and enable more control over numerical relationships within a stylesheet.

## 2. Proposal Description

Currently, CSS math functions permit a mix of different types of units, for instance, percentages and pixels, and more recently, `pi`, `e`, `infinity`, and `-infinity`. This proposal suggests introducing a new `<calc-constant>` value `n` to access an iterative `n` variable within such functions.

The syntax proposed would look as follows:

```css
element:nth-child(n) {
  property: calc(n * 1px);
}
```

In this case, `n` is the index of the current element iteration. The property is calculated based on the index number of the current element.

## 3. Use Cases / Examples

1. **Staggered Styles:** By providing access to `n` in the mathematical expressions, we can apply staggered styles to elements. For instance, with animations or transitions, each subsequent element could have a progressively larger delay, giving a "wave" effect.

    ```css
    .box:nth-child(n) {
      animation-delay: calc(n * 100ms);
    }
    ```
2. **Dynamic Spacing:** You can create dynamic spacing between items in a list or grid by using the `n` variable to calculate margins or gaps.

    ```css
    .item:nth-child(n) {
      margin-top: calc(n * 10px);
    }
    ```
3. **Proportional Dimensions:** The width or height of elements could be proportionally determined using `n`, potentially useful in creating visual hierarchies or pyramid-like structures.

    ```css
    .bar:nth-child(n) {
      height: calc(n * 5%);
    }
    ```
4. **Variable Opacity:** One could create an interesting visual effect by modifying the opacity of consecutive elements.

    ```css
    .card:nth-child(n) {
      opacity: calc(n * 0.1);
    }
    ```
5. **Color Variations:** You could use `n` in `calc()` for creating color gradients or variations across multiple elements.

    ```css
    .gradient:nth-child(n) {
      filter: brightness(calc(100% - n * 5%));
    }
    ```

## 4. Considerations

1. **Value of `n`**

   There are significant questions around how the value of `n` should be determined when used in conjunction with an expression such as `n + 1` within the `:nth-child()` pseudo-class. The ambiguity revolves around whether `n` should be considered as equivalent to the value of `n + 1`, or if it should reflect the value `n` would have held without the `+ 1` expression.

   **Options:**

   1. **Value equal to the total expression**

      The first approach considers `n` as equivalent to the result of the entire expression. In this case, for an element selected with `:nth-child(n + 1)`, the `n` inside `calc()` would represent the numeric value equivalent to the actual position of the selected element in the document tree.

      This approach aligns with the intuitive expectation that `n` represents the selected element's numeric position. However, this method could potentially confuse developers, especially when complex expressions are used within the `:nth-child()` pseudo-class.

      **Example:**

      ```css
      element:nth-child(n + 1) {
        property: calc(n * 1px);  /* n = index of the selected element in the sequence of matched elements */
      }
      ```

   2. **Value equal to its use in the expression**

      The alternative approach interprets `n` to be the raw value it would have been without the `+ 1` (or any other expression) in the `:nth-child()` selector. Here, `n` represents the iteration count in the sequence of elements, starting from 1, before any expression is applied.

      While this interpretation might be less intuitive initially, it offers developers more precise control over the numerical relationship, and it remains consistent regardless of the complexity of the `:nth-child()` expression.

      **Example:**

      ```css
      element:nth-child(n + 1) {
        property: calc(n * 1px);  /* n = raw iteration count, starting from 1 */
      }
      ```

2. **Separate variable for matched `n` sequence count**

   Would it also be helpful to have another related constant to the effect of `ncount` that would represent the total number of elements in the sequence? This constant could be useful for creating dynamic styles that depend on the total number of elements— detecting where the "halfway point" is, for instance, which could also pair well with the `mod()` function.

   **Example:**

   ```css
   element:nth-child(n) {
     /* Calculate height based on position */
     height: calc(1em + mod(n, ncount + 1) * 1em);
   }
   ```

## 5. Conclusion

Introducing the ability to access the `n` variable within CSS math functions would present developers with a greater range of possibilities for dynamic styling. This addition would provide a powerful tool for creating unique and responsive designs, and it fits well within the already established logical paradigms of CSS.

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


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

Received on Saturday, 17 June 2023 02:40:06 UTC