Georg Edelmann
Georg Edelmann

Reputation: 54

How to do responsive column wrapping?

My requirements for a tabular design are: "columns need to wrap when there is no space left" like this

a1 b1
a2 b2
.. ..
.. bm
an 

having a smaller viewport the "table" needs to wrap to

a1
..
an
b1
..
bm

There can be more columns then just 2.

i tried using CSS Grid and Flexbox but couldn't achieve what i wanted to do. Any Ideas?

No Table Tags allowed here :( CSS Grid would be best.. but alas...

My current idea was something like that: https://codepen.io/GEdelmann/pen/BqorwY But it struggles when you have to deal with dynamic content.

Upvotes: 0

Views: 2548

Answers (3)

AndreasT
AndreasT

Reputation: 1001

Just wrap your columns items inside a div and everything inside a flexbox or grid-container.

Sample: https://codepen.io/antekai/pen/NOGEYB?editors=1100

HTML

FLEXBOX SOLUTION

<div class="flex-container">
  <div>
    <div class="item">a1</div>
    <div class="item">a2</div>
    <div class="item">a3</div>
  </div>
  <div>
    <div class="item">b1</div>
    <div class="item">b2</div>
    <div class="item">b3</div>
  </div>
</div>

CSS GRID SOLUTION

<div class="grid-container">
  <div>
    <div class="item">a1</div>
    <div class="item">a2</div>
    <div class="item">a3</div>
  </div>
  <div>
    <div class="item">b1</div>
    <div class="item">b2</div>
    <div class="item">b3</div>
  </div>
</div>

CSS

//flexbox solution
.flex-container{
  display:flex;
  flex-flow:row wrap;
}
// CSS Grid solution
.grid-container{
  display:grid;
  grid-template-columns: repeat(auto-fit,minmax(200px,1fr))
}
//helper class
.item{
  height:100px;
  width:200px;
  background-color: black;
  color:white;
  margin:10px;
}

EDIT

At the following link you can find enhanced solution for the case of unequal height of items. For the flexbox solution, a dynamic JS based enhancement and for the CSS grid a static CSS based enhancement. The logic of the enhancements is the same: add an empty item with height equal to the difference of heights between respective items (e.g. empty item after b1 with height=a1-b1 when a1-b1>0 which results vertical align of a2 and b2). The flexbox enhanced solution can be extended to CSS grid solution and the contrary.

Sample: https://codepen.io/antekai/pen/OBMyqv

Note: for the JS based enhancement (flexbox solution) when you resize the viewport between the breakpoint (at 400px) just type anything (to html,css or js panel) so the codepen refreshes the live-reload.

Upvotes: 0

skaz
skaz

Reputation: 301

According to the layout you want with your examples given in similar grid template area format. You could accomplish going from the 2 columns you list to the 1 column by setting the media query to change the grid template area accordingly. I noticed a2 and b2 were missing from the 1 column example, so I assumed you wanted them to be removed when the screen size is less then X amount. I've typed up a quick codepen to that uses your examples and achieves the goal of formatting the blocks according to what your example portrays. You could move the blocks around however you want in the media query.

https://codepen.io/skazx/pen/ReWeBP

@media (max-width: 600px) {
    .wrapper{
        grid-template-columns: 1fr;
        grid-template-areas: 
        "a1"
        "."
        "an"
        "b1"
        "."
        "bm"
    }
    .a2{
        display: none;
    }
    .b2{
        display: none;
    }
}

Upvotes: 0

nmorell
nmorell

Reputation: 65

You can always use Bootstrap Grid System.

OR

get some Flexbox snippets

Proof of concept here

HTML

<ul class="flex-container">
  <li class="flex-item">1</li>
  <li class="flex-item">2</li>
  <li class="flex-item">3</li>
  <li class="flex-item">4</li>
  <li class="flex-item">5</li>
  <li class="flex-item">6</li>
</ul>

CSS

.flex-container {
  padding: 0;
  margin: 0;
  list-style: none;

  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;

  -webkit-flex-flow: row wrap;
  justify-content: space-around;
}

.flex-item {
  background: tomato;
  padding: 5px;
  width: 200px;
  height: 150px;
  margin-top: 10px;

  line-height: 150px;
  color: white;
  font-weight: bold;
  font-size: 3em;
  text-align: center;
}

Upvotes: 1

Related Questions