0

I have a div containing several child div elements and I want the child elements' width to stretch so that all the child elements fill the width of the containing div, the parent div. I have done a lot of research online about this but haven't found what I'm looking for. For my case there is a vertical scrolling on the parent div when it's children overflow it vertically. I have seen this being done in Zoom and Google Meets. Although what I have witnessed happen in Zoom and Google Meets doesn't have to do with vertical scrolling. There is no vertical scrolling. I tried doing this with jquery/javascript but could not find out why my code isn't working. The child divs width does not stretch so that all the child divs together fit or cover the parent div's width.

$(document).on("ready", function() {
  var child = $(".child").length;
  var childWidth = $(".child").width() + 10; /* child width plus 10 for margin right */
  var parentWidth = $("#parent").width();
  for (var i = 1; i <= child; i++) {
    childWidth = childWidth + 210;
    /*increment child divs width. divs in first   row */
    var remainingSpace = parentWidth - childWidth; /* remaining space in first row of child divs */

    if (remainingSpace < 210) { /* can't fit another 200px plus 10px margin-right div in first row */
      var scalar = remainingSpace / i;
      /*divide remaining space by number of divs in the first row */
      var newChildWidth = 200 + scalar; /* add  scalar to width of all child divs */
      $(".child").css("width", newChildWidth + "px"); /* apply new width to all child divs */
      return false;
      /* stop for iteration because childWidth calculation for  first row is complete */
    }
  }
});
#parent {
  width: 100%;
  /*100% of window width. Which is variable from device to device*/
  height: 100%; /* parent height is 100% of window viewport height */
  overflow: auto;
  text-align: center;
}

.child {
  display: inline-block;
  width: 200px;
  height: 200px;
  margin-right: 10px;
  margin-bottom: 10px;
}
<div id="parent">
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>

I would also accept a pure CSS solution if there are any. Thank you in advance.

3 Answers3

0

I recommend using CSS grid for this type of arrangement.

#parent {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}
.child{
  background: blue;
  height:50px;
  &:nth-child(even){
    background:red;
  }
}

Here's an example: https://codepen.io/andyg2/pen/wvmGEyB

Andy Gee
  • 3,149
  • 2
  • 29
  • 44
0

CSS grid can help here, withut any need for JS.

In this snippet a few things have changed from your original code:

The child divs have been closed with </div> - otherwise they look nested and grid sees only the first div which is a direct child.

The margin right and bottom have been replaced by using a gap when defining the grid.

The width of the children is set at being a minimum of 200px and 1fr (which is telling the grid to spread out any remaining space between all the items on a row).

Each item is given a width of 100% and an aspect-ratio of 1 / 1 so it remains square.

The parent has been given a maximum height of 900px so that on wider viewports the rows remain at 10px apart (otherwise they will evenly distribute the height as well as the width with a large gap vertically).

#parent {
  width: 100%;
  /*100% of window width. Which is variable from device to device*/
  max-height: 900px;
  overflow: auto;
  display: grid;
  grid-gap: 10px;
  /* instead of the margins of 10px on the children */
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

.child {
  width: 100%;
  aspect-ratio: 1 / 1;
  /* to make sure they stay square */
  background: cornflowerblue;
}
<div id="parent">
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>
A Haworth
  • 30,908
  • 4
  • 11
  • 14
  • This seems to achieve my desired outcome. I left out the aspect ratio because I'm only concerned with the width of the child divs. The child divs are too wide on desktops and tablets when there is only one or two child divs inside the parent. I don't know what outcome to suggest. I will appreciate any suggestions and solutions to the suggestions. Also when the child divs don't overflow the parent div vertically they are spaced vertically more than 10px. They should only be 10px apart vertically. I also want the child divs to be centered horizontally. I updated my question. Thanks. – user3777368 Jul 09 '22 at 12:31
  • To stop things being too wide put a max-width on the grid element. I don't see the vertical spacing increasing. Have you set the height of the grid to max-height, not height? Are you seeing too much spacing running my snippet? If so what OS and browser are you using - I'm on Edge/Windows10. – A Haworth Jul 09 '22 at 13:02
  • Setting a max width of 600px on child divs worked. If there is only one child div it dont fill parent div width. I set a fixed height on the child divs instead of letting the child div's height wrap around its contents and they don't fill the parent div's height when there is only one row of child divs . There is a horizontal gap that is more than 10px between the child divs when the total child divs width in one row is lesser than the parent div's width. There is a vertical gap that is more than 10px between the child divs when the child divs don't fill or overflow the parent div's height. – user3777368 Jul 10 '22 at 01:22
  • My suggestion was to set a max width on the giprid element, not on the individual grid items, – A Haworth Jul 10 '22 at 06:03
  • max width 600px works on child divs but not on parent div. When max width is set on parent div the parent div becomes 600px wide and the child divs are constrained in one single vertical line. Any suggestions about the gaps i mentioned earlier? Im sorry this is my first time using gaps. Never knew about it till now. Also align-items center on the parent div works only for one row of the child divs and not on the second row. – user3777368 Jul 10 '22 at 06:30
0

You can achieve this by giving display: table to parent element and display: table-cell to every child element.

HTML CODE

<div id="parent">
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
</div>

CSS

 #parent{
  width: 100%;  /*100% of window width. Which is variable from device to device*/
  height: 900px;
  overflow: auto;
  border: 1px solid magenta;
  display: table;
}

.child{
  width: 200px;
  height: 200px;
  margin-right: 10px;
  margin-bottom: 10px;
  border: 1px solid magenta;
  display: table-cell
}

You can find my codepen demo here - https://codepen.io/sachinsom93/pen/GRxZXbR

Some links you can refer for table display -

  1. How (and why) to use display: table-cell (CSS)

  2. https://developer.mozilla.org/en-US/docs/Web/CSS/display

  3. https://developer.mozilla.org/en-US/docs/Web/CSS/table-layout

Sachin Som
  • 1,005
  • 3
  • 8
  • display table cell on children won't achieve the outcome im looking for because the child divs need margins between them and they need not stretch vertically to fill parent div height. They have their own height. – user3777368 Jul 09 '22 at 10:13