margin not overlap when the outer explicit set height - html

I wonder why the phenomenon will happen?
the inner div set margin-bottom 16px
As far as I know,the outer div contact with the inner div,no padding or border,if the outer div isn't set height css style,the under div will 16px away from the outer div, because the margin is overlap.However,if height css style is set on the outer div,the under div is close to the outer div.
so,can you explain how this phenomenon is caused?
.outer {
background: yellow;
height: 100px;
}
.inner {
height: 100px;
background: green;
margin-bottom: 16px;
}
.under {
background: red;
height: 10px;
}
<div class="outer">
<div class="inner"></div>
</div>
<div class="under"></div>

So first things first, let's address this:
if you remove height css style on the outer div,you will find the under div is move down
This is due to Margin Collapsing:
If there is no border, padding, inline part, block formatting context created, or clearance to separate the margin-bottom of a block from the margin-bottom of its last child, then those margins collapse. The collapsed margin ends up outside the parent.
These rules apply even to margins that are zero, so the margin of a first/last child ends up outside its parent (according to the rules above) whether or not the parent's margin is zero.
Your child margin is collapsing with the parent margin, thus the 16px margin acts as part of the parent.
However by specifying a height, you negate margin collapsing.
From the W3 Box Model spec*:
Two margins are adjoining if and only if:
Both belong to vertically-adjacent box edges, i.e. form one of the following pairs:
The bottom margin of a last in-flow child and bottom margin of its parent if the parent has 'auto' computed height
Because the margins do not collapse, the child's margin will simply attempt to expand the height of the outer div (which won't be reflected, because the parent has a strictly set height of 100px).
But wait... what if we broke the collapse some other way? Would we see the height increase by 16px?
Two margins are adjoining if and only if:
no line boxes, no clearance, no padding and no border separate them
Seems easy enough. Let's add a border to break this rule.
.outer {
background: yellow;
border-bottom: 1px solid black;
}
.inner {
height: 100px;
background: green;
margin-bottom: 16px;
}
.under {
background: red;
height: 10px;
}
<div class="outer">
<div class="inner"></div>
</div>
<div class="under"></div>
Voila! As expected, the margins do not collapse, therefore the child's margin attempts to expand the height of the parent. With no height property on the parent to counter this, the height of the parent grows to 116px.
* This is pointing at an older spec, however this behavior has not changed. In fact, some of the newer spec documents I've found reference/link to this one.

You cannot add a margin to child element to affect on a parent element. You may add margin-bottom:16px; to Outer class as below
.outer{
background:yellow;
height:100px;
margin-bottom:16px;
}

inner is nested inside outer, and under is directly underneath outer with no space or padding. So regardless of the margin given to inner, there'll be no space between outer and under.
You can do this by simply adding a margin-top to under.
.outer{
background:yellow;
height:100px;
}
.inner{
height:100px;
background:green;
}
.under{
background:red;
height:10px;
margin-top:16px;
}

set .outer height:auto;
.outer{
background:yellow;
height:auto;
}
.inner{
height:100px;
background:green;
margin-bottom:16px;
}
.under{
background:red;
height:10px;
}
<div class="outer">
<div class="inner"></div>
</div>
<div class="under"></div>

Related

Padding missing on one side of scrollable div

Take a look at my snippet.
The parent div has a scrollbar and a child div.
Why is the padding (5px) missing on the right side?
#moh
{
background:red;
overflow-x:auto;
width:100px;
padding:5px; // this padding should be on all 4 sides
}
#moh div
{
width:500px;
height:50px;
background:green;
}
<div id="moh">
<div></div>
</div>
To get the bounty I want to know the reason for the missing padding. Maybe there is a name for this phenomenon. Or may it be a browser bug?
It would be excellent to know the part in the CSS or HTML specification which is responsible for the missing padding. But this is not required to get the bounty (Because I know it's hard to find).
#moh
{
background:red;
overflow-x:auto;
width:100px;
padding:5px;
}
#moh div
{
/* width:500px; */
height:50px;
background:green;
}
<html>
<head>
</head>
<body>
<div id="moh">
<div></div>
</div>
</html>
The padding on the right hand side doesn't appear because, the total width of the parent div is 100px(width) + 10px(padding) while the width for the chid div is explicitly set to 500px.
Since the chid div is a block level element and width property greater than that of the parent, it will move past the parent element and hide the right border from the parent div.
Solutions
either remove the width attribute in the child div (so it will take full width of the parent)
or set the width of the parent to at least 500px which is the width of the child element
The reason for this can tell. It's hard to explain, but I'll try. Your" moh " div width value is 100px," moh " in the div width value is 500px. The order of items on Pages is normally left to right. If you do not apply overflow, you see the overflowing sections :
#moh {
background: red;
width: 100px;
padding: 5px; // this padding should be on all 4 sides
}
#moh div {
width: 500px;
height: 50px;
background: green;
}
<div id="moh">
<div></div>
</div>
As you can see, there's an overflow from left to right. when you give overflow, The Overflow will be hidden automatically. So where's the overflow ? (left ? right ? ) That's why it will try to hide everything from the overflow, that is, the part that goes out when it doesn't fit. The part he's trying to hide is in the padding, so that part doesn't show up.
I'm sorry if I said anything that would be misunderstood. Maybe I helped you understand a little bit.
It happens because #moh is 100px and the inner div is 500px. The solution is to set them both to 500px and wrap them with a 3rd div that is limited to 100px with overflow-x.
#wrapper {
overflow-x: auto;
width: 100px;
}
#moh {
background: red;
width: 500px;
padding: 5px; // this padding should be on all 4 sides
}
#moh div {
width: 500px;
height: 50px;
background: green;
}
<div id="wrapper">
<div id="moh">
<div></div>
</div>
</div>
#wrap
{
overflow-x:auto;
width:100px;
}
#inner
{
background:red;
padding: 15px;
width: 500px;
}
#inner div
{
width:500px;
height:100px;
background:green;
}
<div id="wrap">
<div id="inner">
<div></div>
</div>
</div>
one solution would be this:
I had to add some more HTML but hope it solves your problem
It's because of the html behavior of block element like DIV and css overflow property.
By default html elements flow from left to right.
Browsers by Default behavior is -
If parent DIV have any width property (or specific width
inherited) and no css overflow rule is defined, and if child DIV
have defined width which is more than the parent can accommodate,
then it will overflow and will grow beyond the right edge of parent.
To control how Parent Div will deal with overflowing, css overflow
property can be used. overflow:hidden will instruct browser to crop
the exceeding width div at the edge.
overflow-x:auto will instruct browser that, when child element
exceeded width beyond the edge then add scrollbar at x-axis.
So, in the example case above, the child div is having greater width than parent and it is exceeding of the parent. And parent div is having 'overflow-x:auto' rule defined, the scrollbar is appearing upto the edge of parent.
Since padding is inside the edge of the div, it does not considered.
If you want to have padding on all side of the parent div.
Treat the parent div as a grandparent by adding one more div inside a parent and moving child div in it.
On grandparent div you can add required padding and width.
3 On new parent set width:100% which will expand to fit in a grandparent and setting overflow-x:autorule will add scrollbar when the child div expand beyond the parent width.
So, the code will be something like -
#moh
{
background:red;
width:100px;
padding:5px; // this padding should be on all 4 sides
}
#moh div
{
width:500px;
height:50px;
background:green;
}
div{
box-sizing:border-box;
}
#moh div.moh-container{
width:100%;
overflow-x:auto;
}
<!-- Grand parent Div for padding and width -->
<div id="moh">
<!-- Parent Div width 100% to fit in grandparent and overflow rule -->
<div class='moh-container'>
<!-- child element with exceeding width -->
<div></div>
</div>
</div>
Fiddle -
https://jsfiddle.net/guruling/471ka569/13/

CSS relative container does not scale with margin-child-elements

I've got the following problem:
I want to have a relative container element that contains some child elements each with margin.
If i dont set the height of the container, it resizes height / width by its containing children.
Problem is that it seems to ignore the margin on them.
here some code:
css:
.container{
position:relative;
}
.child {
position:relative;
float:left;
width:200px;
height:50px;
margin-bottom:20px;
}
html:
<div class="container">
<div class="child">hello world</div>
</div>
The container should now resize height to 50+20 = 70px,
so if i put another element below it should be ok but it isn't.
Margin seems not to resize containers height, how to change this?
Not getting your question quiet well but you are probably missing to clear your floats...
Demo
.container{
position:relative;
border: 1px solid #f00;
overflow: hidden;
}
Alternatively you can also use clear: both;
Demo
Depending on the effect you are trying to achieve, either:
1) Add 'overflow:hidden' to the .container div
or
2) Use padding-bottom instead of margin-bottom on the .child div

Why the two divs are not aligned?

<div id="container">
<div id="top"></div>
<div id="left"></div>
<div id="right"></div>
<div id="clear"></div>
</div>
#container{
width:200px;
margin-left:auto;
margin-right:auto;
margin-top:50px;
}
#top{
width:200px;
height:20px;
border:medium ridge #FFF;
}
#left{
float:left;
width:50px;
height:20px;
border:medium ridge #FFF;
}
#right{
float:right;
width:40px;
height:20px;
border:medium ridge #FFF;
}
#clear{
clear:both;
}
Why the #right and #top are not right aligned?
Its because the top element is actually overflowing the bounds of the container, while the floated element right is being restricted to it. The top element is overflowing the container because the border is not included in the width. So top is actually occupying 204px.
Problem Illustrated via Example: http://jsfiddle.net/KhJ6e/2/
To fix, adjust top to account for the 2px border on each side. (subtract 4 from width of container) or specify width as auto depending on your intentions.
#top{
width:196px;
height:20px;
border:medium ridge #FFF;
}
Example: http://jsfiddle.net/KhJ6e/1/
The top is wider than it's parent container
#top{
width:auto;
}
The problem is how the width is calculated for the box model. All elements on the screen have 4 components (inner to outer): content, padding, border, margin. By default, the width includes only the content. By adding the borders, top becomes larger than 200 pixels. Using the developer tools in chrome, it was rendering as 206px.
There are two possible solutions, one is fudge the widths, or two modify the box model. The first will work, but it is difficult to maintain. Any small change can mess up the alignment.
A better solution is to use box-sizing: border-box. By adding that CSS style, the width attribute will include content, padding, and border. So, originally padding and border wrap around the outside, but with border-box, the encroach on the inside.
Original: http://jsfiddle.net/deafcheese/Gv5BZ/
Corrected (using
boz-sizing: border-box): http://jsfiddle.net/deafcheese/Gv5BZ/1/
box-sizing reference: http://css-tricks.com/box-sizing/

padding is getting added to width of div

i use this code
<div class="main">
<div class="babyOne">
</div>
<div class="babyTwo">
</div>
</div>
.main{
width:100%;
position:relative;
}
.babyOne,.badyTwo{
width:50%;
float:left;
}
with this CSS above everything works fine.
but as soon as i give padding to inner divs all the ui breaks,
.babyOne,.badyTwo{
width:50%;
float:left;
padding:5px;
}
and fire bug shows the increase in the width of divs equal to padding.
According to padding property this should not happen.
any idea how to prevent this?
First of all you need to learn CSS box-model
This states that whatever padding, border, margin you add to you element does count outside it, so for example the element is of 200px width and 100px height, if you add padding say 5px than the width and height will be 205px and 105px respectively, so inorder to workaround with this you need to use CSS3 box-sizing property, but as still it is CSS3 property and if IE is the main thing you want to supprt, I suggest you to resize the elements according to your needs
So for example a div with these styles
div {
height: 100px;
width: 200px;
padding: 5px;
}
You can re-size the above as
div {
height: 95px;
width: 195px;
padding: 5px;
}
CSS3 box-sizing Reference
The WRAPPER must have fixed size: http://jsfiddle.net/esVgH/1 example:
.main{
width:200px;
position:relative;
}
Another solution is display the .baby as a table cell:
.babyOne, .badyTwo {
display: table-cell;
}
Your problem is the expected behaviour.You set a width and then you say give it some padding.So the width plus the padding is going to be greater than the original width.
You can try CSS3s box-sizing attribute: http://www.quirksmode.org/css/box.html
I'm not sure how widely supported it is though.
There's also a host of SO answers here: How apply padding in HTML without increasing the div size?
.babyOne,.badyTwo{
width:45%; /* As you have like based on padding */
float:left;
padding:5px;
}

Padding in floated elements

I have a top bar, separated to three sections. Left section, center section and right section.
Every section is floated, so their position is in line.
What i would like to do is to set a padding to the left and right element.
10 left padding to left element.
10 right padding to right element.
But whenever i apply some padding for example the div element #tbl {padding-left:10px;} whole structure breaks.
What i want to achieve:
Code:
HTML:
<div id="topbar">
<div id="tbl">abc</div>
<div id="tbc">abcd</div>
<div id="tbr">abc</div>
</div>
CSS:
#topbar {
width:100%;
height:36px;
padding-top:12px;
background-color:#e7e6e6;
border-top:1px solid #d0cdcd;
border-bottom:1px solid #d0cdcd;
}
#tbl {float:left; width: 35%; text-align:left;}
#tbc {display:inline-block; width: 30%; text-align:center;}
#tbr {float:right; width: 35%; text-align:right;}
JSFIDDLE: http://jsfiddle.net/bkwdX/
Thanks
try decreasing the width of them because the padding's add up to outer width, not inner width. you define an elements width as 300px and add 10px right padding to it, the width will take 310px vertical space (in some browsers).
width:100% = width of the floated elements + padding
So you need to set width for the floated elements lower than 100% to let some space for the padding.