Search code examples
cssspacingflexbox

Spacing between flexbox items


This is what I want:

flex with spacing

But this is the closest I've got:

body{
    margin: 0;
    padding: 0;
    border: 1px solid red;
}

.flex{
  display: -ms-flexbox;    
  display: -webkit-box;    
  display: -webkit-flexbox; 
  display: -webkit-flex;
  display: flex;            
}    

.flex > *{ margin: 0 10px; }    
.flex > :first-child{ margin-left: 0; }
.flex > :last-child{ margin-right: 0; }

.flex.vertical > *{ margin: 10px 0; }    
.flex.vertical > :first-child{ margin-top: 0; }
.flex.vertical > :last-child{ margin-bottom: 0; }

.vertical{
      -webkit-box-orient: vertical;    
         -moz-box-orient: vertical;    
              box-orient: vertical;    
  -webkit-flex-direction: column;
     -moz-flex-direction: column;
      -ms-flex-direction: column;
          flex-direction: column;      
}

.box{
  background: #000;
  flex: auto;
  min-height: 100px;
}
<div class="flex vertical">    
  <div class="flex">
    <div class="box"> </div>    
    <div class="box"> </div>                
  </div>   
  <div class="flex">    
    <div class="box"> </div>    
    <div class="box"> </div>                
    <div class="box"> </div>              
  </div>   

  <div class="flex">
    <div class="box"> </div>    
    <div class="box"> </div>                
  </div>           
</div>

I'm applying a margin on flexbox items, then removing half of it from the first & last children.

The problem is that :first-child is not always the first visually, because I may alter the layout order using flexbox ordering utilities. For example:

.flex > *{
  -webkit-box-ordinal-group: 2;
     -moz-box-ordinal-group: 2;
             -ms-flex-order: 2;
              -webkit-order: 2;
                      order: 2;    
}

#important{
  -webkit-box-ordinal-group: 1;
     -moz-box-ordinal-group: 1;
             -ms-flex-order: 1;
              -webkit-order: 1;
                      order: 1;
}

body{
    margin: 0;
    padding: 0;
    border: 1px solid red;
}

.flex{
  display: -ms-flexbox;    
  display: -webkit-box;    
  display: -webkit-flexbox; 
  display: -webkit-flex;
  display: flex;            
}    

.flex > *{ margin: 0 10px; }    
.flex > :first-child{ margin-left: 0; }
.flex > :last-child{ margin-right: 0; }

.flex.vertical > *{ margin: 10px 0; }    
.flex.vertical > :first-child{ margin-top: 0; }
.flex.vertical > :last-child{ margin-bottom: 0; }

.vertical{
      -webkit-box-orient: vertical;    
         -moz-box-orient: vertical;    
              box-orient: vertical;    
  -webkit-flex-direction: column;
     -moz-flex-direction: column;
      -ms-flex-direction: column;
          flex-direction: column;      
}

.box{
  background: #000;
  flex: auto;
  min-height: 100px;
}
<div class="flex vertical">    
  <div class="flex">
    <div class="box"> </div>    
    <div class="box"> </div>                
  </div>   
  <div class="flex">    
    <div class="box"> </div>    
    <div class="box" id="important"> </div>                
    <div class="box"> </div>              
  </div>   

  <div class="flex">
    <div class="box"> </div>    
    <div class="box"> </div>                
  </div>           
</div>

Is there a way to take the visual order into account when applying the margin?


Solution

  • The CSS spec has recently been updated to apply gap properties to flexbox elements in addition to CSS grid elements. This feature is supported on the latest versions of all major browsers. With the gap property, you can get what you want with just gap: 10px (or whatever size you want).