margin on h1 element inside a div - html

I have a div container which has a h1 element within it:
<div id="header">
<h1>Enlighten Designs</h1>
</div>
I have applied a margin-top,a margin-left and a margin-right to the header element.
However the margin-top is not being applied to the header element box wrt to the containing div.
Instead the top margin is being applied to the containing div.
The left and right margins of the header are being applied to the header element box wrt the containing div.
The style rules for the div and header are as follows:
#header {
background: blue;
height: 150px;
}
h1{
background: orange;
margin-top:30px;
margin-left: 10px;
margin-right: 10px;
}
What is the reason for this behavior?

Your 'problem' is that margins in CSS will collapse onto eachother.
Read this awesome article explaining the concept, management summary:
In simple terms, this definition indicates that when the vertical
margins of two elements are touching, only the margin of the element
with the largest margin value will be honored, while the margin of the
element with the smaller margin value will be collapsed to zero.
In your case, specifically read the section "Collapsing Margins Between Parent and Child Elements" a few pages down. In your case, the following CSS 2.1 rule applies:
The top margin of an in-flow block element collapses with its first
in-flow block-level child's top margin if the element has no top
border, no top padding, and the child has no clearance.

Well, the solution is to add overflow: hidden; property to your header element.
Here JsFiddle.

#header {
background: blue;
height: 150px;
position:absolute;
}
h1{
background: orange;
margin-top:30px;
margin-left: 10px;
margin-right: 10px;
position:relative;
}

Related

Adding a border "pushes down" contents [duplicate]

This question already has answers here:
CSS: Margin-top when parent's got no border
(7 answers)
Impact of border property on top margin
(3 answers)
Why does this CSS margin-top style not work?
(14 answers)
Margin on child element moves parent element
(18 answers)
CSS margin terror; Margin adds space outside parent element [duplicate]
(7 answers)
Closed 5 years ago.
I have a p element with a paragraph of text inside a div element. Without a border on the div element, the p element is positioned in the top-left corner, but if I add a border to the div element it "pushes down" the paragraph from the top edge (not the left edge, however).
Why does this occur?, and is there a method of preventing this?
html,
body {
height: 100%;
}
div {
min-width: 300px;
max-width: 500px;
min-height: 200px;
max-height: 450px;
height: 100%;
background-color: Pink;
}
div.first {
border-width: 2px;
border-style: solid;
border-color: Black;
}
p {
width: 75%;
height: 75%;
background-color: Black;
color: White;
}
<div class="first">
<p class="one">Paragraph one text...</p>
</div>
<div class="second">
<p class="two">Paragraph two text...</p>
</div>
UPDATE:
You can prevent this movement by adding margin: 0; to the style of your p tag. See below for an explanation of how and why this happens.
The reason your p tag gets pushed down is because of margin collapsing (or, rather, margins not collapsing when you set a border).
See this page for a more in-depth explanation of how it works. From that page:
The top and bottom margins of blocks are sometimes combined (collapsed) into a single margin whose size is the largest of the individual margins (or just one of them, if they are equal), a behavior known as margin collapsing. Note that the margins of floating and absolutely positioned elements never collapse.
Basically, your margins are getting collapsed by the browser when you don't have a border set, yet they are calculated when you do set that border.
For ways to prevent the browser from collapsing margins, see this question. From that question (first part originally quoted from this other question):
Found an alternative at Child elements with margins within DIVs You can also add:
.parent { overflow: auto; }
or:
.parent { overflow: hidden; }
This prevents the margins to collapse. Border and padding do the same. Hence, you can also use the following to prevent a top-margin collapse:
.parent {
padding-top: 1px;
margin-top: -1px;
}
This is related to margin collapse.
The margin on the <p> element collapses with it's parent.
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.
Note that:
Adjoining vertical margins collapse... if and only if... no line boxes, no clearance, no padding and no border separate them.
In order to prevent margin collapse on both of your examples, you can use methods other than border. For example, overflow:auto:
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.
html,
body {
height: 100%;
}
div {
min-width: 300px;
max-width: 500px;
min-height: 200px;
max-height: 450px;
height: 100%;
background-color: Pink;
overflow: auto;
margin: 0 0 1em;
}
div.first {
border-width: 2px;
border-style: solid;
border-color: Black;
}
p {
width: 75%;
height: 75%;
background-color: Black;
color: White;
}
<div class="first">
<p class="one">Paragraph one text...</p>
</div>
<div class="second">
<p class="two">Paragraph two text...</p>
</div>
See also:
Mastering margin collapsing.
What You Should Know About Collapsing Margins.

Webkit Extra Space at the top of the 'body' element when setting a margin-top on a descendant element

I was playing around with making my page occupy the full viewport with this basic
html {
height: 100%;
}
body {
min-height: 100%;
}
but I noticed that when I added a block element with a margin, the page sizing was off by the amount of the margin. To demonstrate, try this html in a webkit browser:
<html style="height: 100%; margin: 0; padding: 0;">
<body style="min-height: 100%; margin: 0; padding: 0;">
<h1 style="margin-top: 100px;">Box Sizing</h1>
</body>
</html>
You will notice that the body always overflows the html element, causing it to scroll. Does anybody know why this is overflowing?
This is known as collapsing margins. The vertical margin on the h1 element is collapsing with the body element, which causes the adjoining margins to combime and form a single margin, thereby resulting in the body element being shifted down (as though it has a margin-top of 100px.
According to section 8.3.1 of the relevant spec, the following rule(s) prevent the margins from collapsing:
Margins of inline-block boxes do not collapse (not even with their in-flow children).
Therefore you could simply set the display of the element to inline-block and then add width: 100%. You could also float the element as well:
Margins between a floated box and any other box do not collapse (not even between a float and its in-flow children).
In the updated example below, I simply set the display of the h1 element to inline-block so that the margins no longer collapse.
html {
height: 100%;
}
body {
min-height: 100%;
margin: 0;
}
h1 {
margin-top: 100px;
display: inline-block;
width: 100%;
}
<h1>Box Sizing</h1>
See the spec I linked to for a more detailed explanation along with additional workarounds and rules that prevent the margins from collapsing.

CSS: first-child selector including text nodes

is there any way to select a CSS-element that is the first child of its parent, counting text nodes? I want to remove the top margin of a heading if it is at the top of its parent, but if I use:
#content h1 {
margin-top: 1em;
}
#content h1:first-child {
margin-top: 0;
}
and have some HTML like
<div id="content">
This is some text.
<h1>A heading</h1>
Some more text.
</div>
the margin is still removed. Is there any way in CSS to prevent this?
Remove the margin, not just the margin-top, h1 element is pushing the next element down
#content h1 {
margin-top: 1em;
}
#content h1:first-child {
margin: 0px;
}
Demo Fiddle
If you want to remove all except first
#content h1:not(:first-child) {
margin: 0px;
}
Updated Fiddle
In the example given in the OP, you could (remove the :first-child rule and) add
#content {
margin-top: 1em;
}
This would collapse (combine and overlap) with the h1’s margin if there’s no text before the heading, but if there is the h1 would have a separate top margin. You’d then just have to adjust the bottom padding/margin of whatever is preceding so that your #content is positioned desirably, or perhaps alternatively add a ::before pseudo-element with a negative margin (which will collapse with and cancel out the container’s margin) to do the trick:
#content:before {
display: block;
margin-top: -1rem;
content: ' ';
}
Note that if h1 has a different font-size then 1em will different so you would have to account for that or use a fixed unit such as rem or px.
(This doesn’t help in my case – I want to add a top-margin to a floated img if there’s some text before it in the containing <p> [in WordPress-generated content]. But margins of float-ed elements don’t collapse with their container, and the general answer to the question is “no, there’s no such selector.”)

How can I lay out two <div>s on one line, and have one centre-aligned (relative to the entire line) and the other right-aligned?

I want to display 2 divs in a single line. I have a parent div and two child divs.I want to keep the width of first child div and parent div equal. So the header(label of first child div) displays always middle position of parent div and I want to display the second child div at the right side in the same line of parent div.(Condition is always label of first child div should display middle of parent div). Here is the jsfiddle.
If I were styling this header section for a website, and I wanted some flexibility in styling the various elements, here is out I would start.
For my HTML:
<div class="head">
<div class="innerfirst">
<h1>ABCDEF GHIJ</h1>
</div>
<div class="innersecond">
<label>RIGHT1</label>
<label>RIGHT2</label>
</div>
</div>
I would put the page title in a <h1> tag so that I can adjust font-size, padding, background color and so on. In fact, you could add a tag line below the title line and various background images. Having .innerfirst and h1 gives you quite a bit of flexibility.
The <label> tags don't make sense semantically in this context, but perhaps you will have have input fields later like a search box.
For the CSS:
.head {
background-color:#2191C0;
width: 100%;
height: 85px;
position: relative;
}
The above is fine, set position: relative so that you can use absolute positioning for one of the child elements. The fixed height is a good idea, makes it easier to adjust elements vertically.
.innerfirst {
}
.innerfirst h1 {
text-align: center;
color: #FCFCFC;
padding-top: 10px; /* You could also use a margin... */
}
By default, .innerfirst will have 100% width since it is an in-flow block element, same with the h1 element. You can center the text within h1, and adjust color, padding and margin as needed.
.innersecond {
border: 2px solid lightgray;
color: white;
position: absolute;
width: 25%; /* Set this or by default it will shrink-to-fit content */
height: 61px; /* Set this or by default it will shrink-to-fit content */
top: 5px;
right: 5px;
padding: 5px;
}
What you could do is create a box of text and absolutely position it to the right. It is a good idea
to set a height and width otherwise, as a result of the absolute positioning, the div will shrink to fit the content, which is sometimes useful. The top and right offsets will position the .innersecond to the top-right of the parent container because you set position: relative in .head.
.innersecond label {
display: block; /* optional if you want block behavior */
border: 1px dotted white;
}
Finally, if you want the label tags to behave like blocks, use display: block and style according to you design requirements.
For reference, demo fiddle: http://jsfiddle.net/audetwebdesign/qpb9P/
Here's an updated jsfiddle. Read up on the display property!

Unexpected behavior of css float

Here is my jsFiddle
I just have 3 divs. The 2nd div is floated to the right, and 3rd div appears just below the 2nd.
In the 3rd div, I am setting margin-top property, and this property does not have any effect on the layout.
Question: Can someone explain me understanding this behavior of float?
HTML
<div class="header">
</div>
<div class="sidebar">
</div>
<div class="footer">
</div>
CSS
.header {
width: 100%;
height: 80px;
background-color: #abcdef;
}
.sidebar {
margin-top: 15px;
float: right;
width: 200px;
height: 200px;
background-color: #abcdef;
display: block;
}
.footer {
clear: both;
margin-top: 20px;
width: 100%;
height: 60px;
background-color: #000000;
}
This is not unexpected at all. The .sidebar is removed from regular flow layout by its float property, as such it doesn't take up any space anymore. The .footer has a clear rule, so it is forced underneath any floats, but that automatically puts it 215px (margin+height of the sidebar) behind the last element that is part of the flow layout. As such its margin requirement of 20px is completely satisfied, and it appears at its logical current position. You can verify this by setting the top margin to 220px instead, it will appear 5px (220-215) below the sidebar.
You can easily achieve the effect you desire by putting margin-bottom:20px on the sidebar since it will then be required to keep that distance to the footer, pushing it down.
The issue is related to the clear rule.
W3C - An element that has had clearance applied to it never
collapses its top margin with its parent block's bottom margin.
Baiscally, if you want to use clear, the general rule is to add an element between the two floated divs to ensure you can correctly space them.
The top margin of the footer div is being collapsed, http://www.w3.org/TR/CSS21/box.html#collapsing-margins
If you add margin-bottom to the sidebar instead of the top of the footer it will work.
This is caused by the fact that floated elements aren't really there with respect to margin calculations. Your .footer is below whatever unfloated elements are above it, (with a margin of 20px). This issue is caused because margins with respect to floats are calculated relative to other floats, (not all other elements).
So to get the desired effect add a margin-bottom element to .sidebar, have a meaningless float added to the .footer, or add a
<div style="clear:both"></div>
between the .footer and .sidebar