css negative padding

| 16 Comments

The spec and a million or three blog posts all rclearly state (rather than explain) that in CSS, padding cannot be negative. Browser implementations seem to agree with that so indeed negative padding is not allowed.

My question is "why not?" Why shouldn't I be able to set negative padding. What "doesn't make sense" about being able to, for example, move an element's border in closer to or even overlapping the text it contains?

And given that browsers won't let me do this with something simple like negative padding, how can I simulate text underline with a bottom border that actually intersects text descenders instead of sitting below them?

Or, alternatively, why can't I, or how can I, set text underlines to be a different color or weight from the text itself.

I think I hate the Web.

update: I really don't understand how people can think there's no value in negative padding. Why shouldn't I be able to bring an elements border in far enough to overlap the element's content? Why shouldn't my bottom and top borders be able to cross the ascenders and descenders of the text contained within?

16 Comments

The reason there is no negative padding is because that's what margins are for: padding is for adjustment within the border, and margins are for adjustment outside the border. You can have negative margins if you so desire.

As for the lower border linking, try line-spacing.

Is this some sort of parody?

One simple way to underline text and have it be a different color than the text itself, might be something like this:

.mytext
{
color: orange;
border-bottom: 1px solid red;
}

That doesn't completely solve the problem of course, and I realize your comments were about much more than that one specific issue.

It does seem like negative padding could be useful in certain situations.

u {color: blue; text-decoration: underline;}
u span {color: gray; font-weight: bold;}
bold gray text with blue underlining

Rijk took my answer. The problem is that it requires you to change your markup. The workaround if you want clean source markup is to use js to do the dom rearranging ondomcontentloaded (rather than onload to prevent ugly flash of color). Graceful degradation for the js can be provided by putting the span on the outside rather than the inside and assigning it a class.

You can also (if I'm remembering correctly) get all the border styles and whatnot using the same html structure and negative margins on the outer element while reversing the margin change on the inner element.

One more thing, when I say reverse, the underline has to still be on the outside span and a text-decoration: none on the inner element.

It sounds like you want text-line-decoration, text-line-color, and text-line-style from http://www.w3.org/TR/css3-text/ .

I wonder when digg has a new headline: prominent Mozilla developer hates the web

I wonder when digg has a new headline: prominent Mozilla developer hates the web

Looks like the span hack is the only decent option... unless you don't mind waiting until hell freezes over (and thaws again) for the CSS3 stuff to show up in browsers.
Don't hate the web, hate the bueraucracy holding it down.

The best way I can think to do this is to set your links to "display: inline-block" and then constrain the height of the links to whatever value is necessary (i.e. the text height or similar). Now you can use border-bottom to do whatever you want.

I'd advise against using a different bottom border colour than the link text for usability reasons.

Of course, inline-block is only supported in Gecko from 1.9, but as far as I know everything else already supports it fine and there's no real backwards compatibility issues in this case apart from your underlines looking a little out.

You can "emulate" that effect with a background image that contains the underline.

You can "emulate" that effect with a background image that contains the underline.

Negative padding? The padding is the distance between the border and element. There is no logic in making this negative and it shouldn't be like that. With CSS you can easily create the effect you want. I already shiver when only thinking about the incompatibility that would be created between browsers if we're to hack the padding.

This is easy to work around. Just put the border on an outer element and apply negative margin to the inner.

#outer { border: 1px solid blue; }
#inner { margin: -10px; }

Regarding the update: I don't think there's "no value" in negative padding, but I do believe the value is somewhat limited. How often do you want to have text overflowing its container? Generally, that's a bad thing and should be avoided.

Either way, we're pretty much stuck with CSS as it is, so musings about why we should or shouldn't be able to do things are largely pointless. Even if something like this crawled its way into CSS3, that's probably putting it an optimistic 5 years away in terms of realistic use, if not longer.

For what it's worth, I think we all hate the web, or at least the lunacy that is the CSS specification. Try out my recommendation above, at least it requires no markup changes.

Monthly Archives