6
<div class="test">
    <div class="test1"></div>
    <div class="test2"></div>
    <div class="test3"></div>
</div>

why

.test3:nth-of-type(3) {height: 100px;background: black;}

work, but

.test3:nth-of-type(1) {height: 100px;background: black;}

not? Is nth-type-of work same as nth-child in this case?

Ben
  • 73
  • 1
  • 5

3 Answers3

8

The nth-of-type pseudo selector is certainly working here as expected.

From MDN:

The :nth-of-type(an+b) CSS pseudo-class matches an element that has an+b-1 siblings with the same element name before it in the document tree

So

.test3:nth-of-type(3) {height: 100px;background: black;}

'works' because the div with class test3 also happens to be the third div within the container (div with class test)

however

.test3:nth-of-type(1) {height: 100px;background: black;}

doesn't select the test3 div because it isn't the first div in the container

Is nth-of-type work same as nth-child in this case?

In this case they are the same because all of the children in the container are divs.


In general, it could help to think about pseudo classes as a filter which matches only a subset of the matched selector (ie the part of the selector before the colon) when it is in the state that the pseudo class describes.

So for example .test:hover means: select all elements with class test - but only the ones which are being hovered.

Similarly here with nth-of-type: .test3:nth-of-type(3) means:

Select all elements with class test3, but only if it's the 3rd of that kind of element within it's container.

So take the following demo:

.test:nth-of-type(3) {
  color:red;
}
<div>
  <ul>
    <li class="test">li 1</li>
    <li class="test">li 2</li>
    <li class="test">li 3</li>
    <li class="test">li 4</li>
    <li class="test">li 5</li>
  </ul>
  <span class="test">span 1</span>
  <span class="test">span 2</span>
  <span class="test">span 3</span>
  <span class="test">span 4</span>
  <span class="test">span 5</span>
</div>

Notice that both the third list item and the third span are styled - that's because both have class test and are the third of that kind of element within their container

NB:

When using an nth-of-type pseudo class without limiting it with a type selector - all types will match - as if the universal selector was used.

So for example:

.test:nth-of-type(3) is equivalent to *.test:nth-of-type(3)

Demo:

.test:nth-of-type(3) {
  color:red;
}
<div>
  <fred class="test">fred 1</fred>
  <div class="test">div 1</div>
  <span class="test">span 1</span>
  <p class="test">p 1</p>
  <p class="test">p 2</p>
  <p class="test">p 3</p>
  <p class="test">p 4</p>
  <span class="test">span 2</span>
  <fred class="test">fred 2</fred>
  <fred class="test">fred 3</fred>
  <span class="test">span 3</span>
</div>
Danield
  • 121,619
  • 37
  • 226
  • 255
  • thank you! that is right.By the way, do you have any idea to select something like nth-of-class – Ben Apr 25 '17 at 08:03
  • Unfortunately, CSS doesn't have a `nth-of-class` selector - see [this post](http://stackoverflow.com/questions/5545649/can-i-combine-nth-child-or-nth-of-type-with-an-arbitrary-selector?noredirect=1&lq=1) – Danield Apr 25 '17 at 08:07
  • 1
    Nice answer, well explained! – andreas Apr 25 '17 at 08:30
1

You use .test3 in your selectors, but a class .test3 does only occure one time in your markup. So there are no other elements of .test3.

You can use .test > div to access your direct child divs.

Also, the pattern for nth-of-type is :nth-of-type( <an-plus-b> ). So you can just use

.test > div:nth-of-type(2n+1) { ... } /* or */
.test > div:nth-of-type(odd) { ... }

to get the first and the third (every odd) element.

.test>div {
  margin: 10px;
  padding: 10px;
}

.test > div:nth-of-type(2n+1) {
  height: 100px;
  background: black;
  color: white;
}
<div class="test">
  <div class="test1">1</div>
  <div class="test2">2</div>
  <div class="test3">3</div>
</div>

You can also just access the single child you need with .test > div:nth-of-type(1):

.test>div {
  margin: 10px;
  padding: 10px;
}

.test > div:nth-of-type(1) {
  height: 100px;
  background: black;
  color: white;
}
<div class="test">
  <div class="test1">1</div>
  <div class="test2">2</div>
  <div class="test3">3</div>
</div>

See more information about nth-of-type on MDN.

andreas
  • 16,357
  • 12
  • 72
  • 76
1
.test3:nth-of-type(1) {height: 100px;background: black;}

is not working because the type refers to div and since you have no first child element as div with a class of test3 the css is not applied to it.

If your markup was written like in the example below that selector would work but the selector

.test3:nth-of-type(3) {height: 100px;background: black;}

would not because there is no 3rd element of the type div and class test3

Maybe you'll figure of the importance of the type word in this selector by adding some elements of another type before the first div like in the example below

.test3:nth-of-type(1) {height: 100px;background: black; color: #fff;}
        <div class="test">
         <p class="paragraph">1st eleement of paragraph type</p>
         <div class="test3">1st element of div type</div>
         <div class="test2">2nd element of div type</div>
         <div class="test1">3rd element of div type</div>
        </div>
BozanicJosip
  • 506
  • 6
  • 22