15

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

p :nth-child(1)
  • 12
    "Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration." -- Stan Kelly-Bootle – Mason Wheeler Apr 2 '16 at 10:10
  • 1
    Since I suspect this will draw a few close votes, I am leaving this open because it is at least theoretically possible to answer this objectively by either citing other examples of 1-indexing in CSS and claiming consistency, or finding a relevant statement from one of the people who actually makes CSS standards decision. I don't know nearly enough about CSS to do that myself, but as long as we don't upvote any answers that make the obvious "it's how normal humans count" argument without any justification for why everything else is 0-indexed, then there's no harm in leaving this open. – Ixrec Apr 2 '16 at 14:06
  • 1
    @lxrec: I think it is a claim that "everything else is 0-indexed" which should be justified. You don't say Queen Elizabeth the Zeroth, The zeroth day of Christmas, the zeroth street to the left or the zeroth word on the page. – JacquesB Apr 2 '16 at 16:05
  • @lxrec In my answer XPath is cited as a precedent for 1-based indexing. Not sure if it actually was a factor, or just a coincidence, but it's another XML focused system so it makes sense. – user949300 Oct 17 '17 at 4:26
15

If you count your own children you would say "my first child", "my second child" and so on, not "my zeroth child". This is simply how humans count. (Note: This is not some subjective opinion by me. This is literally how ordinal numbers works.)

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[0] means address of first item, array[1] means address of the first item plus the size of 1 item, i.e. second item and so on.

Many higher-level languages which does not support pointer arithmetic directly have retained the 0-based indexing for consistency and familiarity. For example all languages with C-derived syntax - including JavaScript, even though arrays in JavaScript are implemented in a completely different way. But this is not at all universal - languages like COBOL, Fortran, Lua and some Basic's use 1-based indexing. (Visual Basic naturally chose the worst of both worlds by making it configurable.) So it is definitely not like every other language use 0-based indexing. For what its worth, XPath and XQuery also use 1-based indexing.

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 chose 1-based indexing.

  • 1
    "Why numbering should start at zero" – gnat Apr 2 '16 at 10:28
  • 1
    it would help if your answer mention that you believe CSS is primarily intended for use by non-programmers (preferably backed up somehow) – gnat Apr 2 '16 at 10:48
  • 1
    @gnat Is there anywhere in programming any item where a child is said to be the zeroth? Since the selector is nth-child its logical to start from first. – Sami Kuhmonen Apr 2 '16 at 15:22
  • 1
    Can you delete everything except the last paragraph? Everything else is common knowledge on this SE. "While most programmers ...... natural to choose 1-based indexing" – 0fnt Apr 2 '16 at 16:31
  • 2
    I don't disagree with your answer, but many things that we count don't start at 1. You are 0 years old for the first year of your life - you don't start out at 1. The day doesn't start at 1:00 a.m. - it starts at 0:00 a.m. When I measure the distance traveled from my house, I start at zero. Counting from zero is just as natural for human beings as counting from one - it depends on the context, although you are right that we would never speak of our zeroeth child :) – Aaron Rasmussen Apr 2 '16 at 20:52
6

From the CSS Level 3 Selector Specification:

6.6.5.2. :nth-child() pseudo-class

The :nth-child(an+b) pseudo-class notation represents an element that has an+b-1 siblings before it in the document tree, for any positive integer or zero value of n, and has a parent element. For values of a and b greater than zero, this effectively divides the element's children into groups of a elements (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 a and b values 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.

When a=0, the an part need not be included (unless the b part is already omitted). When an is not included and b is non-negative, the + sign before b (when allowed) may also be omitted. In this case the syntax simplifies to :nth-child(b).

If both a and b are equal to zero, the pseudo-class represents no element in the document tree.

Additional formatting in the last paragraph is mine to add emphasis.

0

Probably for consistency with XPath, another XML / HTML processing language. Which begs the question, why does XPath use 1 based indexing?

See https://stackoverflow.com/questions/3319341/why-do-indexes-in-xpath-start-with-1-and-not-0

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..."

protected by gnat Oct 17 '17 at 5:24

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.