Order divs in table-like structure with equal dynamic margin

Viewed 58

I'm not huge fan of bootstrap, so I was wondering if it is possible without it.

I have 6 divs which I want to order in 2 rows and 3 cols. I want the space between each row/col to be exact. I can do this by calculation but was wondering if there is smarter way around.

Note that .item height 50px is just for the example and is not set in the original code but it takes the height it needs to fit the content.

Also If I remove the .container height it will mess the horizontal blue line. I really do not want to rely on .container height.

I think it will be pretty easy with some JS which sets the height but I'd rather skip that and just use .container height instead. Thanks!

.container {
  display: flex;
  justify-content: space-between;
  align-content: space-between;
  width: 500px;
  height: 125px;
  background: blue;
  flex-wrap: wrap;
}

.item {
  background: red;
  width: 30%;
  height: 50px;
}
<div class='container'>
  <div class='item'> item1 </div>
  <div class='item'> item2 </div>
  <div class='item'> item3 </div>
  <div class='item'> item4 </div>
  <div class='item'> item5 </div>
  <div class='item'> item6 </div>
</div>

EDIT: Since I can see there is no way without JS I'll just use the .container's height. If somebody prefers the JS - here is a JQuery solution

$('.container').height(
    $('.item').height()*2 +
  (($('.container').width() - 3*$('.item').width()) /2)
);

Thanks for the answers!

2 Answers

Yes, you can plot .item in two lines and stripes without specifying the exact height and width, and width using flex.

First add flex-flow: wrap column for .container. This will build .item in the order you want. And for the indentation, you can use gap rule.

For the width, use the calc() function to limit the flex width for .item. Like that:

flex: calc(100% / 3);

:root {
  --gap: 20px;
}

.container {
    display: flex;
    flex-flow: wrap column;
    gap: var(--gap);
    width: 500px;
    height: 125px;
    background: blue;
    padding: var(--gap);
}

.item {
    flex: calc(100% / 3);
    background: red;
}
<div class="container">
    <div class="item">item1</div>
    <div class="item">item2</div>
    <div class="item">item3</div>
    <div class="item">item4</div>
    <div class="item">item5</div>
    <div class="item">item6</div>
</div>

Unless you need to fully support IE11 & 13 you can use CSS-Grid: display: grid;. You create a 3 column layout with the use of: grid-template-columns: repeat(3, 1fr); which will splitt the space into 3 equal columns (1fr = 1 fraction).

Then use the grid-gap property to exactly define the gap space.

PS: you dont have to use classes on the grid-cards. You can select them (and onyl them) with the use of: .container > div

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 10px;
  padding: 10px;
  width: 500px;
  background: blue;
}

.container > div {
  background: red;
  min-height: 50px;
}
<div class='container'>
  <div> item1 </div>
  <div> item2 </div>
  <div> item3 </div>
  <div> item4 </div>
  <div> item5 </div>
  <div> item6 </div>
</div>

Related