Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nth-of-type doesn't work as expected [duplicate]

<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?

like image 646
Ben Avatar asked Apr 25 '17 07:04

Ben


2 Answers

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>
like image 64
Danield Avatar answered Sep 23 '22 00:09

Danield


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.

like image 30
andreas Avatar answered Sep 24 '22 00:09

andreas