Skip to content

Commit

Permalink
add inheritance section
Browse files Browse the repository at this point in the history
  • Loading branch information
OnkarRuikar committed Aug 27, 2024
1 parent 2ee7f62 commit cb6099c
Showing 1 changed file with 104 additions and 20 deletions.
124 changes: 104 additions & 20 deletions files/en-us/web/css/css_counter_styles/using_css_counters/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ For example, you can use counters to automatically number the headings on a webp

Counters are, in essence, variables maintained by CSS whose values may be incremented or decremented by CSS rules that track how many times they're used. The following things affect the counter values on an element:

1. Counters are inherited from the parent element or received from a previous sibling.
1. Counters are [inherited](#counter_inheritance_and_propagation) from the parent element or received from a previous sibling.
2. New counters are instantiated using {{cssxref("counter-reset")}} property.
3. Counters are incremented using {{cssxref("counter-increment")}} property.
4. Counters are directly set to a value using the {{cssxref("counter-set")}} property.
Expand Down Expand Up @@ -143,6 +143,84 @@ The counter value is decreased by specifying a negative value for {{cssxref("cou
> You can also use {{cssxref("counter-increment")}} to decrement a non-reversed counter.
> The main benefit of using a reversed counter is the default initial value, and that the `list-item` counter automatically decrements reversed counters.
### Counter inheritance and propagation

Each element or pseudo-element has a set of counters in the scope of that element. Initial counters in the set are received from the element's parent and the preceding sibling. The counter values are received from the last descendent of the previous sibling, the last sibling, or the parent.

When an element declares a counter, the counter is nested inside the counter with the same name received from the parent. If the parent doesn't have a counter with the same name then the counter is added to the element's counters set as it is. A counter with the same name received from the previous sibling is removed from the counters set.

The {{cssxref("counter", "counter()")}} function retrieves the innermost counter with the provided name. And the {{cssxref("counters", "counters()")}} function retrieves the entire counter tree with the given name.

In the following example, we are demoing an inherited counter named `primary` and a sibling counter named `secondary`. All the `<div>` elements display their counters using the `counters()` function. Note that all the counters have been created using `counter-reset` property, and none of the counters have been incremented.

```html
<section>
counter-reset: primary 3
<div>A</div>
<div>B</div>
<div>C</div>
<div class="same-primary-name">D</div>
<span> counter-reset: primary 6</span>
<div>E</div>
<div class="new-secondary-name">F</div>
<span> counter-reset: secondary 5</span>
<div>G</div>
<div>H</div>
<div class="same-secondary-name">I&nbsp;</div>
<span> counter-reset: secondary 10</span>
<div>J&nbsp;</div>
<div>K</div>
<section></section>
</section>
```

```css hidden
.same-primary-name,
.new-secondary-name,
.same-secondary-name {
display: inline-block;
}

@counter-style style {
system: numeric;
symbols: "" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10";
}
```

```css
/* create 'primary' counter on divs' parent */
section {
counter-reset: primary 3;
}

div::after {
content: " ('primary' counters: " counters(primary, "-", style)
", 'secondary' counters: " counters(secondary, "-", style) ")";
color: blue;
}

/* create new 'primary' counter */
.same-primary-name {
counter-reset: primary 6;
}

/* create 'secondary' counter on div 'F' */
.new-secondary-name {
counter-reset: secondary 5;
}

/* override the sibling 'secondary' counter */
.same-secondary-name {
counter-reset: secondary 10;
}
```

{{EmbedLiveSample("Counter inheritance and propagation", "100%", 250)}}

The section element initializes a counter named `primary` with value `3`, and all the child `<div>`s receive the inherited `primary` counter. The element 'D' creates a new `primary`(value `6`) counter which gets nested in the counter received from the parent, so the element has two counters named `primary` with values `3` and `6`.

The element 'F' creates the `secondary`(value `5`) counter for the first time, and it passes the counter to the next sibling 'G'. The element 'G' passes the counter to the next element 'H' and so on. Next, the element 'I' creates a new counter with the same name `secondary`(value `10`), but it drops the `secondary`(value `5`) counter received from the previous sibling 'H' and passes its own counter to 'J'.

### Difference between counter-set and counter-reset

The {{cssxref("counter-set")}} property updates an existing counter and if no counter with the name exists then a new counter is instantiated. The {{cssxref("counter-reset")}} property _always_ creates a new counter.
Expand All @@ -151,43 +229,49 @@ In the following example, we have two sub-lists inside a parent list. Each list

```html
<ul class="parent">
<li>one</li>
<li>two</li>
<li>A</li>
<li>B</li>
<li>
three (the counter updated using `counter-set`)
C (the counter updated using `counter-set`)
<ul class="sub-list-one">
<li>sub-one</li>
<li>sub-two</li>
<li>sub-A</li>
<li>sub-B</li>
</ul>
</li>
<li>four</li>
<li>D</li>
<li>
five (a new counter created using `counter-reset`)
E (a new counter created using `counter-reset`)
<ul class="sub-list-two">
<li>sub-one</li>
<li>sub-two</li>
<li>sub-three</li>
<li>sub-A</li>
<li>sub-B</li>
<li>sub-C</li>
</ul>
</li>
<li>six</li>
<li>seven</li>
<li>F</li>
<li>G</li>
</ul>
```

```css hidden
ul {
list-style: none;
}
```

```css
/* show numbers on list items */
li::before {
content: counter(item) " ";
/* create a new counter for the first time */
.parent {
counter-reset: item 0;
}

/* increment the counter on each list item */
li {
counter-increment: item;
}

/* create a new counter for the first time */
.parent {
counter-reset: item 0;
/* show numbers on list items */
li::before {
content: counter(item) " ";
}

/* change the existing counter value */
Expand All @@ -203,7 +287,7 @@ li {

{{EmbedLiveSample("Difference between counter-set and counter-reset", "100%", 300)}}

Notice how the first sub-list items start receiving numbers starting from `11`, and the numbering is continued in the parent list. This is because the `counter-set` property updates the same 'item' counter. Then notice how the second sub-list items receive new numbering starting from '1' and the parent list items after it don't carry forward the numbering. This is because the `counter-reset` property created a new counter with the same name so the parent list items kept using the old counter.
Notice how the first sub-list items start receiving numbers from `11`, and the numbering is continued in the parent list. This is because the `counter-set` property updates the same 'item' counter declared on the `.parent` element. Then notice how the second sub-list items receive new numbering starting from '1' and the parent list items after it don't carry forward the numbering. This is because the `counter-reset` property created a new counter with the same name so the parent list items kept using the old counter.

### List item counters

Expand Down

0 comments on commit cb6099c

Please sign in to comment.