nadavelyashiv
nadavelyashiv

Reputation: 309

Flexbox CSS - how can I achieve grid layout in a simpler way?

Currently could do this only with nested display: flex containers. Is there a way to achieve this layout with one flex container, and when the screen resizes, stack elements in a column instead of "just" shrinking them?

.container {
  width: 100%;
  display: flex;
  flex-flow: column wrap;
}

.row {
  display: flex;
  flex-wrap: wrap;
  flex: 1 100%;
  max-height: 100px;
}

.row>* {
  border: dashed 1px red;
  margin: 10px;
}

.bc,
.act {
  flex: 1 auto;
}

.summary {
  flex: 3 auto;
}

.short {
  flex: 1 0;
}

.widget {
  border: dashed 1px red;
  margin: 10px;
  max-height: 100px;
  flex: 3 100%;
}
<div class="container">
  <div class="row">
    <div class="bc">50%</div>
    <div class="act">50%</div>
  </div>
  <div class="row">
    <div class="summary">75%</div>
    <div class="short">25%</div>
  </div>
  <div class="widget">100%</div>
  <div class="widget">100%</div>
</div>

Upvotes: 0

Views: 398

Answers (3)

Paulie_D
Paulie_D

Reputation: 115047

As an alternative to flexbox consider CSS-Grid

Add a media query to make all classes span 4 at the suitable width...

.container {
  display: grid;
  grid-column-gap: 10px;
  grid-template-columns: repeat(4, 1fr);
}

.container div {
  border: dashed 1px red;
  margin: 10px;
}

.half {
  grid-column: span 2
}

.quarter-3 {
  grid-column: span 3
}

.full {
  grid-column: span 4
}
<div class="container">
  <div class="half">50%</div>
  <div class="half">50%</div>
  <div class="quarter-3">75%</div>
  <div class="quarter-1">25%</div>
  <div class="full">100%</div>
  <div class="full">100%</div>
</div>

Upvotes: 1

Temani Afif
Temani Afif

Reputation: 272901

You can use a row direction and media query like this:

.container {
  width: 100%;
  display: flex;
  flex-flow: row wrap;
}

.container>* {
  border: dashed 1px red;
  margin: 10px;
  box-sizing: border-box;
}

.bc,
.act {
  flex-basis: calc(50% - 20px);
}

.summary {
  flex: 3 auto;
}

.short {
  flex: 1 auto;
}

.widget {
  max-height: 100px;
  flex-basis: 100%;
}

@media all and (max-width:600px) {
  .container>* {
    flex-basis: 100%;
  }
}
<div class="container">
  <div class="bc">50%</div>
  <div class="act">50%</div>
  <div class="summary">75%</div>
  <div class="short">25%</div>
  <div class="widget">100%</div>
  <div class="widget">100%</div>
</div>

Upvotes: 1

Pete
Pete

Reputation: 58432

By using flex wrap and changing your direction to row and a suitable width, you can use one container. To make them into a column on lower screen sizes, just add a media query that makes the divs all 100% width

* {
  box-sizing: border-box;
}

.container {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
}
.container>div {
  border: 1px dashed red;
  margin:10px;
}
.quarter {
  width:calc(25% - 20px);
}
.half {
  width:calc(50% - 20px);
}
.three-quarters {
  width:calc(75% - 20px);
}
.full {
  width:calc(100% - 20px)
}
<div class="container">
  <div class="half">50%</div>
  <div class="half">50%</div>
  <div class="three-quarters">75%</div>
  <div class="quarter">25%</div>
  <div class="full">100%</div>
  <div class="full">100%</div>
</div>

Upvotes: 2

Related Questions