0

I stumbled across an issue that I simply don't know how to fix, even after looking and trying countless solutions. Using flexbox, I want to make each div in the section take 1/3 of their parent's width and make each three stay on the same row. It has been answered yet I'm probably missing something that I really can't find at the moment, so any help is appreciated!

To be more clear about the issue here's what happens to every 3rd div in the flexbox:

enter image description here

Of course, I'm going to provide some CSS too:

/* The parent element */
#list {
    display: flex;
    flex-wrap: wrap;
    width: 100%;
}

/* Each div inside */
.page {
    padding: 12px;
    margin-top: 0px;
    margin-bottom: 15px;
    margin-left: 8px;
    flex: 0 0 33.3333333333%;
}
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Nemalp
  • 107
  • 1
  • 6
  • You likely need to reduce your percent for the flex in .page. You'll need to accommodate for padding/margin in percentages. – dale landry Jan 02 '21 at 02:42
  • Why don't you use grid? It would be much easier and the layout won't break in smaller viewports. – Shounak Das Jan 02 '21 at 02:47
  • If you still want to use flex, I'd either get rid of the margin-left and add the 8 px to the padding-left, or use flex: 0 0 calc(33.33333% - 8px); Maybe even make it -9px to account for rounding errors so the total width doesn't go over 100%. – LarryBud Jan 02 '21 at 03:13
  • Those suggestions worked but I specifically used the `flex: 0 0 calc(33.33333% - 8px)` one. Thank you all! – Nemalp Jan 02 '21 at 03:41

1 Answers1

1

The reason your containers are wrapping:

This is happening because you have set the assigned width of the boxes to be 1/3 of the available space. What's actually happening is they are taking up 1/3 + 8px + 12px + 12px of the available space as you have set the property margin-left: 8px; and padding: 12px; (padding for both ends).

To demonstrate

/* Resets */
* {
  margin: 0;
  padding: 0;
}
/* The parent element */
ul {
    display: flex;
    flex-wrap: wrap;
    width: 100%;
}

/* Each div inside */
li {
    list-style-type: none;
    box-shadow: inset 0 0 10px black;
/*  padding: 12px;
    margin-left: 8px; These are the properties affecting the result */
    margin-top: 0px;
    margin-bottom: 15px;
    flex: 0 1 calc(1 / 3 * 100%);
}
<ul>
  <li>Page</li>
  <li>Page</li>
  <li>Page</li>
  <li>Page</li>
</ul>

There are two options I see:

  • Reduce the flex-basis and center the containers
  • Use CSS Grid (preferable)

The flex route

/* Resets */
* {
  margin: 0;
  padding: 0;
}
/* The parent element */
ul {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    width: 100%;
}

/* Each div inside */
li {
    list-style-type: none;
    box-shadow: inset 0 0 10px black;
    padding: 12px;
    margin-top: 0px;
    margin-bottom: 15px;
    margin-left: 8px;
    flex: 0 1 calc(1 / 4 * 100%);
}
<ul>
  <li>Page</li>
  <li>Page</li>
  <li>Page</li>
  <li>Page</li>
</ul>

The CSS Grid route

/* Resets */
* {
  margin: 0;
  padding: 0;
}
/* The parent element */
ul {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 8px;
    width: 100%;
}

/* Each div inside */
li {
    list-style-type: none;
    border: 1px solid black;
    padding: 12px;
    margin-top: 0px;
    margin-bottom: 15px;
    flex: 0 1 calc(1 / 4 * 100%);
}
<ul>
  <li>Page</li>
  <li>Page</li>
  <li>Page</li>
  <li>Page</li>
</ul>

I realize you requested flexbox specifically but this is much better with CSS Grid as it will give you control over cell responsive-resizing and the adding of content in the future.

Raheel Junaid
  • 577
  • 3
  • 12
  • are you sure the padding of 12px on each side isn't already taken into account in the 33.333333%? – LarryBud Jan 02 '21 at 04:06
  • Positive, I tested it. You can too if you'd like. I originally didn't think this would affect anything but it seems that the content itself, combined with the padding is expanding the width unintentionally. – Raheel Junaid Jan 02 '21 at 04:08
  • I did test your flex snippet, changing the flex: 0 1 calc(1 / 3 * 100%); to flex:0 1 calc(33.33333% - 8px) and left the padding in there, and all 3 cells fit on one line. – LarryBud Jan 02 '21 at 04:27
  • It seems we're getting different results. I tested my first snippet by commenting out the `margin-left` only instead of both the `margin` and `padding` and all three elements didn't fit onto one line. Are you sure you're testing the first snippet? – Raheel Junaid Jan 02 '21 at 04:36