Home > Back-end >  Make a list of divs stretch to fit parent width while maintaining vertical scrolling
Make a list of divs stretch to fit parent width while maintaining vertical scrolling

Time:07-09

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 do not stretch so that all the child divs together fit or cover the parent div's width. Please keep your answers simple so that I can understand it. Here is my code:

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

<style type="text/css">
    #parent{
        width: 100%;  /*100% of window width. Which is variable from device to device*/
        height: 900px;
        overflow: auto;
    }
    .child{
        display: inline-block;
        width: 200px;
        height: 200px;
        margin-right: 10px;
        margin-bottom: 10px;
    }
</style>

<script type="text/javascript">
    $(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
            }
        }
    });
</script>

I would also accept a pure css solution if there's any. Thank you in advance.

CodePudding user response:

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

CodePudding user response:

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 ></div>
  <div ></div>
  <div ></div>
  <div ></div>
  <div ></div>
  <div ></div>
  <div ></div>
  <div ></div>
  <div ></div>
  <div ></div>
  <div ></div>
</div>

CodePudding user response:

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 ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></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

  • Related