# CSS – Element number selector
Take a chestnut
The scene of a
Today when writing the hexo-Theme-zhaoo article table of Contents (TOC), there is a requirement that the title is not displayed when the table of contents does not exist.
Abstract the DOM structure:
<aside class="toc-wrap">
<h3 class="toc-title">Article Contents:</h3>
<ol class="toc">.</ol>
</aside>
Copy the code
The most straightforward idea is to match.toc and hide the.toc-title that precedes it if it doesn’t exist. But CSS does not select forward because that would cause backtracking. (See: # How to advise the W3C on Web standards? – Answer by Mr Stephen He)
You need to find a way to save the world by using their common parent element,.toc-wrap. If.toc-wrap has only one child, hide it. As follows:
.toc-wrap
& > :only-child
display none
Copy the code
š° is very simple, but worth thinking about, CSS really can’t “forward choice”?
Scenario 2
Early BootStrap uses a lot of repetitive code when building rasterized layouts, like this:
@media (min-width: 768px) {
.col-md-1 { flex: 0 0 8.33333%; max-width: 8.33333%; }
.col-md-2 { flex: 0 0 16.6667%; max-width: 16.6667%; }
.col-md-3 { flex: 0 0 25%; max-width: 25%; }
.col-md-4 { flex: 0 0 33.3333%; max-width: 33.3333%; }
.col-md-5 { flex: 0 0 41.6667%; max-width: 41.6667%; }
.col-md-6 { flex: 0 0 50%; max-width: 50%; }
.col-md-7 { flex: 0 0 58.3333%; max-width: 58.3333%; }
.col-md-8 { flex: 0 0 66.6667%; max-width: 66.6667%; }
.col-md-9 { flex: 0 0 75%; max-width: 75%; }
.col-md-10 { flex: 0 0 83.3333%; max-width: 83.3333%; }
.col-md-11 { flex: 0 0 91.6667%; max-width: 91.6667%; }
.col-md-12 { flex: 0 0 100%; max-width: 100%; }}@media (min-width: 992px) {
.col-lg-1 { flex: 0 0 8.33333%; max-width: 8.33333%; }
.col-lg-2 { flex: 0 0 16.6667%; max-width: 16.6667%; }
.col-lg-3 { flex: 0 0 25%; max-width: 25%; }
.col-lg-4 { flex: 0 0 33.3333%; max-width: 33.3333%; }
.col-lg-5 { flex: 0 0 41.6667%; max-width: 41.6667%; }
.col-lg-6 { flex: 0 0 50%; max-width: 50%; }
.col-lg-7 { flex: 0 0 58.3333%; max-width: 58.3333%; }
.col-lg-8 { flex: 0 0 66.6667%; max-width: 66.6667%; }
.col-lg-9 { flex: 0 0 75%; max-width: 75%; }
.col-lg-10 { flex: 0 0 83.3333%; max-width: 83.3333%; }
.col-lg-11 { flex: 0 0 91.6667%; max-width: 91.6667%; }
.col-lg-12 { flex: 0 0 100%; max-width: 100%; }}Copy the code
This can be simplified with CSS preprocessors, but there is still a lot of repetitive code after compilation.
for $i in 1.12
.col-{$i}
col-attr round(($i * 100 / 12) %, 6)
@media (min-width 576px)
for $i in 1.12
.col-sm-{$i}
col-attr round(($i * 100 / 12) %, 6)
@media (min-width 768px)
for $i in 1.12
.col-md-{$i}
col-attr round(($i * 100 / 12) %, 6)
@media (min-width 992px)
for $i in 1.12
.col-lg-{$i}
col-attr round(($i * 100 / 12) %, 6)
@media (min-width 1200px)
for $i in 1.12
.col-xl-{$i}
col-attr round(($i * 100 / 12) %, 6)
Copy the code
Soul searching, is CSS really not suitable for dealing with “repeated elements” scenarios?
Front knowledge
Some CSS3 selectors:
>
Child element selector+
Adjacent element selector~
Sibling element selector
Some CSS3 pseudo-classes:
:only-child
The unique child of the parent element:first-child
The first child of the parent element:last-child
The last child of the parent element:nth-child(n)
The NTH child of the parent element:nth-last-child(n)
The penultimate NTH child of the parent element:nth-child(xn+y)
The xN + y child of the parent:nth-last-child(xn+y)
The penultimate xN + y child of the parent
A chemical reaction
Combining the above selectors with pseudo-classes can lead to some interesting “chemistry” that matches styles based on the number of elements.
The DOM structure is as follows:
<ul>
<li>1</li>
<li>2</li>
<li>3</li>.</ul>
Copy the code
AndrĆ© LuĆs
Andre Luis:
/* There is only one element */
ul>li:nth-child(1):nth-last-child(1) { width: 100%; } /* matches the first element */
ul>li:only-child { width: 100%; } /* matches the first element */
Copy the code
/* with only two elements */
ul>li:nth-child(1):nth-last-child(2), /* matches the first element */
ul>li:nth-child(2):nth-last-child(1) { /* matches the second element */
width: 50%; /* matches all elements */
}
Copy the code
/* with three and only three elements */
ul>li:nth-child(1):nth-last-child(3),
ul>li:nth-child(2):nth-last-child(2),
ul>li:nth-child(3):nth-last-child(1) {
width: 33.3333%;
}
Copy the code
Clever lists with CSS3 selectors
Lea Verou
One problem with the above scheme is that when there are too many elements, there are still a large number of repeat selectors. The upgraded Lea Verou solution requires only two fixed lines of selectors.
/* There is only one element */
ul>li:first-child:nth-last-child(1) {
width: 100%;
}
Copy the code
/* with only two elements */
ul>li:first-child:nth-last-child(2),
ul>li:first-child:nth-last-child(2) ~ li {
width: 50%;
}
Copy the code
/* with three and only three elements */
ul>li:first-child:nth-last-child(3), /* matches the first element */
ul>li:first-child:nth-last-child(3) ~ li { /* Matches all elements except the first */
width: 33.3333%;
}
Copy the code
Styling elements based on sibling count
To improve
When the number of elements is not determined:
/* > three elements */
ul>li:first-child:nth-last-child(n+3),
ul>li:first-child:nth-last-child(n+3) ~ li {
width: calc(100% / n);
}
Copy the code
conclusion
The above method can solve the problems of forward selection and repeated elements, and the parent element can be used flexibly in the actual scene.