Why does :nth-child() iterate from one instead of zero?
As shown in this example. Why does it select the first element and not the second when
Software Engineering Stack Exchange is a question and answer site for professionals, academics, and students working within the systems development life cycle. It only takes a minute to sign up.Sign up to join this community
CSS uses ordinal numbering when identifying elements in an ordered collection. For example
:first-child matches the first child element of a parent,
@page :first matches the first page,
::first-line matches the first line in a block, and
::first-letter matches the first letter of the first line of a block.
:nth-child() pseudo-class is a generalization of the
:first-child selector, where you read n as the provided number. So
:nth-child(1) means 1st child or first-child,
:nth-child(2) means 2nd child and so forth.
So it is natural that
:nth-child(1) select the first child, and it would be highly confusing and illogical if it selected the second child!
CSS uses ordinal numbering because this is how humans naturally talk about such elements. You say the first paragraph of a text, not the zeroth paragraph or paragraph-zero.
The reason you even ask the question is probably because you are a programmer, and many programming languages indexes array and list items from 0. The reason for this is that in low level languages like C, an array is really a pointer to the memory address of the first item and the index is an offset relative to this pointer. So
array means address of first item,
array means address of the first item plus the size of 1 item, i.e. second item and so on.
While most programmers will be familiar with both 1 and 0-based indexing, normal people will naturally count from 1, and CSS is a language designed not just for programmers but for designers and graphic professionals, so it is natural to choose 1-based indexing.
From the CSS Level 3 Selector Specification:
188.8.131.52. :nth-child() pseudo-class
:nth-child(an+b)pseudo-class notation represents an element that has
an+b-1siblings before it in the document tree, for any positive integer or zero value of
n, and has a parent element. For values of
bgreater than zero, this effectively divides the element's children into groups of
aelements (the last group taking the remainder), and selecting the
bth element of each group. For example, this allows the selectors to address every other row in a table, and could be used to alternate the color of paragraph text in a cycle of four. The
bvalues must be integers (positive, negative, or zero). The index of the first child of an element is 1.
It goes into a lot more detail with examples. It appears to be that the final calculation of
an+b must total to a positive number.
a=0, the an part need not be included (unless the
bpart is already omitted). When
anis not included and
bis non-negative, the + sign before
b(when allowed) may also be omitted. In this case the syntax simplifies to
bare equal to zero, the pseudo-class represents no element in the document tree.
Additional formatting in the last paragraph is mine to add emphasis.
Probably for consistency with XPath, another XML / HTML processing language. Which begs the question, why does XPath use 1 based indexing?
The relevant (but controversial quote) is:
"...1-based logic was the right choice for XPath and XSLT...because the language was designed for users, not for programmers, and users still have this old-fashioned habit of referring to the first chapter in a book as Chapter One..."