8

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?

BlackWolf
  • 5,239
  • 5
  • 33
  • 60
  • 5
    You can't select text nodes with CSS. You'd need to change your markup. http://stackoverflow.com/a/5688758/1612146 – George Mar 04 '14 at 18:13
  • alright, thanks. The markup is created by the showdown markdown parser, but I will take a look at it, thanks :-) I thought if there was any way in using `:before:empty` or something like that, but I think CSS can't do that. – BlackWolf Mar 04 '14 at 23:38

2 Answers2

1

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

  • the problem is that actually, I WANT the margin for the first heading of your example, because there is a text node before it. – BlackWolf Mar 04 '14 at 23:39
  • @BlackWolf i have updated the answer, now it removes the margin except from first heading – Vinay Pratap Singh Bhadauria Mar 05 '14 at 04:11
  • 1
    Thanks for the effort... its a good trick, unfortunately still not what I need, since I would need the margin to be removed from the first child if it appears before any text. So in [this fiddle](http://jsfiddle.net/nmgB7/) the margin of the first heading should be 0. I think oGeez was right in saying CSS cannot do this, but thanks anyway. – BlackWolf Mar 05 '14 at 08:16
0

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

Jake
  • 948
  • 8
  • 19