Reputation: 59
I'm trying to make a three column setup with gutters that has equal heights. I'm currently trying to do this with flexbox but the issue I'm having is that if a row ends up having two columns, the justify-content: space-between;
makes a gap in the middle instead of flowing left to right like bootstrap columns would do. I thought this would be done with align-content: flex-start;
but I'm either using it wrong or it doesn't work the way I'm trying to use it.
Is there a way to have flexbox use the space between for the gutters but keep the left to right flow? Here is a link to show the issue I'm having and how I want it to look.
http://codepen.io/anon/pen/jWvqdL
Also, is there a way to use flexbox with the padding and column width % setup of bootstrap then have a child element inside the column that is 100% height?
Upvotes: 1
Views: 2747
Reputation: 87201
Here is a version that does what you want.
It shows both a 2 and 3 column layout, with just 2 extra CSS rules
.container2,
.container3 {
max-width: 840px;
margin: 0 auto;
border-right: 1px solid red;
border-left: 1px solid red;
}
.flex {
display: flex;
flex-wrap: wrap;
margin-bottom: 40px;
}
.container3 .column {
box-sizing: border-box;
margin-bottom: 12px;
width: calc(33.33% - 8px);
background: #000;
}
.container3 .column:nth-child(3n+2),
.container3 .column:nth-child(3n+3) {
margin-left: 12px;
}
.column-content {
padding: 20px;
color: #fff;
}
.container2 .column {
box-sizing: border-box;
margin-bottom: 12px;
width: calc(50% - 6px);
background: #000;
}
.container2 .column:nth-child(2n+2) {
margin-left: 12px;
}
<div class="container3">
<div class="flex">
<div class="column">
<div class="column-content">
<p>Content</p>
<p>Content</p>
<p>Content</p>
</div>
</div>
<div class="column">
<div class="column-content">
<p>Content</p>
</div>
</div>
<div class="column">
<div class="column-content">
<p>Content</p>
</div>
</div>
<div class="column">
<div class="column-content">
<p>Content</p>
</div>
</div>
<div class="column">
<div class="column-content">
<p>Content</p>
</div>
</div>
</div>
</div>
<hr>
<div class="container2">
<div class="flex">
<div class="column">
<div class="column-content">
<p>Content</p>
<p>Content</p>
<p>Content</p>
</div>
</div>
<div class="column">
<div class="column-content">
<p>Content</p>
</div>
</div>
<div class="column">
<div class="column-content">
<p>Content</p>
</div>
</div>
<div class="column">
<div class="column-content">
<p>Content</p>
</div>
</div>
<div class="column">
<div class="column-content">
<p>Content</p>
</div>
</div>
</div>
</div>
Update based on comments for mixed columns
.container {
max-width: 840px;
margin: 0 auto;
}
.flex {
display: flex;
flex-wrap: wrap;
margin-bottom: 40px;
margin-left: -12px;
}
.column {
box-sizing: border-box;
margin-bottom: 12px;
margin-left: 12px;
background: #000;
}
.column-content {
padding: 20px;
color: #fff;
}
.col2 {
width: calc(50% - 12px);
}
.col3 {
width: calc(33.333% - 12px);
}
.col4 {
width: calc(25% - 12px);
}
<div class="container">
<div class="flex">
<div class="column col3">
<div class="column-content">
<p>Content</p>
<p>Content</p>
<p>Content</p>
</div>
</div>
<div class="column col3">
<div class="column-content">
<p>Content</p>
</div>
</div>
<div class="column col3">
<div class="column-content">
<p>Content</p>
</div>
</div>
<div class="column col2">
<div class="column-content">
<p>Content</p>
</div>
</div>
<div class="column col2">
<div class="column-content">
<p>Content</p>
</div>
</div>
<div class="column col2">
<div class="column-content">
<p>Content</p>
</div>
</div>
<div class="column col4">
<div class="column-content">
<p>Content</p>
</div>
</div>
<div class="column col4">
<div class="column-content">
<p>Content</p>
<p>Content</p>
</div>
</div>
</div>
</div>
Upvotes: 2
Reputation: 59
This is how I decided to do it. I'm using the standard bootstrap set up, with the padding on columns and negative margin on the parent, but setting display: flex;
to the parent and the column with flex-wrap: wrap;
on the parent. This way, I can use the boostrap column percent width and have equal height from flex.
http://codepen.io/anon/pen/wMExMJ
Upvotes: -1
Reputation: 371331
One method to solve the problem would be to include a "phantom" div as the last child with visibility: hidden
.
I've copied the first flex item from your code and pasted it as the last item in the container. I've added a hidden
class to it.
<div class="column hidden">
<div class="column-content">
<p>Content</p>
<p>Content</p>
<p>Content</p>
</div>
</div>
Then in your CSS:
.hidden { visibility: hidden; }
For other options, see this answer: https://stackoverflow.com/a/34930349/3597276
The reason align-content: flex-start
doesn't work as you expect is because the align-*
properties work along the cross axis. In this case, as your flex container is flex-direction: row
, the cross axis is vertical. So align-content
, align-items
and align-self
would move your flex items up/down, not left right.
For an illustration of main axis / cross axis, and more details about the align-*
properties, see here: In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
Upvotes: 1
Reputation: 804
One way is by removing justify-content
and managing the gutters with margin
then using the :nth-child(n)
selector to selectively remove the margin so the elements fit. http://codepen.io/anon/pen/QyVEJZ
Upvotes: 1