In CSS, why does the combination of float: left; display:table; margin: x on multiple elements make the margins decrease?
This should not happen. Horizontal margins on block-level tables should be calculated in the same way as with any other block-level non-replaced elements, as described in section 10.3.3 of the CSS2.1 spec, regardless of which table layout algorithm is used. In particular, percentages values for margins should be calculated based on the width of the containing block of the element that you're displaying as a table; since all your elements are siblings that share the same parent and the same margin percentage value, they should be equidistant as long as they are floating block boxes.
In all browsers except Google Chrome, the elements are equidistant, as expected. So my best guess is that this is another Chrome bug.
If you comment out the display: table
declaration — which as you say causes the behavior to return to normal — browsers will still generate anonymous block table boxes within your floats to contain the table cells. This should not adversely affect the layout, but if it does, I can't comment further as I'm not intimately familiar with how table layout works in terms of CSS.
Why does this CSS margin-top style not work?
You're actually seeing the top margin of the #inner
element collapse into the top edge of the #outer
element, leaving only the #outer
margin intact (albeit not shown in your images). The top edges of both boxes are flush against each other because their margins are equal.
Here are the relevant points from the W3C spec:
8.3.1 Collapsing margins
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.
Adjoining vertical margins collapse [...]
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
- 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
You can do any of the following to prevent the margin from collapsing:
- Float either of your
div
elements- Make either of your
div
elements inline blocks- Set
overflow
of#outer
toauto
(or any value other thanvisible
)
The reason the above options prevent the margin from collapsing is because:
- Margins between a floated box and any other box do not collapse (not even between a float and its in-flow children).
- 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.
- Margins of inline-block boxes do not collapse (not even with their in-flow children).
The left and right margins behave as you expect because:
Horizontal margins never collapse.
Why top margins are collapsing but bottom margins are not?
Using "clearfix" with display: table
will keep the bottom margin, display: block
will not.
Src: http://cssmojo.com/the-very-latest-clearfix-reloaded/
Update: Why the top margin collapse is because of no BFC is estabished on its immediate parent
To make the margins not collapse, add a BFC, in this case on the p
parent, like in below sample, by adding for example overflow: auto
.
More to read: Mastering margin collapsing
Update: Why doesn't a <table>
's margin collapse with an adjacent <p>
.left-column,
.right-column {
background-color: orange;
width: 150px;
}
.left-column {
float: left;
}
.right-column {
float: right;
}
.clearfix-using_display-table,
.clearfix-using_display-block {
background-color: yellow;
width: 125px;
overflow: auto; /* establish BFC */
}
.clearfix-using_display-table p,
.clearfix-using_display-block p {
background-color: silver;
width: 100px;
}
.clearfix-using_display-table:after,
.clearfix-using_display-block:after {
content: " ";
clear: both;
}
.clearfix-using_display-table:after {
display: table;
}
.clearfix-using_display-block:after {
display: block;
}
<div class="wrapper">
<div class="left-column">
<h3>Table</h3>
<div class="clearfix-using_display-table">
<p>Lorem Ipsum...</p>
<p>Lorem Ipsum...</p>
</div>
</div>
<div class="right-column">
<h3>Block</h3>
<div class="clearfix-using_display-block">
<p>Lorem Ipsum...</p>
<p>Lorem Ipsum...</p>
</div>
</div>
</div>
What does this combination of :before, :after and display:table do?
It is part of a micro clearfix hack described in details here: nicolasgallagher.com: A new micro clearfix hack
The clearfix hack is a popular way to contain floats without resorting to using presentational markup.[...]
The complete clearfix is:
/**
* For modern browsers
* 1. The space content is one way to avoid an Opera bug when the
* contenteditable attribute is included anywhere else in the document.
* Otherwise it causes space to appear at the top and bottom of elements
* that are clearfixed.
* 2. The use of `table` rather than `block` is only necessary if using
* `:before` to contain the top-margins of child elements.
*/
.cf:before,
.cf:after {
content: " "; /* 1 */
display: table; /* 2 */
}
.cf:after {
clear: both;
}
/**
* For IE 6/7 only
* Include this rule to trigger hasLayout and contain floats.
*/
.cf {
*zoom: 1;
}
[...]This “micro clearfix” generates pseudo-elements and sets their display to table. This creates an anonymous table-cell and a new block formatting context that means the :before pseudo-element prevents top-margin collapse. The :after pseudo-element is used to clear the floats. As a result, there is no need to hide any generated content and the total amount of code needed is reduced.[...]
Why is float:left required in navigation to keep text center when position:absolute applied to header?
The position: absolute
applied to the header makes the div FIXED while all other divs become relatively MOVABLE. So, to make the others also fixed, we give them some other properties like display:inline-block, float:left etc.
Also, need to give a margin-top to the div below the absolute div to offset the collapsing margin
Please see working code with these fixes applied and which has all the divs at https://codepen.io/anon/pen/QqRgRB
The snippet is as follows -
div.header {
position: absolute;
left: 0%;
top: 0%;
width: 100%;
height: auto;
text-align: center;
color: #EE82EE;
background-color: grey;
}
.menu {
text-align: center;
width:100%;
margin:0;
margin-top: 72px;
color:black;
height: 100px;
background-color: red;
float: left;
padding:0px;
display: inline-block;
}
.submenu {
text-align: center;
width:100%;
margin:0;
margin-top: 0px;
color:black;
height: 100px;
background-color: yellow;
display:inline-block;
padding:0px;
}
@media screen and (max-width: 766px){
.menu {
float:none;
}
}
body {
margin:0px;
}
<div class="header">
<h1>HEADER </h1>
</div>
<div class="menu">
<h1>MENU</h1>
</div>
<div class="submenu">
<h1>SUBMENU</h2>
</div>
How do I keep two side-by-side div elements the same height?
Flexbox
With flexbox it's a single declaration:
.row {
display: flex; /* equal height of the children */
}
.col {
flex: 1; /* additionally, equal width */
padding: 1em;
border: solid;
}
<div class="row">
<div class="col">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</div>
<div class="col">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad omnis quae expedita ipsum nobis praesentium velit animi minus amet perspiciatis laboriosam similique debitis iste ratione nemo ea at corporis aliquam.</div>
</div>
HTML 5 strange img always adds 3px margin at bottom
This problem is caused by the image behaving like a character of text (and so leaving a space below it where the hanging part of a "y" or "g" would go), and is solved by using the vertical-align
CSS property to indicate that no such space is needed. Almost any value of vertical-align
will do; I'm fond of middle
, personally.
img {
vertical-align: middle;
}
jsFiddle: http://jsfiddle.net/fRpK6/1/
Related Topics
HTML Textarea Horizontal Scroll
Text-Align: Right; Only for Placeholder
How to Make an Input Element Occupy All Remaining Horizontal Space
Why Does Width Apply to a Button with Display Inline
How to Make Last Cell of a Row in a Table Occupy All Remaining Width
How to Make Responsive Website for All Devices
If an HTML Form Has Two <Input Type="Submit"> Buttons, How to Know Which Got Clicked
Why Is "" Being Injected into My HTML
How to Use the Same Meta Tag for Opengraph and Schema.Org
Double Dotted Border While Using Colspan
Twitter-Bootstrap Closing Alert Does Not Work
Bootstrap Carousel Indicators Are Square; I Want Them Round
How to Vertically Align a <Table> in the Middle of a Fixed Height <Div>