Can I combine :nth-child() or :nth-of-type() with an arbitrary selector?

When it comes to selecting specific elements in CSS, pseudo-classes like :nth-child() and :nth-of-type() can be really useful. These pseudo-classes allow us to select elements based on their position in relation to their parent or siblings. However, there seems to be confusion around whether these pseudo-classes can be combined with an arbitrary selector. In this article, we will explore this topic and provide some solutions.

Understanding :nth-child() and :nth-of-type()

Before we delve into combining these pseudo-classes with an arbitrary selector, let's first understand how they work individually.

:nth-child() selects elements based on their position among all the children of their parent. For example, :nth-child(odd) selects every odd child element.

:nth-of-type() is similar to :nth-child(), but it selects elements based on their position among elements of the same type within the parent. For instance, :nth-of-type(odd) selects every odd child element of the same type.

Selecting every nth child within a subset

Now, let's get to the main question: Can we combine :nth-child() or :nth-of-type() with an arbitrary selector?

Unfortunately, the answer is no. These pseudo-classes do not take the selector into account when calculating the position of the element. They simply count all the children or elements of the same type within the parent.

So, in your example, table.myClass tr.row:nth-child(odd) selects every odd child row of the table, regardless of whether or not they have the "row" class. That's why you end up with only one element instead of the two you were expecting.

Possible workarounds

Although we cannot directly combine :nth-child() or :nth-of-type() with an arbitrary selector, we can achieve similar results using other CSS techniques. Here are some possible workarounds:

Option 1: Combine selectors in a different order

If possible, you can try combining selectors in a different order to achieve the desired result. For example:

tr.row:nth-child(odd) {/* styles */}

This selects every odd table row that has the "row" class. However, this approach may not work in all cases, especially when the class you want to target is not a direct child of the parent element.

Option 2: Use JavaScript or jQuery

If CSS alone doesn't provide a suitable solution, you can use JavaScript or jQuery to achieve the desired effect. Here's an example using jQuery:

$(".myClass tr.row:nth-child(odd)").addClass("selected");

This code selects every odd table row with the "row" class and adds the "selected" class to them. You can then style the "selected" class as desired.

Option 3: Add a class to the elements you want to select

If you have control over the HTML markup, you can add a specific class to the elements you want to select. For example:


<table class="myClass">
  <tr>
    <td>Row
  <tr class="row selected"> 
    <td>Row
  <tr class="row">
    <td>Row
  <tr class="row selected"> 
    <td>Row
</table>
        

Then, you can easily select these elements by their class:

.myClass tr.row.selected {/* styles */}

Conclusion

Although it is not possible to directly combine :nth-child() or :nth-of-type() with an arbitrary selector, there are workarounds available. By combining selectors in a different order, using JavaScript or jQuery, or adding a class to the elements you want to select, you can achieve similar results. It's important to remember that CSS has its limitations, but with a bit of creativity and problem-solving, you can find solutions to meet your styling needs.