1

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?

miken32
  • 42,008
  • 16
  • 111
  • 154
  • You could use an XPath expression of `//div[@class="row"]/count(div)` which with your first example gives `4`. – Nigel Ren Sep 21 '18 at 16:05
  • sure you can do it with js or php, but is it just for width of col or do you want to achieve something else, because there is a css only solution for dynamic col width based on number of divs – Dirk Sep 21 '18 at 16:08
  • Dirk, yes it is just for for col width. How could I achieve this with css? –  Sep 21 '18 at 16:10
  • give me a second i will create an answer – Dirk Sep 21 '18 at 16:11
  • I have updated my solution to include a pure CSS solution, as previously answered on SO. – Rob W Sep 21 '18 at 16:16

3 Answers3

2

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.

Rob W
  • 9,134
  • 1
  • 30
  • 50
0

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}`);
Joe Fitzsimmons
  • 1,043
  • 1
  • 8
  • 22
0

.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

Dirk
  • 831
  • 6
  • 13