0

Users can enter descriptions which may include paragraphs or lists. Or they may just enter text without any enclosing <p> or <ul> elements. What I need to do is remove most of the padding and margin above the first element and below the last element so that the user entered content has a nice tight border around it. So I could do one of the following:

  • Use a css rule I was unaware of to target only the first and last elements
  • Use css3 or html5 (I assume there's something within these to easily do what I want) and hope everyone upgrades their browsers asap while the older browsers just get a slightly uglier version of the page
  • Find the first and last elements with Javascript and modify accordingly
  • Modify the html to add a class like <p class="first">

Ideally the 1st solution exists, does it? I'm ok with the 2nd solution though if not, does it exist? The last 2 I don't care for...

UPDATE: don't care about IE6. But I do need to deal with the situation that if there's just text to begin with, without any <p> or <ul> or other elements, then actually nothing special needs to be done for the top margin/padding.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
at.
  • 50,922
  • 104
  • 292
  • 461

4 Answers4

8

Use :first-child and :last-child like this. Note that > and :first-child (CSS2) doesn't work in IE6 and below, and :last-child (CSS3) doesn't work in IE8 and below. The only real workaround to both is to use a .first and .last class respectively (you can add them dynamically with JavaScript as Phrogz says).

.description > p, .description > ul {
    margin: 1.5em 0;
}

.description > :first-child {
    margin-top: 0;
}

.description > :last-child {
    margin-bottom: 0;
}

I added the > combinator to prevent elements like strong or li getting selected. What does it mean?

Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • 1
    Note, though, that you could use JS to attach a `.last-child` class procedurally for those browsers that don't support the CSS selector. – Phrogz Jan 10 '11 at 19:00
  • if :first-child works in IE7 and above, that's good enough for me. I could just make all allowed elements have little bottom padding/margin and make the first element have the same padding/margin. – at. Jan 10 '11 at 19:49
  • if there was text at the beginning of the content, your code above would make it so the first paragraph or unordered list AFTER the initial text would bunch up against that initial text, right? Any way to not have that happen? – at. Jan 10 '11 at 19:54
  • @at: You would have to find a way to wrap the stray text in its own `

    `.

    – BoltClock Jan 11 '11 at 02:41
0

Something like this?

.container * + p, .container * + ul
{
  margin: 1em 0 0;
}

.container p, .container ul
{
  margin: 0;
}
zzzzBov
  • 174,988
  • 54
  • 320
  • 367
0

BoltClock's answer works great in most cases, but IE8 and earlier ignores the :...-child pseudo-selectors.

You can use jQuery to accomplish the same thing, while targetting more browsers.

//On ready...
$(function(){
  //Update styles dynamically
  $('ul:last').css({'margin-bottom':0,'padding-bottom':0});
  $('ul:first').css({'margin-top':0,'padding-top':0});
});
Matt van Andel
  • 636
  • 7
  • 13
0

Have you considered wrapping the content in a container with a negative margin? It requires the content to at least be wrapped in a single p element (not hard to test/add melodramatically).

CSS:

.container {border:1px solid black;}
.container .subcontainer {margin:-1em 0;}
.container p {margin:1em 0;}

HTML:

<div class="container"><div class="subcontainer">
    <p>My first paragraph.</p>
    <p>My second paragraph.</p>
</div></div>
Rudu
  • 15,682
  • 4
  • 47
  • 63
  • I did consider this and was going to list it as a last option... the problem is it gets tricky because I don't know what kind of html the user is going to add. I like things that are not tricky... – at. Jan 10 '11 at 19:36
  • Unfortunately, because some (unfortunately popular) browsers don't support the CSS route, none of these are particularly simple solutions. You mentioned `P` or `UL` so I thought input was restricted to those two, if this isn't the case, I hope you're filtering at some tags (` – Rudu Jan 10 '11 at 20:06