W3C home > Mailing lists > Public > public-css-archive@w3.org > November 2020

[csswg-drafts] [selectors-4] New selector based on the amount of child elements (#5694)

From: Rami Yushuvaev via GitHub <sysbot+gh@w3.org>
Date: Wed, 04 Nov 2020 13:19:11 +0000
To: public-css-archive@w3.org
Message-ID: <issues.opened-736108510-1604495950-sysbot+gh@w3.org>
ramiy has just created a new issue for https://github.com/w3c/csswg-drafts:

== [selectors-4] New selector based on the amount of child elements ==
## Overview

Currently there are no [selectors](https://drafts.csswg.org/selectors-4/#overview) that let us apply a style based on the total amount of direct children the element has.

I can't apply red color if the element that has 2 direct children or green color if it has 3 direct children.

My proposal is to add a new pseudo-class called `:nth-children(n)` which is based on the existing naming conventions.

### Code Example

Lists:

```css
ul:nth-children(2) {   /* only if a list has 2 child elements */
  color: red;
}
ul:nth-children(3) {   /* only if a list has 3 child elements */
  color: green;
}
```

Tables:
```css
table tr:nth-children(4) {   /* only if a tr has 4 child elements (including <td>, <th> and other elements) */
  background-color: red;
}
table tr:nth-children(5) {   /* only if a tr has 5 child elements (including <td>, <th> and other elements) */
  background-color: green;
}
```

## The Problem with Existing Pseudo-Class

The vast majority of the child element selectors are trying to **drill up** - the selector applied on the `<li>` checking against the parent `<ul>` element.

While my proposal is to **drill down** (like flex and grid) - the selector applied on the `<ul>` checking against the amount of child `<li>` elements.

### `E:first-child`
An **E** element, first child of its parent.

### `E:last-child`
An **E** element, last child of its parent.

### `E:only-child`
An **E** element, only child of its parent.

### `E:nth-child(n [of S]?)`
An **E** element, the **n** child of its parent matching **S**.

### `E:nth-last-child(n [of S]?)`
An **E** element, the **n** child of its parent matching **S**, counting from the last one.

### `E:empty`
An element that has no children (neither elements nor text) except perhaps white space. **(This selector is the only selector that applied on the parent element, checking child elements.)**

### `E > F`
An F element child of an E element. **(This is a general selector to target a specific child element. Doesn't count totals.)**

## The Solution

As mentioned above, the new selector will behave like flex and grid, it will be applied on the parent element and check the total number of children elements it has.

### `E:nth-children(n)`
An **E** element, counting total **n** children.

## Usage

Conditional design based on the amount of child elements:

```css
tr:nth-children(1) td {
  color: red;
}
tr:nth-children(2) td,
tr:nth-children(3) td,
tr:nth-children(4) td {
  color: yellow;
}
tr:nth-children(5) td,
tr:nth-children(6) td,
tr:nth-children(7) td {
  color: green;
}
```

Another example is to use keyword values:

```css
ul:nth-children(even) {   /* 2, 4, 6, etc. */
  color: red;
}
ul:nth-children(odd) {   /* 1, 3, 5, etc. */
  color: green;
}
```

## Use Cases

This can help developers apply conditional design in many case:

* Style content based on the total amount of paragraphs - too few paragraphs will have red text color, the more paragraphs the text has the greener the text become.
* Style charts (see [ChartsCSS.org](https://chartscss.org/charts/column/)) based on the amount of data items (`<td>` elements) and amount of datasets (`<tr>` elements).
* Style different lists `<ol>`, `<ul>`, `<dl>` based on the total amount of list items.

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


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Wednesday, 4 November 2020 13:19:13 UTC

This archive was generated by hypermail 2.4.0 : Tuesday, 5 July 2022 06:42:22 UTC