Home > Enterprise >  Responsive wrapping of columns with different width ratios (float, flex, grid)?
Responsive wrapping of columns with different width ratios (float, flex, grid)?

Time:08-05

Is there a way to specify column width ratios and minimum widths to allow wrapping for narrow screens (responsive design)?

 ----- ----- ----- 
| 1/3 |    2/3    |
|     |(1/3 | 1/3)|
 ----- ----- ----- 

 ----- ----- 
| 1/3 | 1/3 |
|     | 1/3 |
 ----- ----- 

 ----- 
| 1/3 |
 ----- 
| 1/3 |
| 1/3 |
 ----- 

Each 1/3 is a div, so is 2/3.
It should fill 100% of its parent's width (centered "main" container column).

I've tried the following:

  • "classic" float: did not get it right
  • flexbox: close, but uneven sizes
  • grid: sizes well, but doesn't wrap?

div {
  box-sizing: border-box;
  border: 1px solid red;
  margin: 1px;
  padding: 0;
}

#container>div {
  float: left;
}

#container::after {
  content: "";
  display: block;
  clear: both;
}

.flex {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1rem;
}

.flex>div {
  flex-basis: 200px;
  flex-shrink: 0;
}

.fone {
  flex-grow: 1;
}

.ftwo {
  flex-grow: 2;
}

.gthree {
  display: grid;
  grid-template-columns: 1fr 2fr;
  grid-gap: 1rem;
}

.gtwo {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-gap: 1rem;
}
float: not quite right
<div id="container">
  <div style="width:33%;">A</div>
  <div style="width:66%;">
    <div style="width:50%;">B</div>
    <div style="width:50%;">C</div>
  </div>
</div>

flex: wraps, uneven sizing, children overflow
<div >
  <div >A</div>
  <div >
    <div>B</div>
    <div>C</div>
  </div>
</div>

grid: nice sizing, but does not wrap
<div >
  <div>A</div>
  <div >
    <div>B</div>
    <div>C</div>
  </div>
</div>

Intended result:
<div >
  <div>A</div>
  <div>
    <div>B</div>
    <div>C</div>
  </div>
</div>

  • Which method is suited for my purpose?
  • How would it be implemented?

CodePudding user response:

Not perfect, but you can get really close with grids and auto-fit (1) and minmax.

We set the min value in our min max to the width it'll wrap after, and the max to 1fr for the cells to flex with the grid.

The issue is repeat() with auto-fit sets an equal ratio between all columns, so A will be as big as B & C until everything wraps together. Which is fine for scenarios 2 and 3 but not 1.

This could be fixed by using flex and and setting the flex-grow's accordingly so that when everything's in one line, the ratios are correct, but then in the other scenarios the ratios would have to go change again, which is an issue.

div {
  box-sizing: border-box;
  border: 1px solid red;
  margin: 1px;
  padding: 0;
}

#container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

.inner { 
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
<div id="container">
  <div class='single'>A</div>
  <div class='inner'>
    <div>B</div>
    <div>C</div>
  </div>
</div>

CodePudding user response:

Try this:

div {
  box-sizing: border-box;
  border: 1px solid red;
  margin: 1px;
  padding: 0;
}

.container {
  display: flex;
  flex-wrap:wrap;
  justify-content:space-evenly;
  /* Or you can use any of the 
   following as per needs:
justify-content:space-between;
justify-content:space-around;
justify-content:space-evenly;
justify-content:center; */
}

.inner { 
  display: flex;
  flex-wrap:wrap;
  flex:1;
}
.middle { 
  display: flex;
  flex-wrap:wrap;
  flex:1;

}
.single{
/* For occupying equal space: */
  flex:1;
  
}


/* `Note: The flex-wrap works when you use a specific width, else the width will adjust automatically depends on screen size` */
<div >
  <div class='single'>A</div>
  <div class='middle'>
    <div class='inner'>B</div>
    <div class='inner'>C</div>
  </div>
</div>

  • Related