Flexbox using align-items: flex-start together with align-content: center

Viewed 362

Good Day.

I'm trying to use flex box to enforce the following behavior in a flex container which contains excess space on the cross-axis:

  1. If all flex items fit in one row, then they should align at the top of the cross axis; but
  2. Once they wrap, the flex items should condense in the center of the cross axis.

To do this, I've tried the following markup at https://jsfiddle.net/ht5bue6s/

* {
  box-sizing: border-box;
  font-size: 1.5rem;
}

html {
  background: #b3b3b3;
  padding: 5px;
}

body {
  background: #b3b3b3;
  padding: 5px;
  margin: 0;
}

.flex-container {
  height: 500px;
  background: white;
  padding: 10px;
  border: 5px solid black;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: space-evenly;
  align-items: flex-start;
  align-content: center;
}

.item-1 {
  background: #ff7300;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
}

.item-2 {
  background: #ff9640;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
}

.item-3 {
  background: #ff9640;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
}

.item-4 {
  background: #f5c096;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
}

.item-5 {
  background: #d3c0b1;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
}

.item-6 {
  background: #d3c0b1;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
}
<div class="flex-container">
  <div class="item-1">1</div>
  <div class="item-2">2</div>
  <div class="item-3">3</div>
  <div class="item-4">4</div>
  <div class="item-5">5</div>
  <div class="item-6">6</div>
</div>

As you'll see, the flex items always condense to the center. That is, "align-content: center" is always applied even when the flex items do not wrap.

I've read the MDN quote, "For align-content to work you need more height in your flex container than is required to display the items. It then works on all the items as a set, and dictates what happens with that free space, and the alignment of the entire set of items within it".

With that, it seems that if there is excess space on the cross axis within the flex container, that you simply cannot apply align-items alongside align-content. Instead, align-content will always override align-items.

So my question: is there any combination of container or item CSS properties which will produce the behavior described in #1 and #2 requirements above?

Thank you.

1 Answers

To achieve the desired result, you can make use of a media query.

To make this work, remove the flex-wrap and align-content properties from the .flex-container element. We will nly add these properties on the .flex-container element at a particular width of the browser window.

For example, following media query

@media (max-width: 450px) {
  .flex-container {
    flex-wrap: wrap;
    align-content: center;
  }
}

will make a flex container a multi-line flex container when the width of the browser window equal to or smaller than 450px. We also add align-content: center to make sure that the flex-lines are aligned in the center of the flex container.

This ensures that for a width greater than 450px, flex container has only one flex-line and flex items are aligned at the start of that single flex-line. For a width smaller than or equal to 450px, we make the flex container a multi-line flex container and align those flex-lines at the center of the flex container using align-content: center.

Working Demo

* {
  box-sizing: border-box;
  font-size: 1.5rem;
}

html {
  background: #b3b3b3;
  padding: 5px;
}

body {
  background: #b3b3b3;
  padding: 5px;
  margin: 0;
}

.flex-container {
  height: 500px;
  background: white;
  padding: 10px;
  border: 5px solid black;
  display: flex;
  justify-content: space-evenly;
  align-items: flex-start;
}

.flex-container div {
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
}

.item-1 { background: #ff7300; }
.item-2 { background: #ff9640; }
.item-3 { background: #ff9640; }
.item-4 { background: #f5c096; }
.item-5 { background: #d3c0b1; }
.item-6 { background: #d3c0b1; }   

@media (max-width: 450px) {
  .flex-container {
    flex-wrap: wrap;
    align-content: center;
  }
}
<div class="flex-container">
  <div class="item-1">1</div>
  <div class="item-2">2</div>
  <div class="item-3">3</div>
  <div class="item-4">4</div>
  <div class="item-5">5</div>
  <div class="item-6">6</div>
</div>

Related