Shepmaster
Shepmaster

Reputation: 430386

How can I wrap flexbox children so that multiple children are stacked next to another child?

I have a table-like layout using flexbox:

+--------------+---------------+-----------------+---------------+
|      1       |       2       |        3        |       4       |
|              |               |                 |               |
+--------------+---------------+-----------------+---------------+

As the page gets smaller, I'd like to wrap the content to end up with something like this:

+--------------+-------------------------------------------------+
|              |                        2                        |
|              |                                                 |
|              +-------------------------------------------------+
|      1       |                        3                        |
|              |                                                 |
|              +-------------------------------------------------+
|              |                        4                        |
|              |                                                 |
+--------------+-------------------------------------------------+

I tried to use flex-wrap: wrap and extend the width of the trailing children to force them to wrap, but that just produces something like:

+-----------+--------------------------------------+
|           |                   2                  |
|           |                                      |
|     1     +--------------------------------------+
|           |
|           |
+-----------+--------------------------------------+
|                        3                         |
|                                                  |
+--------------------------------------------------+
|                        4                         |
|                                                  |
+--------------------------------------------------+

This is my current attempt:

.container {
  display: flex;
  flex-wrap: wrap;
}

.controls {
  flex: 0 0 25%;
  max-width: 25%;  
}

.name, .artist, .album {
  flex: 0 0 75%;
  max-width: 75%;
}

@media screen and (min-width: 600px) {  
  .name, .artist, .album {
    flex: 0 0 25%;
    max-width: 25%;
  }
}
<div class="container">
  <div class="controls">PLAY</div>
  <div class="name">NAME</div>
  <div class="artist">ARTIST</div>
  <div class="album">ALBUM</div>
</div>

(JSFiddle)

I'd prefer a pure CSS solution that works in IE11+.

Upvotes: 2

Views: 1080

Answers (1)

Michael Benjamin
Michael Benjamin

Reputation: 371013

Consider using a nested flex container that switches items 2, 3 and 4 to a column on smaller screens.

Here's an example based on your code:

HTML

<div class="container">
    <div class="controls">PLAY</div>
    <div class="inner-container"><!-- nested flex container -->
        <div class="name">NAME</div>
        <div class="artist">ARTIST</div>
        <div class="album">ALBUM</div>
    </div>
</div>

CSS

.container {
    display: flex;
    flex-wrap: wrap;
}

.inner-container {
    display: flex;
    flex: 0 0 75%;
}

.controls {
    flex: 0 0 25%;
}

.name,
.artist,
.album {
    flex: 1;
}

@media screen and (max-width: 600px) {
     .inner-container { flex-direction: column; }
     .controls { align-self: center; }
}

Revised Fiddle

Upvotes: 2

Related Questions