Include margins in flex calculation? - html

I've this fiddle:
http://codepen.io/FezVrasta/pen/rOvpqL
<div class="r1"></div>
<div class="r2"><button>toggle</button></div>
<div class="r1 target"></div>
Where I have 3 divs inside a flexbox, each div has a margin bottom.
One of these divs can toggle (hide/show).
The problem is that the first div should not change its size theoretically, but in practice it does.
I think the problem is flex not taking in account margins.
Is there a solution using flex?

In this case the flexbox-layout is missing 10px when you're removing the bottom element (corresponding to the element's margin-bottom) .
You can overcome this adding flex-basis: 10px to .r3. that will compensate the missing 10px.
pen

Related

Middle align a div vertically in another div using percentage value

<!DOCTYPE html>
<html lang="en">
<head>
<title>tested html</title>
<meta charset="utf-8">
</head>
<body>
<div id="outer-div" style="height:20em;background-color:red;">
<div id="inner_div" style="height:50%;margin-top:25%;margin-bottom:25%;">This the inner-div to be centered inside outer-div</div>
</div>
</body>
</html>
There are already many solutions to center(vertically only) a div inside another one, but i just wonder why the inner_div above cannot get centered in its parent div(outer-div)?
The picture below is the html rendering result from my opinion, but actually result is completely different -- the outer-div get pushed down by inner-div's margin settings. so why?
Part 1. Collapsing Margins.
the outer-div get pushed down by inner-div's margin settings. so why?
This is a normal HTML rendering behavior and it is called collapsing margins. Excerpts from the specification:
Adjoining vertical margins collapse [...] Two margins are adjoining
[...] top margin of a box and top margin of its first in-flow child
To explain it a bit, when you have a parent and its first child, with at least one of them having a top margin, the larger of the existing margins will be applied to the parent. (Except in some well defined situations - read the specs to see which they are.)
Part 2. Centering without extra elements.
i just wonder why the inner_div above cannot get centered in its
parent div(outer-div)?
It actually can get centered, by using Flexbox with justify-content and justify-content both on center.
.parent {
width: 300px;
height: 200px;
background-color: Green;
display: flex;
justify-content: center;
align-items: center;
}
.child {
width: 200px;
height: 100px;
background-color: Red;
}
<div class="parent">
<div class="child"></div>
</div>
There are other techniques as well that can achieve the same result (by mixing table and inline display modes), but I wouldn't recommend using those in this century.
Use padding-top and padding-bottom instead of margin if you want to move you child div inside parent div.
<div id="outer-div" style="height:20em;background-color:red;">
<div id="inner_div" style="height:50%;padding-top:25%;padding-bottom:25%;">This the inner-div to be centered inside outer-div</div>
</div>
Fiddle
Because padding gives space inside the container and margin gives the space outside the container. This is the basic concept.
Edit:
To clarify your confusion i have added background-color:yellow to inner div.
Fiddle Link contains margin-top as inner div take space from outside it will also move the outer div to below as it is position:static.
Instead give position:absolute as here it will move mover outer div to below.
This two image will explain more.
In above image you can check that inner div taking the margin. Check the pointer and yellow color is margin you can see from inspecting element.
And in above this image there is no margin show the outer div. As we point the outer div. But it just move the div below because of inner div.

padding within in a div

I simply can't figure this out: I have a div that is centered on screen with a width of 60%. Inside this div I have 3 more divs that float left with the width of 33% and have a gray bg color. The divs are filled with text and one image per div. Each div should now take 1/3 space inside the "maindiv". This works fine but as soon as I give my 3 "contentdivs" a padding so the text gets seperated a bit the third div wanders below the others. I also want a margin around my 3 divs so there is a gap between all the divs. But this only works if I give the divs a width of like 31%. As soon as I shrink my browser though, the third one pops up below the others again.
How it looks now:
How it looks with a width of 33.33%
How can fix this? I mean I set the divs to a relative width by setting the size in %. So the divs should just shrink as soon as I shrink my browser window. I tried to surround all the divs by other divs and messed around with margins and paddings but it just won't work.
Most likely it’s box model’s fault. Paddings, margins and borders can be added together in different ways. Add box-sizing:border-box to the container and its elements. Most certainly this brings about what you intended to do, and width:33.3333% wil work out as expected.
Adding margin still breaks the item? There’s another great thing called calc(). Assumed you have a margin of 8px, that’s just a few pixels too much. With calc(), you can subtract the additional margin like this:
.item{ width:calc(33.3333vw - 8px); }
Note that there must be whitespace around the minus. Try it and include your margin.
Apply box-sizing: border-box to all related elements (or the entire document, as Bootstrap does). http://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing
Then, rather than margin, use padding for the outer spacing. This eliminates the need to do mental math altogether.
div {
box-sizing: border-box;
}
.one-third, .inner, .full-width {
padding: 8px;
}
.one-third {
float: left;
width: 33.333%;
}
.inner {
background-color: pink;
}
<div class="full-width">
<div class="inner">Full-width div</div>
</div>
<div class="one-third">
<div class="inner">Content</div>
</div>
<div class="one-third">
<div class="inner">Content</div>
</div>
<div class="one-third">
<div class="inner">Content</div>
</div>
Fiddle demo
Your best bet would be to get the three columns and margins to equal 100%. This is fairly easy if you know you are only having three columns:
.item {
width:32%;
margin-left:2%;
}
.item:first-child {
margin-left:0;
}
As long as there is only three it will always add up to 100% as you are overriding the first .item. If you don't override the first item then you will have a space before your columns and the last column won't fit. Mixing pixels and percentages will give you issues in a grid (unless they're paddings and you are using box-sizing). Margin is not included in the box-sizing as it is not part of the main box model.

Elements that don't take their children's width or height

I have run across this problem from time to time and have never been able to understand what causes it.
<div id="wrapper">
<div id="primary">content</div>
<div id="secondary">content</div>
</div>
#primary {
width:50%;
float: left;
}
#secondary {
width: 50%;
}
And then you look at the properties on Chrome's inspect element and the wrapper div shows up as 0px height and 0px width.
This is commonly referred to as the clearfix issue. An alternative to placing an inline-styled div below would be to assign overflow:hidden to the wrapper div.
For more information about clearing issues, check out A List Apart: CSS Floats 101 (Section 6: Collapsing specifically)
You need to add a <div style='clear:both'></div> below the <div id='secondary'/>. The CSS tag "float" does not allow the parent to see where the children actually end. Adding the div that clears the left and right sides of any floats allow the parent element to fill the space correctly.
You need to try and clear the div with the float, so try these, adding a <div> after the second div, and adding style="clear:both" to the div i just said to create as the style, or you can simply specify the exact height & width of the wrapper div, let me know what happens please. good luck!

center content on page with margin

if I want to center content on my page, I can simply apply margin: 0 auto to it.
But that makes zero margins. How can I do if I want a minimum of, say, a couple ems of margin on the right and left.
thanks
Wrap the content in a div with margin.
You can set a width to the div which you are wrapping your content,and apply margin
You'll need to apply padding or margin to the parent element.

Child elements with margins within DIVs

I need two consecutive div elements (with backgrounds) to be touching seamlessly, one below the other. However, this layout breaks when I put a child p element into the bottom div. The margins of the p element force a blank gap between both div elements. This is strange behavior, as I am expecting the margin of the p to stay within the content and background area of the div. It renders the same way on Firefox, Chrome and IE 8.
<div style="background: #ccccff">Top Div</div>
<div style="background: #ffcccc"><p>Bottom Div</p></div>
Here's what it looks like.
I could fix this by changing the margins to paddings for the p element, but then I would also have to do this with header elements, list elements, and any other element I want to use at the start of a div. That is not desirable.
Could someone enlighten me: what caveat of the box model am I missing? Is there an easy way to fix this, preferably by modifying the style of the div?
Add overflow: hidden or overflow: auto to the div
That is the expected behavior*. There are a few ways to get around it. If you float the divs, they will contain the margins of child elements and prevent margin collapsing. Another approach is to add a border or padding to the divs.
* The margins of the div and the p "combine to form a single margin", even though they are nested, because they have adjoining margins with no padding or border between them.
Solution 1
Add overflow: hidden/auto to the containing div to prevent the margin collapsing.
Solution 2
Add positive padding to the containing div and equal negative margin to the inner element
New Solution
Add padding of 0.01px to the containing div, this will prevent the margin collapsing but won't need any negative margin on the inner element.
Setting a positive padding, and a corresponding negative margin on the div element seems to fix the issue, though I know not why.
<div style="background: #ccccff">Top Div</div>
<div style="background: #ffcccc; padding: 1px; margin: -1px"><p>Bottom Div</p></div>