3

I have the following Code: http://codepen.io/anon/pen/rxZRJP?editors=1100

HTML:

<nav class="navigation">
  <li class="navigation-item" style="background: #003f8f">
    <a href="#">1</a>
  </li>
  <li class="navigation-item" style="background: #548122">
    <a href="#">2</a>
  </li>
  <li class="navigation-item" style="background: #f4a628">
    <a href="#">3</a>
  </li>
  <li class="navigation-item" style="background: #d21527">
    <a href="#">4</a>
  </li>
</nav>

CSS:

.navigation {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.navigation-item {
  display: flex;
  flex: 1 1 20%;
  height: 190px;
  list-style-type: none;
  align-items: flex-end;
  justify-content: center;
  padding: 15px;
  margin: 15px;
}

.navigation-item a {
  color: #ffffff;
  text-decoration: none;
  font-size: 24px;
  display: flex;
  height: 100%;
  width: 100%;
  justify-content: center;
  align-items: center;
}

If you resize the viewport to around 1200px the fourth item will wrap and grow on its own single row.

To prevent having the fourth item singled out, I could write a @media-query with a fixed viewport size and change the flex-basis or give the items a min-width.

So my Question is:
Is there any more flexible way, to have no item singled out?

EDIT:
I want the items to wrap and I want the items to fill all the available space. So removing flex-grow or flex-wrap is not really an option.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Th0rkel
  • 63
  • 1
  • 6

2 Answers2

2

You could get a lot of inspiration for this thread: Flex-box: Align last row to grid

In your case, you could do a lot of small thing to achieve what you want in a simpler way.

1/ Add box-sizing: border-box, so the padding is included in the defined width. See for more explanations http://www.paulirish.com/2012/box-sizing-border-box-ftw/

2/ Use calc() to remove the margin from the width, so every item will fit on the line.

/* New box-sizing, so the padding and the border are included in element sizing */
* {
  box-sizing: border-box;
}

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

.navigation-item {
  display: flex;
  
  /* Make the 4 elements to fit in a single line */
  flex: 1 1 calc(25% - 30px);
  height: 190px;
  padding: 15px;
  margin: 15px;
  list-style-type: none;
}

.navigation-item a {
  display: inline-block;
  margin: auto;
  
  color: #ffffff;
  text-decoration: none;
  font-size: 24px;
}
<nav class="navigation">
  <li class="navigation-item" style="background: #003f8f">
    <a href="#">1</a>
  </li>
  <li class="navigation-item" style="background: #548122">
    <a href="#">2</a>
  </li>
  <li class="navigation-item" style="background: #f4a628">
    <a href="#">3</a>
  </li>
  <li class="navigation-item" style="background: #d21527">
    <a href="#">4</a>
  </li>
</nav>

3/ If you want to 4th element to be on a separate line, you could change the flex-basis

* {
  box-sizing: border-box;
}

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

.navigation-item {
  display: flex;
   
  /* We make that only 3 elements fit in a line */
  flex: 1 1 calc(100% / 3 - 30px);
  height: 190px;
  padding: 15px;
  margin: 15px;
  list-style-type: none;
}

.navigation-item a {
  display: inline-block;
  margin: auto;

  color: #ffffff;
  text-decoration: none;
  font-size: 24px;
}
<nav class="navigation">
  <li class="navigation-item" style="background: #003f8f">
    <a href="#">1</a>
  </li>
  <li class="navigation-item" style="background: #548122">
    <a href="#">2</a>
  </li>
  <li class="navigation-item" style="background: #f4a628">
    <a href="#">3</a>
  </li>
  <li class="navigation-item" style="background: #d21527">
    <a href="#">4</a>
  </li>
</nav>
Community
  • 1
  • 1
tzi
  • 8,719
  • 2
  • 25
  • 45
  • This is not really helping me. But thanks anyway. By the way: calc() in flex-basis is not working in ie10. So if you still have to support <= ie10, you can't use that. – Th0rkel Feb 04 '16 at 23:27
  • I like to share the simplest demonstration. If you want to use `calc()` with IE10, set it for the `width` and use `flex-basis: auto`. I updated my answer, since your question is more clear now ;) – tzi Feb 05 '16 at 08:54
1

Is there any more flexible way, to have no item singled out / have all items with the same width all the time?

Yes, remove flex-grow: 1 from your flex shorthand.

So instead of this:

.navigation-item {  flex: 1 1 20%; }

Try this:

.navigation-item {  flex: 0 1 20%; }

Revised Codepen

The flex-grow: 1 rule is telling flex items to consume all available space in the container. When they share a row, the available space is distributed evenly among them. But when the fourth item wraps to the second row by itself, it takes all the space.

Also, if you don't want the items to shrink, you would adjust flex-shrink:

.navigation-item {  flex: 0 0 20%; }

Except you're using a percentage width, so the flex items will shrink for that reason.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701