Modern CSS features mean that alternating bulleted list styles can now be styled so that they recur infinitely without needing to deeply nest selectors.
This technique relies on container style queries to check the nearest parent's bullet type, and change to a different type.
⚠ at time of writing, browser support is limited, and those that do support style queries only support style queries on custom properties. So a custom --type
property is used in lieu of list-style-type
. In the future list-style-type
will be able to be queried directly.
First we set up the default list styles. A container name is used to ensure that the queries only apply to list containers. You can update container-name
to whatever name you prefer.
ul {
--type: disc;
container-name: list;
list-style-type: var(--type);
}
Then we query for list containers that have a --type
of disc
, and apply a new --type
to lists within those containers.
@container list style(--type: disc) {
ul {
--type: circle;
}
}
If we stop here, the topmost ul
(level 1: ul
) will have a list-style-type
of disc
because the container query doesn't apply.
Any ul
(level 2: ul ul
) within it will have a list-style-type
of circle
because the container query applies.
A ul
nested within those ul
s (level 3: ul ul ul
) will have a list-style -type
of disc
again because the container query doesn't apply.
This will continue alternating infinitely.
Additional steps can be added to the cycle by adding additional container queries:
@container list style(--type: circle) {
ul {
--type: square;
}
}
Lastly it's worth noting that CSS nesting allows us to nest the container queries to reduce some of the redundant selectors.
ul {
--type: disc;
container-name: list;
list-style-type: var(--type, disc);
@container list style(--type: disc) {
--type: circle;
}
@container list style(--type: circle) {
--type: square;
}
}
<ul>
<li>
<p>1</p>
<ul>
<li>
<p>1.1</p>
<ul>
<li>
<p>1.1.1</p>
<ul>
<li>
<p>1.1.1.1</p>
<ul>
<li>
<p>1.1.1.1.1</p>
<ul>
<li>
<p>1.1.1.1.1.1</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>