Given the following HTML:
<div class="outer">
<div>
<div class="inner">A</div>
</div>
</div>
<div class="outer">
<div class="inner">B</div>
</div>
and the following CSS (prefix free):
.outer {
display: box;
box-orient: vertical;
height: 100px;
width: 100px;
background: red;
margin: 10px;
}
.inner {
height: 50px;
margin-top: 10px;
background: green;
}
Here is a CodePen.
A
is wrapped in a <div>
so it's margin gets ignored.
Q: How can I achieve B
's behavior for A
(margin) with the flex box model?
Note: The div wrappers can go multiple levels deep
Targeting: latest Chrome/Safari/iOS
Thank you very much for your help!
Edit: Thanks to @JoséCabo I came up with this:
.outer {
display: flex;
flex-direction: column;
height: 100px;
width: 100px;
background: red;
margin: 10px;
}
.inner {
height: 50px;
margin-top: 10px;
background: green;
}
CodePen
Chrome:
Safari:
Unfortunately it doesn't work in Safari as mentioned by @cimmanon, so I still need some help.
Margin collapsing is a feature of a block formatting context. There is no margin collapsing in a flex formatting context. 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.
Margins of elements do not collapse when the value of the overflow property of the elements is set to anything other than visible. Its value must be visible so that margin can collapse.
So what you would do is use grid-gap for spacing between the items. Then use padding for the same spacing between the items and the container. The last row margin problem is eliminated.
How to Avoid Margin Collapse. First, remember that margins should preferably be used to increase the distance between sibling elements, not to create spacing between a child and a parent. If you need to increase space within the Flow layout, reach first for padding if possible.
What you're looking at actually has nothing to do with Flexbox, but what's called margin collapse
.outer div {
border: 1px solid;
}
The addition of the border has prevented the margin from collapsing. Rather than relying on margins, I would recommend placing a padding on the parent container:
.outer {
padding-top: 10px;
}
Example:
.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;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div class="wrapper">
<div class='container'>
<div class='item'>item</div>
<div class='item'>item</div>
<div class='item'>item</div>
<div class='item'>item</div>
<div class='item'>item</div>
<div class='item'>item</div>
</div>
</div>
</body>
</html>
Now, to cover all of your prefixes, you need something like this:
.outer {
display: -moz-box;
display: -webkit-flexbox;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-moz-box-orient: vertical;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
height: 100px;
width: 100px;
background: red;
margin: 10px;
}
Finally I came up with the right solution (for my specific problem).
.outer {
display: flex;
flex-direction: column;
height: 100px;
width: 100px;
background: red;
margin: 10px;
}
.inner {
height: 50px;
margin-top: 10px;
background: green;
display: inline-block;
width: 100%;
}
CodePen
I'm using display: inline-block
on .inner
to disable margin collapsing and then compensate for the lost width with width: 100%
.
All the credit goes to cimmanon for pointing me in the right "margin collapse" direction
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With