Margin top in inline element - html

My question is pretty simple:
Why is the margin top ignored for inline elements in firefox?
Does anyone know?

This is not Firefox-only, and defined in the CSS 2.1 Specification:
8.3 Margin properties: 'margin-top', 'margin-right', 'margin-bottom', 'margin-left', and 'margin'
Margin properties specify the width of the margin area of a box. The 'margin' shorthand property sets the margin for all four sides while the other margin properties only set their respective side. These properties apply to all elements, but vertical margins will not have any effect on non-replaced inline elements.
(Emphasis at the end is mine; margin-top is a vertical margin)

inline elements can apply only margin letf and right but if you are using firefox it also appear margin bottom and top after inspect element but it doesn't apply realy

Related

CSS Margins strange behavior [duplicate]

This question already has answers here:
CSS margin strange behavior, why?
(3 answers)
Closed 8 years ago.
I don't understand the following behavior:
jsFiddle
If I take a div and I set the top and bottom margins and the div has and height of 0px, only the top margin will be used, but if I set the height of the div to 1px all is working right.
Why is this happening?
Edit
based on the article cited on #Krzysztof Trzos's answer I understood that this behavior is based on
Empty blocks
If there is no border, padding, inline content, height, or min-height to separate a block's margin- top from its margin-bottom, then its top and bottom margins collapse.
And in the same article there is written
Margins of floating and absolutely positioned elements never collapse.
so to prevent this you can set the float:left attribute or overflow:auto
(thx to #SW4 for the second)
Try using padding instead of margin
http://jsfiddle.net/qa011xhu/1/
I thing the thing with the margin is that it's overlapping on itself. Like it would be if there would be two containers one above another and the first one would have margin-bottom: 10px; and 2nd one margin-top: 10px;. There would be space 10px between them, not 20px.
And, found this article:
https://developer.mozilla.org/en-US/docs/Web/CSS/margin_collapsing
Empty blocks
If there is no border, padding, inline content, height, or min-height to separate a block's margin-top from its margin-bottom, then its top and bottom margins collapse.
This is due to margin collapsing
Top and bottom margins of blocks are sometimes combined (collapsed)
into a single margin whose size is the largest of the margins combined
into it, a behavior known as margin collapsing.
You can overcome it by either using padding, or enforcing a new block formatting context on the collapsed element using overflow:auto or overflow:hidden
A block formatting context is a part of a visual CSS rendering of a
Web page. It is the region in which the layout of block boxes occurs
and in which floats interact with each other.

Does html specification state what happens when both bottom and margin-bottom are specified?

To me specifying both bottom and margin-bottom seems like a contradiction. Because both are means to specify indent between the element and surrounding elements/containers. That is, bottom should be measured from the border, otherwise it's indent measured from indent. Does anyone know what the specification has to say?
bottom property "specifies how far a box's bottom margin edge is offset above the bottom of the box's containing block"1. And
The margin edge surrounds the box margin. If the margin has 0 width, the margin edge is the same as the border edge. The four margin edges define the box's margin box."2
So yes, specification says that bottom is measured from margin edge.

Basic HTML/CSS - margin & display behaviour

I have a basic question regarding HTML/CSS and the behaviour of margins from certain elements.
To make my point clear, I created this fiddle: http://jsfiddle.net/5VA5h/
You see, I applied some kind of "reset" and added some styles to all h1.
In the first example, the margin from h1 is applied on the outside of the box, while in #c, where h1 is set display: inline;, it is applied inside the box.
Why is this so?
In your first example, with the <h1> as a block element, the top margin is collapsing (emphasis mine):
In CSS, the adjoining margins of two or more boxes (which might or might not be siblings) can combine to form a single margin. Margins that combine this way are said to collapse, and the resulting combined margin is called a collapsed margin.
...and later:
Two margins are adjoining if and only if:
both belong to in-flow block-level boxes that participate in the same block formatting context
no line boxes, no clearance, no padding and no border separate them (Note that certain zero-height line boxes (see 9.4.2) are ignored for this purpose.)
both belong to vertically-adjacent box edges, i.e. form one of the following pairs:
top margin of a box and top margin of its first in-flow child
bottom margin of box and top margin of its next in-flow following sibling
bottom margin of a last in-flow child and bottom margin of its parent if the parent has 'auto' computed height
top and bottom margins of a box that does not establish a new block formatting context and that has zero computed 'min-height', zero or 'auto' computed 'height', and no in-flow children
The second example, with the <h1> as an inline element, the vertical margins do not take effect:
The 'margin' shorthand property sets the margin for all four sides while the other margin properties only set their respective side. These properties apply to all elements, but vertical margins will not have any effect on non-replaced inline elements.
Margin-Top and Margin-Bottom is not used by elements with display:inline;
See: Margin top in inline element
Top and Bottom margins in inline elements are not important. In inline elements, each element represents a word in a text.

Removed margins above and below a <div> element?

I've come across a strange behavior related to the margins of a <div> element. I've added a very simple test case to jsFiddle to show you what I mean.
Interestingly the margins are used correctly when using a border. Is this the default behavior? Does this have something to do with collapsing margins? Is it possible to somehow force the margins without any hacks?
Least ugly solution so far that I thought of:
.cssContainer {
margin:10px;
padding:0.1px;
background-color:#FF0000;
}
But I don't know whether this will work in every browser.
This is another case of adding overflow:auto to the rescue!
jsFiddle example
Just add overflow:auto to your container div and voila, harmony is restored.
.cssContainer {
margin:10px;
padding:0px;
overflow:auto;
background-color:#FF0000;
}
From specs, the reason this works is because a new block formatting context is established by applying overflow other than visible, forcing margins of .cssContainer to not collapse with its in-flow children .cssElement.
From this site
the simplest way to stop the margin collapse from occurring is to add
padding or borders to each element. If we wanted 10px margins on each
element we could simply use a 9px margin and 1px of padding to get the
result we wanted
This is due to the CSS box model. The elements with the red backgrounds will not grow in height to accommodate the top and bottom padding of its children elements, but because the border was specified in the second example and encompasses the padding, the padding will show.
The overflow: auto; property works because the padding overflows its parent element. To illustrate this, in Google Chrome Developer Tools, find and click the HTML row for the green element whose bottom padding will not show. Chrome will highlight the element on the page. Notice how the padding is included in the highlighted element. The padding actually overflows the parent element. The parent element won't show it though because there's no content in or after the padding (no 'bounds').
From the css spec regarding box models:
Adjoining vertical margins collapse, except:
...
Horizontal margins never collapse.
Two margins are adjoining if and only if:
...
both belong to vertically-adjacent box edges, i.e. form one of the following pairs:
top margin of a box and top margin of its first in-flow child
bottom margin of box and top margin of its next in-flow following sibling
bottom margin of a last in-flow child and bottom margin of its parent if the parent has 'auto' computed height
...
Note the above rules imply that:
...
Margins of elements that establish new block formatting contexts (such
as floats and elements with 'overflow' other than 'visible') do not
collapse with their in-flow children.
Unfortunately, text-overflow: auto is slightly risky because the spec says:
auto
The behavior of the 'auto' value is user agent-dependent,
but should cause a scrolling mechanism to be provided for overflowing boxes
However, all browsers that I have looked at appear to implement it in the following manner:
The box is expanded to the smaller amount between:
as much as its containing box allows
as much as is necessary to display the content without clipping
Then if clipping must occur, a scrollbar is added.

Why this behaviour (on ALL browsers) with margin-top?

This is my code :
HTML
<div class='father'>
<div class='son'>Son</div>
</div>
CSS
.father
{
background-color:blue;
}
.son
{
margin-top:50px;
background-color:red;
height:50px;
}
Where is the background-color blue of the father?
I know how to fix this problem (putting padding-top:1px to the father) but I'd like to know why of this behaviour!
For me it doesnt make sense, because on every browsers, not only IE, this is the behaviour.
This is a result of Collapsing Margins. You can read a good article by Eric Meyer on this topic where he illustrates this exact behavior. The following image is from his article.
Here's what the CSS2 specification has to say about it.
8.3.1 Collapsing margins
If the top and bottom margins of a box are adjoining, then it is
possible for margins to collapse through it. In this case, the
position of the element depends on its relationship with the other
elements whose margins are being collapsed.
If the element's margins are collapsed with its parent's top margin, the top border edge of the box is defined to be the same as
the parent's.
Otherwise, either the element's parent is not taking part in the margin collapsing, or only the parent's bottom margin is involved.
The position of the element's top border edge is the same as it
would have been if the element had a non-zero bottom border.
Note that the positions of elements that have been collapsed through
have no effect on the positions of the other elements with whose
margins they are being collapsed; the top border edge position is only
required for laying out descendants of these elements.
Source: http://www.w3.org/TR/CSS2/box.html#collapsing-margins
This is because the div is a block-level element. Certain block-level elements don't contain any padding by default. Divs are one such element. Block-level elements will take up the entire height and width of the container while respecting any padding it may contain.
W3C Visual formatting model
The parent element's height is set to its content's height by default. Once you set a height on the parent, that's no longer the default. Checking up on it, I believe that the padding adds to the height. So, the height is originally determined by the content unless otherwise stated in the CSS. Then, in most cases (IE 6 may be the exception), the padding is added to the height.
Good thing about SO, it helps us be much more detailed in our responses. :)
In CSS, block level elements naturally fills the elements content area, so your "son" div is filling your "father" div completely. Of course, you can bypass this by adding margin/padding/height to your parent div.
You're setting blue explicitly:
.father {
background-color:blue;
}
It's overridden (thanks to the "C" in CSS a.k.a cascading) but the style remains on your parent element (here, appropriately named "father").
If your .father box receives any height at all (check in the Firebug/Chrome dev tools inspector) than the blue is going to show through. I am guessing this is what you're seeing in IE (that or perhaps there's a flash of content before your child element style comes in). I don't think the IE debug tools show bounding boxes but you can test the element for it's height using JavaScript.
Moving outwards from the content, you have padding, border, and margin (as you probably know). Background covers only padding, but not margin.