Frontend developers have long known that CSS nth-child
selectors may be combined to yield interesting and practical results. Most commonly, this technique is applied to select all items in a list when there are more than N children, less than N children, exactly N children, or between N and M children. However these simple selectors may also be combined in other ways to produce even more advanced selectors.
Modulo Selector
The CSS modulo selector can be used to select only the remaining items (quotient) after dividing a list of items by a number n. This can be used in conjunction with a grid system to ensure that all rows are filled evenly by hiding extra elements. This is particularly useful for responsive designs in which the number of columns changes between viewports, yet the desire is to keep all rows filled evenly.
Note: I recommend hiding only unnecessary elements, and I discourage loading more content than necessary on any device, particularly on mobile devices.
See the Pen CSS Modulo Quantity Query Selector by Joey Hoer (joeyhoer).
This technique is accomplished by selecting the final element in a complete group (i.e. full row) using nth-child(an)
(where a
is the divisor), and then counting backwards from the last element using nth-last-child(b)
(where b
is a number between 2
and the divisor) until that element is matched. Once the element is found, the general sibling combinator (~
) is used to select the remaining items in the list.
/* Modulo 4 */
ul > *::nth-child(4n):nth-last-child(2) ~ *,
ul > *::nth-child(4n):nth-last-child(3) ~ *,
ul > *::nth-child(4n):nth-last-child(4) ~ * { }
Note: We begin with 2
because nth-last-child(1)
will always be the last-child
, and when nth-child(an)
matches last-child
, there is no remainder.
This approach works great except when n
is 0
, as there is then no element to match. This means that the first group is never selected. To overcome this challenge, an additional less-than quantity query may used to select items in an incomplete first group/row.
Middle Element Selector
The CSS middle element selector is used to select the middle element in a list of elements. This is particularly useful when used with the general sibling combinator (~
) to select items in the second half of a list. This technique can be used add a different background to half of a list, and to anchor menus to the right rather than the left and prevent overflow on the right side of the screen.
See the Pen CSS Middle Child Selector by Joey Hoer (joeyhoer).
Unfortunately, this technique produces a lot of generated code, and while the required code is very repetitive and therefore quite compressible, it is inelegant because it is difficult to maintain and scale because a maximum number of elements must be known in advance.
This technique is accomplished using :nth-child(b)
and :nth-last-child(b)
in equal measure by incrementing b
from the start until the median is matched. Because this technique requires a unique selector for each distinct quantity, the total number of required selectors is at least half of the maximum list size. If a list minimum is also known, the number of overall selectors required may be reduced further.
/* Exact middle element of a list of 6–14 elements */
ul > *:nth-child(3):nth-last-child(3),
ul > *:nth-child(4):nth-last-child(4),
ul > *:nth-child(5):nth-last-child(5),
ul > *:nth-child(6):nth-last-child(6),
ul > *:nth-child(7):nth-last-child(7) {}
Lists with an even count present an issue, as they do not have a median. In this case, the developer must choose either to select the preceding element, the following element, both elements or neither. Selecting both elements requires an additional CSS selector, effectively doubling the number of selectors required.
These selectors may combined with the general sibling combinator (~
) to select the items in the second half of the list. Because the general sibling combinator is not inclusive (meaning that the current element is not selected) it will typically be desired to target the “after” method when selecting even numbered lists, and add an additional selector to make the list inclusive. This technique also doubles the number of selectors required.
There is no way to select only the first half of a list using this method.
Half of Elements Selector
To work around the limitations of the middle element selector, the CSS half of elements selector can select both the first half of a list, and the second half of a list using a fraction of the number of required selectors.
See the Pen CSS Half Selector by Joey Hoer (joeyhoer).
This technique is accomplished using :nth-child(-n+b)
and :nth-last-child(n+b)
, incrementing b
until the median is matched. The n
value overlaps either in a positive or negative direction from the median, based on the signs associated with the nth-child
and nth-last-child
equations. Because this technique requires a unique selector for each distinct quantity, the total number of required selectors is at least half of the maximum list size. Fortunately, this technique is also very repetitive and compressible.
/* First half of elements in list of 1–14 elements */
ul > *:nth-child(-n+1):nth-last-child(n+1),
ul > *:nth-child(-n+2):nth-last-child(n+2),
ul > *:nth-child(-n+3):nth-last-child(n+3),
ul > *:nth-child(-n+4):nth-last-child(n+4),
ul > *:nth-child(-n+5):nth-last-child(n+5),
ul > *:nth-child(-n+6):nth-last-child(n+6),
ul > *:nth-child(-n+7):nth-last-child(n+7),
ul > *:nth-child(-n+8):nth-last-child(n+8) {}
Lists with an odd count present an issue, as they cannot be divided evenly. In this case, the developer must choose whether to select the median element; doing so does not increase the number of selectors required.