CSS: first-child selector including text nodes - html

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.”)

Related

Top margin of an element (CSS)

I need to set a margin to the top of an element. The text must be within the element and have a top margin of N pixels.
Here is what I want to achieve:
Fiddle: http://jsfiddle.net/GRQNh/
CSS:
body {
height: 960px;
}
.breadcrumbs {
position: relative;
background-color: #eee;
height: 10%;
}
.name {
color: #000;
margin-top: 50px;
}
Thanks.
DEMO or you may be try with padding-top instead margin-top as follows
.name {
display:block;
color: #000;
padding-top: 50px;
}
Since .breadcrumbs has position: relative, set position: absolute; to .name.
JSFiddle
You need to add display: inline-block; to get the margin to work.
For instance,
.name {
color: #000;
margin-top: 50px;
display: inline-block;
}
Hope this helps.
For it to work you will need to make the element behave like a block element. A block element can have, for instance, margins or paddings.
However, you will want to keep it from being displayed like an actual block element, so you will want to keep its visual displacement the same (that is, inline).
Luckily, there is a css value for display which does exactly what you need:
display: inline-block;
Add this to the span (which is inilne by default) and it will behave like a block element while it will still look like an inline element.
You can also give up on margins at all and use padding-top: 50px.
in this case, you must specify the parent ELEMENT position relative and absolute position subsidiary and specify top: 0;
the <span> is an inline element. That means you cant apply margin or padding to it.
For the solution to your problem you have -at least- two options.
1.Change the container of your text to a block element, like <div>
so:
<span class="name">Name</span>
will become
<div class="name">Name</div>
2.Change the behavior of your span by making it a block or inline-block element with this css:
.name {
display:inline-block
/* rest of your css */
These two articles will give you a good idea of what is inline and block
http://www.impressivewebs.com/difference-block-inline-css/
http://css-tricks.com/almanac/properties/d/display/

margin on h1 element inside a div

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;
}

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

Margin on inline-block element

HTML:
hello there! <div class='badge'>give this a small margin.</div> Please!​
CSS:
.badge {
display: inline-block;
margin-top: -2px;
}
See fiddle here: http://jsfiddle.net/ThySQ/2/
How to give the text in the div a margin? It doesn't seem to work like this.
Adding a negative margin to inline content won't work (at least on most browsers). If you want to move the text upwards you can position the element relatively and set the top to a negative number.
.badge {
display: inline-block;
top: -2px;
position: relative;
}
http://jsfiddle.net/ThySQ/4/
You need to apply padding to the div to have the extra space applied within the div.
.badge {
display: inline-block;
margin-top: -2px;
padding: 4px; /* sets up a 4px margin all around the inside edge of the div */
}
That will affect whatever content is within the div.