1

Given some css selector that returns a set of matching elements from the document. Is there any way within css to take the resulting set and target the nth result?

nth-of-type and nth-child pseudoclasses will not work to my understanding because they will not treat all possible matches as a linear list. Such as:

<div>
  <span class="aClass" /> <!-- found by :nth-of-type(1) -->
  <span class="aClass" /> <!-- found by:nth-of-type(2) -->
  <div>
    <span class="aClass" /> <!-- found by :nth-of-type(1) -->
</div>

I want to be able to treat all these occurrences as a linear list of 3 elements, and target one of them independently of where in the document they may be located.

Paulie_D
  • 107,962
  • 13
  • 142
  • 161
Julian
  • 1,665
  • 2
  • 15
  • 33
  • So you want to be able to get the third `` regardless of whether it is a direct descendant or a grandchild descendant of the parent element? Is that correct? – JakeParis Feb 18 '16 at 19:05
  • Yes. If it's the third span found in the document, I want to be able to get it reliably as the third node in a set – Julian Feb 18 '16 at 19:09
  • You're looking for `nth-of-class` which does not exist...and even if it did it wouldn't work *between* DOM elements. You need JS...that's what it's for. – Paulie_D Feb 18 '16 at 19:11
  • can we help solve your problem in a different way? Why exactly do you want to target an element by its index in the selector set, rather than by traversing the DOM naturally? – andi Feb 18 '16 at 19:32

4 Answers4

2

I don't think this is possible as you described it. A general rule of CSS is that queries can delve deeper, and occasionally they can move "sideways" along the tree through a set of neighbors (and for that matter, only in one direction), but they can never take information from one node, traverse upward, go into a neighbor, and apply that information to another node. An example:

<div>
  <div class="relevant">
    <!-- *whistles spookily* - "Zis WILL be the last time you see me!" -->
  </div>
  <span class="myCssTarget"></span>
</div>

The comment in that HTML is a space that is, for all intents and purposes, "invisible" to myCssTarget. If I added any HTML inside of there, then it could never directly affect the span outside.

I could offer further suggestions if you offer a specific situation, but this may be either a call for a redesign of the components you're putting in, or perhaps a JavaScript-based solution.

Katana314
  • 8,429
  • 2
  • 28
  • 36
1

I just saw some clarification to the question. Here is a much simpler fiddle to get all spans with "aClass" into a list that will let you target the nTh span. Still using Jquery instead of CSS.

https://jsfiddle.net/h2e0xgwf/6/

$(document).ready(function(){
var nTh = 5;  // change this to whichever N you wish
var allSpans = $("div > span.aClass");
$(allSpans[nTh-1]).html($(allSpans[nTh-1]).html() + " : found the " + nTh + "th element").css("background-color", "blue").css("color","white");



 });
aemorales1
  • 312
  • 3
  • 13
0

I know that there is no way to do that within CSS. You can select the nth element of the given class name with JavaScript

var elem = getElementsByClassName('.aClass').item(n-1)

or with jQuery

var elem = $('.aClass').toArray().filter(function(elem, i){
    return i==(n-1);
})[0];

user196249
  • 11
  • 3
0

If I understood you correctly you want a linear list of all spans that have class="aClass" who are direct children of a div.

Which means that in your example you will have 2 list of spans, the first list will have 2 elements and the second list will have 1.

You then wish to change the style of all nth children; for example changing the firsts' style would cause 2/3 spans to be affected: the two directly under a new div. And if you were to change the second child, only 1/3 spans would be affected.

If that is what you are looking for I don't believe it can be done in CSS but it can be done in JQuery. I created a fiddle with an example just in case my understanding of your question was correct.

https://jsfiddle.net/h2e0xgwf/4/

$(document).ready(function(){
var nTh = 3;  // change this to whichever N you wish
var rowsOfSpans = new Array();
var divsWithChildren = $("div:parent");
for(var i = 0; i < divsWithChildren.length; i++){
  rowsOfSpans[i] = $(divsWithChildren[i]).children("span.aClass");
}

for(var i = 0; i < rowsOfSpans.length; i ++){
  for(var j =0; j < rowsOfSpans[i].length; j++){
      if(j == nTh-1){
      // THIS IS THE NTH ELEMENT
      $(rowsOfSpans[i][j]).html($(rowsOfSpans[i][j]).html() + " : found the " + nTh + "th element").css("background-color", "blue").css("color","white");
    }
  }
}


});
aemorales1
  • 312
  • 3
  • 13