118

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.

Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
maxspan
  • 13,326
  • 15
  • 75
  • 104

4 Answers4

201

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>
TylerH
  • 20,799
  • 66
  • 75
  • 101
Barun
  • 4,245
  • 4
  • 23
  • 29
  • 22
    Your markup is confusing. This works but considering making your example easier to understand/read. – Carrie Kendall Apr 29 '16 at 22:23
  • This will show one or two columns when there's only one or two `div`s in side, due to `flex-grow`. – TheThirdMan Dec 01 '16 at 10:37
  • 6
    Remove `flex-grow` if you don't want the child elements to stretch out to fill the space. – cptstarling Mar 20 '17 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? – lifetimeLearner007 Jul 07 '18 at 19:29
  • 1
    @lifetimeLearner007 add `max-width: 33%;` and the odd divs will not fill the whole row – Babu Aug 29 '22 at 07:55
  • What if we want to have margin in between the columns? Considering css column-gap property is still not widely supported for flex elements. – Niraj Sep 16 '22 at 01:23
76

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.

klewis
  • 7,459
  • 15
  • 58
  • 102
RoboBear
  • 5,434
  • 2
  • 33
  • 40
  • 2
    thank for your answer. Please see my image below, how to make box 4,5 same with 1,2,3 ? image: https://prnt.sc/n29bm7 – huykon225 Mar 24 '19 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 Sep 10 '19 at 16:41
  • 1
    This should be the accepted answer. It is a better approach to flexbox using the flex-wrap property. – incarnate Nov 17 '19 at 14:35
  • This answer is not fit for a case which the number of elements is not divide by 3. – URL87 Jul 11 '23 at 09:34
27

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>
Sumit
  • 2,242
  • 1
  • 24
  • 37
HAPPY SINGH
  • 536
  • 4
  • 13
  • 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 Apr 01 '21 at 18:20
8

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

Chris Halcrow
  • 28,994
  • 18
  • 176
  • 206