36

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)
user51349
  • 477
  • 1
  • 4
  • 3
  • 33
    "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 02 '16 at 10:10
  • 2
    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 02 '16 at 14:06
  • 4
    @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 02 '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 04:26

3 Answers3

48

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.

The :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) selects 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 index 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 do 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, Julia 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 it's 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 choose 1-based indexing.

Pang
  • 313
  • 4
  • 7
JacquesB
  • 57,310
  • 21
  • 127
  • 176
  • 6
    ["Why numbering should start at zero"](http://programmers.stackexchange.com/a/110822/31260) – gnat Apr 02 '16 at 10:28
  • 4
    @gnat: Would you say my comment here is the first in the thread - because yours is the zeroeth? Humans don't count like that, and CSS is designed for humans, not computer scientists :) – JacquesB Apr 02 '16 at 10:45
  • 2
    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 02 '16 at 10:48
  • 3
    @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 02 '16 at 15:22
  • @SamiKuhmonen [javax.swing.tree.TreeModel.getChild(Object parent, int index)](https://docs.oracle.com/javase/8/docs/api/javax/swing/tree/TreeModel.html#getChild-java.lang.Object-int-) "...index is a valid index for parent (that is index >= 0 && index < getChildCount(parent))" – gnat Apr 02 '16 at 15:40
  • 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 02 '16 at 16:31
  • @0fnt: Apparently it is not common knowledge for everyone, judging by other comments. – JacquesB Apr 02 '16 at 16:44
  • @JacquesB "CSS is designed for humans" - well... if it was, it would have variables, so I could name my `#b64d27` a `link-color-normal` or something. CSS is just a way to create a bunch of rules which fight each other with their specificity, ending up in adding `!important` to all the things. Yeah, that old "intended for use by non-programmers" hairy-tail. – scriptin Apr 02 '16 at 17:03
  • 1
    @scriptin: I just meant CSS is a domain-specfic language designed for a certain audience of designers and web-developers. Some of these may also be programmer, but programmers are only a subset of the audience. That does not mean CSS is necessarily accessible to anyone, e.g. it uses a number of technical terms from typography and design which a programmer without any design background would probably not understand. But any competent web designer would understand a RGB code. – JacquesB Apr 02 '16 at 17:50
  • @scriptin: "intended for use by non-programmers" does not necessary mean easy to use. It just mean you don't expect the audience to have experience with computer science or general purpose programming languages. They might still require highly specific domain expertise. Some of the problems CSS tackle are intrinsically complex. – JacquesB Apr 02 '16 at 18:17
  • 6
    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 02 '16 at 20:52
  • @gnat: The method you quote use 0-based indexing, but the term "zeroth child" is not used. In the DOM, child nodes are also indexed from 0, but the method to get the item at index 0 is called `firstChild()`, not `zerothChild()`. So ordinal numbers start from 1st even in the case of 0-based indexing. – JacquesB Apr 03 '16 at 08:27
  • @scriptin one can argue that absence of variables supports the assumption that language is intended for non-programmers. "Let's spare users from the need to learn yet another programming related thing" – gnat Apr 03 '16 at 08:37
  • 1
    @AaronRasmussen: You should distinguish between ordinal numbers and cardinal numbers. Ordinal numbers are used to identify distinct elements by position, while cardinal numbers are used for amounts. It is the difference between "the third paragraph" and "three paragraphs". You can have zero children but you can't say "my zeroth child". – JacquesB Mar 02 '22 at 16:29
  • 0-indexing makes array arithmetics easier requiring less "minus 1" and parenthesis when doing modulo operations – Felype Mar 08 '22 at 22:55
  • 1
    One of the best answers I've read in terms of readbility to coverage depth ratio. – Marshall Davis Mar 09 '22 at 02:33
10

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.

Adam Zuckerman
  • 3,715
  • 1
  • 19
  • 27
3

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

user949300
  • 8,679
  • 2
  • 26
  • 35