JWiley
JWiley

Reputation: 3219

Flexbox keep child widths static with set number per row

I'm using flexbox to create a group of buttons that need to be centered and in even groups (this example 3 per row). However, my options seem to be either group them but allow width growth by adding to the child:

flex: 0 0 20% 

or keep them static width and allow the flex-wrap to change their position based on screen size. Is there a way to allow both? I.e. for large screen sizes, have 2 groups of 3 buttons and allow appropriate wrapping for smaller screens, but always keep the static widths?

    .parent {
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
    }
    
    .child{
      text-decoration: none !important;
      display: inline-block;
      width: 160px;
      height: 140px;
      padding-top: 10px;
      margin: 30px 30px 30px 30px;
      border-radius: 30px;
      border: 1px solid #003595;
    }
   
<div class="parent">
  <a class="child" href="blah">
      <i class="fa fa-broadcast-tower fa-5x"></i>
      <span>Button 1</span>
  </a>
  <a class="child" href="blah">
      <i class="fa fa-chart-line fa-5x"></i>
      <span>Button 2</span>  
  </a>
  <a class="child" href="blah">
      <i class="fa fa-address-card fa-5x"></i>
      <span>Button 3</span>
  </a>                    
  <a class="child" href="blah">
      <i class="fa fa-clipboard-list fa-5x"></i>
      <span>Button 4</span>
  </a>
  <a class="child" href="blah">
      <i class="fa fa-signal fa-5x"></i>
      <span>Button 5</span>
  </a>
  <a class="child" href="blah">
      <i class="fa fa-signal fa-5x"></i>
      <span>Button 6</span>
  </a>
</div>

Here's a fiddle to show/play with the resizing.

Upvotes: 0

Views: 258

Answers (3)

Sphinxxx
Sphinxxx

Reputation: 13037

You say you need your buttons to be centered, so how about adding a max-width to the parent, and then center everything with margin: auto and justify-content: center? That way it will also wrap correctly on smaller screens:

.parent {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;

    max-width: 700px;
    margin: auto;
    justify-content: center;
}

https://jsfiddle.net/ms1t8xry/9/

Upvotes: 2

Paulie_D
Paulie_D

Reputation: 115288

CSS-Grid can do that

Codepen Demo

body {
  text-align: center;
}

.parent {
  display: inline-grid;
  grid-gap: 1em;
  grid-template-columns: repeat(3, 1fr);
}

.child {
  text-decoration: none !important;
  width: 160px;
  height: 140px;
  padding-top: 10px;
  border-radius: 30px;
  border: 1px solid #003595;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<div class="parent">
  <a class="child" href="blah">
    <i class="fa fa-broadcast-tower fa-5x"></i>
    <span>Button 1</span>
  </a>
  <a class="child" href="blah">
    <i class="fa fa-chart-line fa-5x"></i>
    <span>Button 2</span>
  </a>
  <a class="child" href="blah">
    <i class="fa fa-address-card fa-5x"></i>
    <span>Button 3</span>
  </a>
  <a class="child" href="blah">
    <i class="fa fa-clipboard-list fa-5x"></i>
    <span>Button 4</span>
  </a>
  <a class="child" href="blah">
    <i class="fa fa-signal fa-5x"></i>
    <span>Button 5</span>
  </a>
  <a class="child" href="blah">
    <i class="fa fa-signal fa-5x"></i>
    <span>Button 6</span>
  </a>
</div>


Flexbox requires us to calculate the margins

.parent {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
}

.child {
  text-decoration: none !important;
  flex: 0 0 160px;
  height: 140px;
  margin: 1em calc((100% - (160px *3)) / 7); /* I think it's 7 */
  padding-top: 10px;
  border-radius: 30px;
  border: 1px solid #003595;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<div class="parent">
  <a class="child" href="blah">
    <i class="fa fa-broadcast-tower fa-5x"></i>
    <span>Button 1</span>
  </a>
  <a class="child" href="blah">
    <i class="fa fa-chart-line fa-5x"></i>
    <span>Button 2</span>
  </a>
  <a class="child" href="blah">
    <i class="fa fa-address-card fa-5x"></i>
    <span>Button 3</span>
  </a>
  <a class="child" href="blah">
    <i class="fa fa-clipboard-list fa-5x"></i>
    <span>Button 4</span>
  </a>
  <a class="child" href="blah">
    <i class="fa fa-signal fa-5x"></i>
    <span>Button 5</span>
  </a>
  <a class="child" href="blah">
    <i class="fa fa-signal fa-5x"></i>
    <span>Button 6</span>
  </a>
</div>

Upvotes: 0

Huangism
Huangism

Reputation: 16448

For flex solution, you can just use a divider flex child to separate the rows and set its width to 100%. I also added justify-content: space-between for the container. There is no need for margin calculation since you have a divider

.parent {
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
      justify-content: space-between;
    }
    
    .child{
      text-decoration: none !important;
      display: inline-block;
      width: 160px;
      height: 140px;
      padding-top: 10px;
      margin: 30px 30px 30px 30px;
      border-radius: 30px;
      border: 1px solid #003595;
    }
    .divider {
      width: 100%;
    }
<div class="parent">
  <a class="child" href="blah">
      <i class="fa fa-broadcast-tower fa-5x"></i>
      <span>Button 1</span>
  </a>
  <a class="child" href="blah">
      <i class="fa fa-chart-line fa-5x"></i>
      <span>Button 2</span>  
  </a>
  <a class="child" href="blah">
      <i class="fa fa-address-card fa-5x"></i>
      <span>Button 3</span>
  </a>
  <div class="divider"></div>
  <a class="child" href="blah">
      <i class="fa fa-clipboard-list fa-5x"></i>
      <span>Button 4</span>
  </a>
  <a class="child" href="blah">
      <i class="fa fa-signal fa-5x"></i>
      <span>Button 5</span>
  </a>
  <a class="child" href="blah">
      <i class="fa fa-signal fa-5x"></i>
      <span>Button 6</span>
  </a>
</div>

Or As I mentioned before you could just put them into 2 different flex containers. They all work, you can pick whichever solution suits you the best

Upvotes: 0

Related Questions