28

I don't know if there is a CSS selector can do the same as the line below (jQuery code):

.tab_cadre_central .top:eq(0) table tbody tr td table tbody tr:eq(3)

I have tried in CSS something like this:

.tab_cadre_central .top::nth-child(0) table tbody tr td table tbody nth-child:eq(3) {
    display:none;
}

but it didn't work.

SharpC
  • 6,974
  • 4
  • 45
  • 40
user2077308
  • 451
  • 1
  • 4
  • 9
  • To answer your question title, no, there is no standard CSS equivalent to `:eq()` in jQuery. See [jQuery difference between :eq() and :nth-child()](http://stackoverflow.com/questions/7039966/jquery-difference-between-eq-and-nth-child) – BoltClock Feb 22 '13 at 10:01

2 Answers2

49

While jQuery's :eq() uses 0-based indexing, :nth-child() uses 1-based indexing, so you need to increment your indexes appropriately:

.tab_cadre_central .top:nth-child(1) table tbody tr td table tbody tr:nth-child(4)

But you should really think about refactoring that selector...


⚠ It's worth noting that although :eq() and :nth-child() can behave similarly - they are certainly not the same. :eq() will select the n+1 th element in the set while :nth-child() will select all elements in the set that are the n th child of their respective parents. ⚠

<div>
    <span></span>
    <span></span>
</div>
<div>
    <span></span>
</div>

The selector div span:nth-child(1) will fetch two elements, while div span:eq(0) will only select one.

Dennis
  • 32,200
  • 11
  • 64
  • 79
  • i agree, this does look a bit tedious – kabuto178 Feb 22 '13 at 02:51
  • 4
    That's not the only difference. In fact, unless the HTML is extremely restricted, this selector may match more elements than is necessary - or *not match at all*. The OP will need to ensure themself that their HTML actually matches both selectors. – BoltClock Feb 22 '13 at 09:40
  • @BoltClock Added a warning - I had thought about it earlier and probably should have because the difference is pretty subtle to someone unfamiliar with it. – Dennis Feb 22 '13 at 12:07
  • so eq:(0) will select the 2nd span tag since its n+1.. right? – Imran Bughio May 25 '15 at 13:49
  • 1
    @ImranBughio No, `:eq(0)` will select the first span element in the first div. `:nth-child(1)` will select the first span element in each div. It looks like I phrased that poorly in my answer. – Dennis Jun 10 '15 at 02:29
  • BoltClock is right, the HTML must be extremely restricted for this to work long term. I added another answer that uses a better selector `:nth-of-type()` – David Lopez Dec 14 '19 at 02:41
11

The top answer will only work under very strict circumstances and a limited HTML structure. It will lead to issues when you are trying to select elements by a CSS class or other trait. Let me explain, in the following code:

<div class="divWrapper">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <br>
    <div>4</div>
    <div>5</div>
    <div>6</div>
    <br>
    <div>7</div>
    <div>8</div>
    <div>9</div>
</div>

Let's say we want to give the 7th div within .divWrapper a light blue background, if you thought this would work, you are wrong:

.divWrapper > div:nth-child(7) {
  background: lightblue;
}

This happens because even though we selected children that are divs, :nth-child() actually counts not only divs, but all HTML elements within that scope as valid children, therefore the code above paints the 6th div instead of the 7th, because it considered the <br> tag in-between as a valid child. This can make things very confusing and break the intended design of your website if you were to add new HTML elements.

This is why I recommend using :nth-of-type() instead, if you are trying to target a CSS class or other attributes, just like with :eq() in jQuery.

This does the job:

.divWrapper > div:nth-of-type(7) {
  background: lightblue;
}

You can see this example in this codepen: https://codepen.io/techbawz/pen/ZEYpBPe or you can run the code directly on this answer.

Hope this helps.

.divWrapper {
  width:100%;
  text-align: center;
}

.divWrapper > div {
  color: white;
  width: 50px;
  height: 20px;
  background: black;
  display: inline-block;
  margin: .5em;
}

/* We paint the first div within divWrapper green. Works fine! So far... */
.divWrapper > div:nth-child(1) {
  background: green;
}

/* We try to paint the 7th div red. It doesn't work, because our selector is not only considering all divs that are childs of divWrapper, but also the <br> tags that are HTML tags which are children of divWrapper  */
.divWrapper > div:nth-child(7) {
  background: red;
}

/* using nth-of-type, our selector DOES paint the 7th div */
.divWrapper > div:nth-of-type(7) {
  background: lightblue;
}
<div class="divWrapper">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <br>
    <div>4</div>
    <div>5</div>
    <div>6</div>
    <br>
    <div>7</div>
    <div>8</div>
    <div>9</div>
</div>
David Lopez
  • 305
  • 3
  • 6