Last Margin/Padding Collapsing in Flexbox/Grid Layout

Margin collapsing in flexbox

Margin collapsing is a feature of a block formatting context.

There is no margin collapsing in a flex formatting context.

3. Flex Containers: the flex and inline-flex display
values

A flex container establishes a new flex formatting context for its
contents. This is the same as establishing a block formatting context,
except that flex layout is used instead of block layout. For example,
floats do not intrude into the flex container, and the flex
container’s margins do not collapse with the margins of its contents.

Flexbox overflow-x last margin

You could use :after pseudo-element with width same as margin to create that space but then you also need to remove margin-right from last li.

ul {  display: flex;  overflow-x: auto;  border: 1px solid aqua;  background-color: tomato;  width: 400px;  list-style: none;  padding-left: 0;}ul:after {  content: '';  flex: 0 0 10px;}li {  border: 1px solid Aquamarine;  min-width: 300px;  margin: 10px;}li:last-child {  margin-right: 0;}
<ul>  <li>item1</li>  <li>item2</li>  <li>item3</li>  <li>item4</li></ul>

Collapsing margin on Flexbox grid in Edge and Firefox

Margin using percent doesn't work cross browsers on flex items, so if your margin's is more related to the viewport, use viewport units (vh or vw), else you can combine px with CSS calc() (i.e. width: calc(33.333% - 20px)) to match an equal gutter between the items.

Updated codepen

body {  padding: 1.5%;  background-color: #333;}
.container { //background-color: black; max-width: 964px; margin: 0 auto; display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; -webkit-box-flex-flow: row wrap; -moz-box-flex-flow: row wrap; -webkit-flex-flow: row wrap; -ms-flex-flow: row wrap; flex-flow: row wrap;}
.item { position: relative; width: 97%; color: #fff; background-color: #4286f4; padding: 0 20px 40px; margin: 1.5vh; box-sizing: border-box;}
@media only screen and (min-width:420px){ .item { width: 47%; }}
@media only screen and (min-width:768px){ .item { width: 30.333%; }}
a { position: absolute; bottom: 20px; left: 20px;}
<div class="container">  <div class="item item-1">    <h2>Item one</h2>    <p>Pellentesque convallis turpis nec enim consequat, vitae pellentesque purus tempus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis blandit elit vel lacus gravida, nec imperdiet ligula ornare.</p>    <a href="#">Read more</a>  </div>  <div class="item item-2">    <h2>Item two</h2>    <p>Pellentesque convallis turpis nec enim consequat, vitae pellentesque purus tempus.</p>    <a href="#">Read more</a>  </div>  <div class="item item-3">    <h2>Item three</h2>    <p>Pellentesque convallis turpis nec enim consequat, vitae pellentesque purus tempus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae.</p>    <a href="#">Read more</a>  </div>  <div class="item item-4">    <h2>Item four</h2>    <p>Pellentesque convallis turpis nec enim consequat.</p>    <a href="#">Read more</a>  </div>  <div class="item item-5">    <h2>Item five</h2>    <p>Pellentesque convallis turpis nec enim consequat.</p>    <a href="#">Read more</a>  </div>  <div class="item item-6">    <h2>Item six</h2>    <p>Pellentesque convallis turpis nec enim consequat.</p>    <a href="#">Read more</a>  </div></div>

Collapsing margin on Flexbox children

It's a bit of a hack, but you can add a negative margin on the flex container to cancel out the items' margins along the edges, and then move its "background" styling to a parent wrapper-element.

Updated JSBin

Updated CSS (SASS):

.wrapper
background: #eef
border: 1px solid darkgray

.container
display: flex
flex-wrap: wrap
margin: -1em

.item
flex-grow: 1
margin: 1em
border: 1px solid black
padding: 1em
min-width: 6em

Better way to set distance between flexbox items

  • Flexbox doesn't have collapsing margins.
  • Flexbox doesn't have anything akin to border-spacing for tables (edit: CSS property gap fulfills this role in newer browsers, Can I use)

Therefore achieving what you are asking for is a bit more difficult.

In my experience, the "cleanest" way that doesn't use :first-child/:last-child and works without any modification on flex-wrap:wrap is to set padding:5px on the container and margin:5px on the children. That will produce a 10px gap between each child and between each child and their parent.

Demo

.upper {
margin: 30px;
display: flex;
flex-direction: row;
width: 300px;
height: 80px;
border: 1px red solid;

padding: 5px; /* this */
}

.upper > div {
flex: 1 1 auto;
border: 1px red solid;
text-align: center;

margin: 5px; /* and that, will result in a 10px gap */
}

.upper.mc /* multicol test */ {
flex-direction: column;
flex-wrap: wrap;
width: 200px;
height: 200px;
}
<div class="upper">
<div>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa<br/>aaa</div>
<div>aaa<br/>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa</div>
</div>

<div class="upper mc">
<div>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa<br/>aaa</div>
<div>aaa<br/>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa</div>
</div>

CSS Grid padding right on the last item on horizontal scrolling with grid-auto-flow: column;

an extra empty element can fix this:

.Container {
max-width: 800px;
margin: 0 auto;
}

.book-list {
overflow: scroll;
display: grid;
grid-auto-flow: column;
grid-gap: 8px;
padding: 0 8px 16px 8px;
}
/* the fix */
.book-list::after {
content:"";
width:1px;
margin-right:-1px;
}
/**/
.book-list div{
width: 100px;
height: 140px;
border: 1px solid #333;
}

body {
margin:0;
}
<div class="Container book-list" >
<div>
<span>Book Name</span>
</div>
<div>
<span>Book 1</span>
</div>
<div>
<span>Book Name</span>
</div>
<div>
<span>Book 1</span>
</div>
<div>
<span>Book Name</span>
</div>
<div>
<span>Book 1</span>
</div>
<div>
<span>Book Name</span>
</div>
<div>
<span>Book 1</span>
</div>
<div>
<span>Book Name</span>
</div>
<div>
<span>Book 1</span>
</div>
<div>
<span>Book Name</span>
</div>
<div>
<span>Book 1</span>
</div>
</div>


Related Topics



Leave a reply



Submit