nth-of-type es una pseudo-clase que selecciona a los elementos en un grupo de hermanos que coinciden con el patrón especificado y su ordenamiento de origen.

/* Tercer elemento <p> */
p:nth-of-type(3) {
  background: red;
}

/* Todos los elementos impares <p> */
p:nth-of-type(2n+1) {
  background: blue;
}

La forma en la que se construye dicho patrón es usando palabras clave, valores enteros, una fórmula e incluso selectores.

<ul>
  <li>Elemento 01</li>
  <li>Elemento 02</li>
  <li>Elemento 03</li>
  <li>Elemento 04</li>
  <li>Elemento 05</li>
</ul>
li:nth-of-type(patrón) { ... }

nth-of-type(3)

Selecciona solo el tercer elemento del grupo de hermanos.

p:nth-of-type(3) {
  background: red;
}
Nota

Para más detalles sobre que patrones podrías aplicar, te recomiendo ver :nth-child.

nth-child vs. nth-of-type

Las pseudo-clases son completamente iguales en el caso de tener los mismos elementos dentro de un padre, no hay una diferencia visual.

<section>
  <p>Elemento 01</p>
  <p>Elemento 02</p>
  <p>Elemento 03</p>
  <p>Elemento 04</p>
  <p>Elemento 05</p>
</section>
p:nth-child(2) {
  background: pink;
}

p:nth-of-type(2) {
  background: yellow;
}
nth-child(2)
nth-of-type(2)

La diferencia radica cuando hay otro tipo de elementos dentro del padre.

<section>
  <strong>Elemento 01</strong>
  <p>Elemento 02</p>
  <p>Elemento 03</p>
  <p>Elemento 04</p>
  <p>Elemento 05</p>
</section>
p:nth-child(2) {
  background: pink;
}

p:nth-of-type(2) {
  background: yellow;
}

Esto pasa porque nth-child comprueba que el elemento sea exactamente el segundo hijo del padre y que también sea un elemento <p>. Se enfoca en la posición y el elemento.

Mientras que nth-of-type comprueba que se seleccione el segundo elemento <p> del padre. Se enfoca en el tipo de elemento.

Nota

Es decir, nth-child es más estricto al momento de buscar una coincidencia.

Otra forma de verlo es que nth-child comienza a contar desde el primer elemento del padre, sin importar el tipo y nth-of-type comienza a contar desde el elemento especificado.

Para nth-child el conteo sucede así:

<section>
  <strong>Elemento 01</strong> <!-- Primer elemento -->
  <p>Elemento 02</p> <!-- Segundo elemento -->
  <p>Elemento 03</p> <!-- Tercer elemento -->
  <p>Elemento 04</p> <!-- Cuarto elemento --> 
  <p>Elemento 05</p> <!-- Quinto elemento -->
</section>

Y para nth-of-type el conteo sucede así:

<section>
  <strong>Elemento 01</strong> <!-- No cuenta -->
  <p>Elemento 02</p> <!-- Primer elemento -->
  <p>Elemento 03</p> <!-- Segundo elemento -->
  <p>Elemento 04</p> <!-- Tercer elemento --> 
  <p>Elemento 05</p> <!-- Cuarto elemento -->
</section>

Tomando esos detalles en cuenta, el siguiente código no tendría efecto para nth-child:

p:nth-of-type(1) {
  background: yellow;
}


p:nth-child(1) {
  background: pink;
}

¿Por qué?

Porque sencillamente el primer elemento no es un <p>, sino un <strong> y no se cumple la condición para nth-child. Pero, si para nth-of-type.

Recursos