125

I have been trying to show three columns per row. Is it possible using flexbox?

My current CSS is something like this:

.mainDiv {
    display: flex;
    margin-left: 221px;
    margin-top: 43px;
}

This code puts all content in a single row. I want to add a constraint to just shows three records per row.

5 Answers 5

209

This may be what you are looking for:

http://jsfiddle.net/L4L67/

body>div {
  background: #aaa;
  display: flex;
  flex-wrap: wrap;
}

body>div>div {
  flex-grow: 1;
  width: 33%;
  height: 100px;
}

body>div>div:nth-child(even) {
  background: #23a;
}

body>div>div:nth-child(odd) {
  background: #49b;
}
<div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

6
  • 24
    Your markup is confusing. This works but considering making your example easier to understand/read. Commented Apr 29, 2016 at 22:23
  • This will show one or two columns when there's only one or two divs in side, due to flex-grow. Commented Dec 1, 2016 at 10:37
  • 6
    Remove flex-grow if you don't want the child elements to stretch out to fill the space. Commented Mar 20, 2017 at 13:35
  • @Barun, What if there are odd number of divs say 5? The second row will have 2 divs stretched full width and not that pretty looking. How to make the divs in 2nd row to take width same as that in 1st row? Commented Jul 7, 2018 at 19:29
  • 1
    @lifetimeLearner007 add max-width: 33%; and the odd divs will not fill the whole row
    – Babu
    Commented Aug 29, 2022 at 7:55
83

Even though the above answer appears to be correct, I wanted to add a (hopefully) more readable example that also stays in 3 columns form at different widths:

.flex-row-container {
    background: #aaa;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
}
.flex-row-container > .flex-row-item {
    flex: 1 1 30%; /*grow | shrink | basis */
    height: 100px;
}

.flex-row-item {
  background-color: #fff4e6;
  border: 1px solid #f76707;
}
<div class="flex-row-container">
  <div class="flex-row-item">1</div>
  <div class="flex-row-item">2</div>
  <div class="flex-row-item">3</div>
  <div class="flex-row-item">4</div>
  <div class="flex-row-item">5</div>
  <div class="flex-row-item">6</div>
</div>

Hope this helps someone else.

4
  • 2
    thank for your answer. Please see my image below, how to make box 4,5 same with 1,2,3 ? image: prnt.sc/n29bm7
    – huykon225
    Commented Mar 24, 2019 at 16:22
  • Hey @huykon225. Essentially you'd want to adjust your value for flex: 1 1 30%; on the flex-items. The "flex" property is a shorthand for 3 flex box properties: "[flex-grow] [flex-shrink] [flex-basis]" which define the widths and space filling properties of flex elements. Flex-basis sets the initial width of flex-items, and flex-grow describes how those items fill remaining space (based on the different flex-grow values). So in this case, you’d want to set a flex-basis value for the items that corresponds to the width you want (maybe 20%), and the flex-grow to “0”.
    – RoboBear
    Commented Sep 10, 2019 at 16:41
  • 2
    This should be the accepted answer. It is a better approach to flexbox using the flex-wrap property.
    – incarnate
    Commented Nov 17, 2019 at 14:35
  • Nice answer. It demonstrates flex-wrap: wrap;. Also, experimenting with the Stack Snippet shows how the grow property works. Thanks! Commented Mar 1 at 17:31
28

Try this one using Grid Layout:

.grid-container {
  display: grid;
  grid-template-columns: auto auto auto;
  padding: 10px;
}
.grid-item {
  background-color: rgba(255, 255, 255, 0.8);
  border: 1px solid rgba(0, 0, 0, 0.8);
  padding: 20px;
  font-size: 30px;
  text-align: center;
}
<div class="grid-container">
  <div class="grid-item">1</div>
  <div class="grid-item">2</div>
  <div class="grid-item">3</div>  
  <div class="grid-item">4</div>
  <div class="grid-item">5</div>
  <div class="grid-item">6</div>  
  <div class="grid-item">7</div>
  <div class="grid-item">8</div>
  <div class="grid-item">9</div>  
</div>

1
  • This seems to work a lot better than flex wrap + space-between when the number of items is variable, e.g there may be 2 items, or an odd number of items, like 5. If you want the items to have a fixed size, then space-between ruins the display by separating the 4th and 5th children, unlike with this solution
    – Konrad
    Commented Apr 1, 2021 at 18:20
13

You can now use grid-auto-flow

https://jsfiddle.net/chalcrow/bqye79kr/1/

CSS

.grid-flow {
    display: grid;
    grid-auto-flow: row;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(2, 1fr);
}

Note - the repeat(3, 1fr) means '3 columns, each taking up 1 (equal) fraction of the available space.

HTML

<div class="grid-flow">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
</div>

Result

enter image description here

0

You can take advantage of a library that you may already have installed, bootstrap, and use their grid system which uses flexbox under the hood, while giving an easy to use semantic class naming system to implement it:

<!-- containers can have one or many child grids. Each grid should have a child row, which hold child columns -->
<div class='container'>
  <div class='row'>
    <div class='col'>col</div>
    <div class='col'>col</div>
    <div class='col'>col</div>
  </div>
</div>

enter image description here

Not the answer you're looking for? Browse other questions tagged or ask your own question.