user8796786
user8796786

Reputation:

Modify DOM based on amount of divs after specific class

Is there any way to modify DOM based on amount div after specific class?

For example, if I have a div with a class called row and after that I have 4 div elements. Is there a way to change these 4 div element class depending on how many div elements there are?

Code:

<div class="row">
        <div class="col-1-of-4">
          some content
        </div>
        <div class="col-1-of-4">
          some content
        </div>
        <div class="col-1-of-4">
          some content
        </div>
        <div class="col-1-of-4">
          some content
        </div>
      </div>

Another example I have a div class row again, but this time I want 3 div elements after that, then I would want these div elements to have a class called col-1-of-3, not col-1-of-4. If I would have just 2 div elements after that then class col-1-of-2 and if just one div element then no class at all.:

Code:

<div class="row">
        <div class="col-1-of-3">
          some content
        </div>
        <div class="col-1-of-3">
          some content
        </div>
        <div class="col-1-of-3">
          some content
        </div>
      </div>

Also these div elements with classes called col-1-of-4, col-1-of-3 and col-1-of-2 have their own div elements inside them, but they should stay like they were.

Is it possible to achieve with JavaScript or PHP?

Upvotes: 1

Views: 46

Answers (3)

Dirk
Dirk

Reputation: 831

.row {
  width: 100%;
  display:flex;
  flex-grow: 1;
  margin-bottom: 2px;
}
.col {
  float:left;
  background: rgba(255,0,0,.2);
  text-align: center;
  margin-right: 2px;
}

.col:first-child:nth-last-child(1),
.col:first-child:nth-last-child(1) ~ .col{
    width: calc(100% / 1);
}

.col:first-child:nth-last-child(2),
.col:first-child:nth-last-child(2) ~ .col{
    width: calc(100% / 2);
}

.col:first-child:nth-last-child(3),
.col:first-child:nth-last-child(3) ~ .col{
    width: calc(100% / 3);
}

.col:first-child:nth-last-child(4),
.col:first-child:nth-last-child(4) ~ .col{
    width: calc(100% / 4);
}

.col:first-child:nth-last-child(5),
.col:first-child:nth-last-child(5) ~ .col{
    width: calc(100% / 5);
}
<div class="row">
  <div class="col">1</div>
</div>

<div class="row">
  <div class="col">1</div>
  <div class="col">2</div>
</div>

<div class="row">
  <div class="col">1</div>
  <div class="col">2</div>
  <div class="col">3</div>
</div>

<div class="row">
  <div class="col">1</div>
  <div class="col">2</div>
  <div class="col">3</div>
  <div class="col">4</div>
</div>

<div class="row">
  <div class="col">1</div>
  <div class="col">2</div>
  <div class="col">3</div>
  <div class="col">4</div>
  <div class="col">5</div>
</div>

so this is with float, can be used in a sass/scss mixin to create code automagically. there should be also a flex solution but i dont have it at hand at the moment

Upvotes: 0

Rob W
Rob W

Reputation: 9142

You would need to write conditional blocks to handle this if I'm understanding you correctly (wanting a JS or PHP solution).

Note: It goes without saying that a similar solution can be completed with a CSS-only approach, as outlined here: Can CSS detect the number of children an element has?

Here's an example (using jQuery) with 3 sets of row's, with varying children (2, 3, 4):

$(function() {
  var $rows = $(".row");
  $rows.each(function() {
    $row = $(this);
    var $children = $(">div", $row),
      total = $children.size();

    $children.addClass("col-1-of-" + total);
  });
});
.row {
  border: 1px solid #000;
  margin: 10px;
}

.row > div {
  margin: 10px;
}

.row .col-1-of-2 {
  border: 1px solid #f00;
}

.row .col-1-of-3 {
  border: 1px solid #0f0;
}

.row .col-1-of-4 {
  border: 1px solid #00f;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="row">
  <div>
    some content
  </div>
  <div>
    some content
  </div>
</div>

<div class="row">
  <div>
    some content
  </div>
  <div>
    some content
  </div>
  <div>
    some content
  </div>
</div>

<div class="row">
  <div>
    some content
  </div>
  <div>
    some content
  </div>
  <div>
    some content
  </div>
  <div>
    some content
  </div>
</div>

When you run the snippet, you must inspect the elements. I've added borders so you can see the difference.

Upvotes: 2

Joe Fitzsimmons
Joe Fitzsimmons

Reputation: 1063

Theres a number of ways to achieve this. I'd maybe add another class name so you can easily identify groups of divs, and differentiate between parent and child divs. Does this help you get where you're going? Basically find the number of children in a row and then concatenate that number into the class name.

var x = document.getElementsByClassName('row')[0].childElementCount
var element = document.getElementsByClassName('row')[0];
    element.classList.add(`col-1-of-${x}`);

Upvotes: 0

Related Questions