0

I have a HTML which users will enter.

Note: Markup HTML will never look like that. Sometimes this class room will move up, that class room will move down, so on and so forth. Or, they will add more class rooms.

My job is to look for "my-child" class names and style different colors for each my-child: my first child is red, second is green and third is blue.

Problem: I use first-of-type or nth-of-type() (I did use first-chil, too) they all don't work out. So that first-of-type, nth-of-type() or first-child or ~ are not a solution.

jsfiddle

.school .my-child:first-of-type {
      color: red;
    }
    .school .my-child:nth-of-type(2){
      color: green;
    }
    .school .my-child:nth-of-type(3) {
      color:blue;
    }
    <div class="school">
      <div class="class-room">
          <div class="other">Child</div>
      </div>
      <div class="class-room">
          <div class="other">Child</div>
      </div>
      <div class="class-room">
          <div class="other">Child</div>
      </div>
      <div class="class-room">
          <div class="my-child">Child</div>
      </div>
      <div class="class-room">
          <div class="other">Child</div>
      </div>
      <div class="class-room">
          <div class="other">Child</div>
      </div>
      <div class="class-room">
          <div class="other">Child</div>
      </div>
      <div class="class-room">
          <div class="my-child">Child</div>
      </div>
      <div class="class-room">
          <div class="other">Child</div>
      </div>
      <div class="class-room">
          <div class="other">Child</div>
      </div>
      <div class="class-room">
          <div class="my-child">Child</div>
      </div>
      <div class="class-room">
          <div class="other">Child</div>
      </div>
    </div>

5
  • 1
    do you mean you need css' nth-child? Commented May 1, 2019 at 19:09
  • I have tried nth-child, but that doesn't work Commented May 1, 2019 at 19:11
  • 1
    This can't be done by CSS alone, at least not until they implement has(). Is JavaScript an option? Commented May 1, 2019 at 19:13
  • could you do something like: .school .class-room:nth-of-type(4) .my-child { color: red; } ? Commented May 1, 2019 at 19:24
  • First, I am thinking of it could be done by CSS, but it may be difficult. Can it be done by javascript? Commented May 1, 2019 at 19:27

2 Answers 2

2

Add a bit of JavaScript to give each .my-child div a new class: child1, child2 etc. Then target those new classes with the colors.

document.querySelectorAll('.school .class-room .my-child')
  .forEach(function(el, i) {
    el.className += ' child'+(i+1);
  })
.my-child.child1 {
  color: red;
}

.my-child.child2 {
  color: green;
}

.my-child.child3 {
  color: blue;
}

/* add as many more as necessary */
<div class="school">
  <div class="class-room">
    <div class="other">Child</div>
  </div>
  <div class="class-room">
    <div class="other">Child</div>
  </div>
  <div class="class-room">
    <div class="other">Child</div>
  </div>
  <div class="class-room">
    <div class="my-child">Child</div>
  </div>
  <div class="class-room">
    <div class="other">Child</div>
  </div>
  <div class="class-room">
    <div class="other">Child</div>
  </div>
  <div class="class-room">
    <div class="other">Child</div>
  </div>
  <div class="class-room">
    <div class="my-child">Child</div>
  </div>
  <div class="class-room">
    <div class="other">Child</div>
  </div>
  <div class="class-room">
    <div class="other">Child</div>
  </div>
  <div class="class-room">
    <div class="my-child">Child</div>
  </div>
  <div class="class-room">
    <div class="other">Child</div>
  </div>
</div>

Or, if you use jQuery for everything, you can use this for the JavaScript instead:

$('.school .class-room .my-child')
  .each(function(i, el) {
    $(this).addClass('child'+(i+1));
  });
Sign up to request clarification or add additional context in comments.

4 Comments

Hi Mr Lister, Thank you very much for your help! It is very good way. Would you please explain your .JS especially (function(el, i). Thanks!
The function is the parameter to the forEach call of the list, and it takes two arguments: the list element it is working on, and the index of the element it is working on. So the first time through the loop, el is the topmost my-child div and i is 0. And so on for the rest of the list. See also the MDN page on forEach. Or, their page on Array​.prototype​.for​Each(), which explains it much better in my eyes.
Hi Mr. Lister, I'd like to learn how would you convert your JavaScript into JQuery? Thanks
@abcidd Sure; I added the jQuery to my answer just now. It doesn't really gain much though; it's marginally shorter, but not really much more efficient.
1

Unfortunately, the nth-of-type() selector will not work that way. For the following selector, it would:

.school .my-child:nth-of-type(3)

  1. Find all the elements with the selector ".my-child" within the element ".school"
  2. The ".my-child" elements are divs (where the type part comes in)
  3. Look for the third div (the type found above) within the direct parent (siblings, in this case, anything div under ".class-room")
  4. There are not 3 divs in this element. The selector will do nothing.

What you want to do is not currently possible in CSS only. A javascript option would look like this;

let myChildren = document.getElementsByClassName('my-child'); // an array containing all '.my-child' elements

// Iterate over every .my-child element
for(let i = 0; i < myChildren.length; i++){
  if(i % 3 === 0){ // checking that there is no remainder from this operation allows us to get every third
    this.style.color = 'red';
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.