Grow your CSS skills. Land your dream job.

Fix Padded Image Links with Negative Margins

Published by Chris Coyier

This is a pretty basic trick that will be obvious to many of you. But for whatever reason, the solution to it always kind of eluded me so I'm sharing it here. I like padded links. Where you give links in body content a little padding, background, and rounded corners.

a {
  padding: 2px 6px;
  background: #eee;
  -moz-border-radius: 4px;
  -webkit-border-radius: 4px;
}

A "padded" link

The problem is that when you make images into links, this padding shows up in ungainly ways.

Wrong Ways to Fix

How I used to fix it was to use a sledgehammer instead of a chisel. That is, I wrote some jQuery to remove the padding for those images.

$("a:has('img')").css(padding, 0);

I did that because jquery has the .has() function which is able to see if an elements contains another element, which CSS lacks. It might be cool if we could do this in CSS...

a:contains img { padding: 0; }

... but we can't. Another way would be to add a class to all links that contain images like class="imageLink". I have no particular problem with the semantics of that, but it's not as future-friendly as I might like. Perhaps a future design of the site doesn't use padded links and now all those old links have an unneeded class name.

The Easy Way

As it turns out, the easy way to handle this is apply some negative horizontal margins to the image inside.

a img { margin: 0 -6px; }

That will yank the extra padding away from the outside and leave you with a clean nubby-free image.

View Demo

Note that in the demo I used a class to fix the problem, the very thing I told you not to do above. This was just for demo purposes since I wanted a problem image and a fixed image on the same page.

Comments

  1. Permalink to comment#

    Hey Chris,

    I was thinking about padded links the other day. I was trying to use on on a site, but ran into a problem when the linked phrase line wraps.

    Let’s say I have a five word sentence that starts at the end of one line bounces down to the next line. With padded links, the padding is applied on the first line effectively, but when the line wraps, the word now shows up DIRECTLY next to the background color of the padded link, with no padding applied.

    How do you fix this? It’s been driving me crazy :)

    • Permalink to comment#

      That’s how it works here isn’t it?

    • I know what you mean and yes, that’s annoying and not ideal. Since you don’t know where a line is going to break, I can’t think of any immediate solutions. Although I wonder if using a little word-spacing might help?

    • Permalink to comment#

      This has been bothering me too. The best *I’ve* come up with is to use   for the spaces within the links, so if the entire link doesn’t fit on the line, it jumps down to the next line. Which, of course, leaves you with a really ungainly line length above it, but it looks better than a weirdly styled split link.

      I’m not sure, though, it there’s any semantic issue with using a non-breaking space for this purpose. Is that bad form?

    • That’s another way to go… Probably cleaner though to go with white-space: nowrap; on the links. With David’s example of a five-word sentence though, that might make for even weirder line breaks.

    • Toni L
      Permalink to comment#

      Mega easy solution wuold be to keep a rule of thumb that a link inside paragraph text shouldn’t be more then two words – solves most of the issues with padded links.

  2. Permalink to comment#

    “Nubbies” is a word that doesn’t get used nearly often enough. Nice tip, too!

  3. Colin
    Permalink to comment#

    Does this validate?

    At some point I got it into my head that negative anything was bad and should just be avoided, not sure why.

  4. Why can’t we use a img {padding: 0} ?

    I remember I once used a thick bottom border for my links and to avoid images to have it I made something like that.

  5. Permalink to comment#

    Negative padding does validate. But negative margins do not. nagatives should be used with caution. As can cause side effects with other parts of your site but I think using them the way Chris has in the tutorial is fine and quite a good tip.

    I usually just create a span class for text links with padding, hasn’t failed me yet.

  6. Permalink to comment#

    I am going to reshape my site, doing lots of testing with different browsers and (funny!) on IE7 the negative margin problem does not shows up. Normally it’s the reverse…:-). I suppose that nevertheless is a bug in IE.

    Anyway your tecnique goes ok also in IE7.

  7. Daniel
    Permalink to comment#

    this is css-tricks at its best! ;) i really like these small tips, thank you Chris

    another problem with image links i used to have is when you apply a border-bottom to them. The images do also get underlined but one can fix that using img { vertical-align: middle } as in your example on the demo

  8. Colin
    Permalink to comment#

    Also why would it be bad to use jQuery to fix this? Performance degradation?

    • Dustin
      Permalink to comment#

      Why do something with Javascript (and the overhead of traversing the entire document DOM) when it can easily be done with a CSS statement. :)

  9. Dustin
    Permalink to comment#

    This is yet another case where we really need a parent element selector to complement the child selector.

    ie; instead of:

    a > img { ... }

    Which of course selects any IMG element that is a child of an A element. We need:

    a < img { padding: 0; }

    I have found many occasions where it would be handy to have the ability to access the parent element as above, it would infact be perfect for this instance without the need for negative margins. ;)

  10. Felipe Arima
    Permalink to comment#

    Thanks for this “trick” Chris!

    I was really suffering from this padded image when working with padded links.
    This is the solution I was just looking for!

    Keep up the good work! Really appreciate it!

    Cheers

  11. What I dig about negative margins (and was slightly surprised at) is that they validate entirely.

    I will admit, I’ve had some hesitation using them because it felt like I was doing something wrong and it was a “duck-tape fix” in some cases…in this example, it’s not. But I will admit I’ve used it to drag a margin in between my header and containers on IE when I probably had some other invalid code causing the issue….or perhaps it was just IE. ;)

  12. Gavin
    Permalink to comment#

    Interesting tip. I’ve had to troubleshoot this problem as I’ve not used links like this before in my body text.

    One thing I’m not sure on though is in what context does this happen.

    Is it when an article has a feature image? Normally floated to the right or left? Or would it be as an inline image between righting? Or both?

    The reason I ask this is because in some crazy theory part of my brain II think there must be a way to apply a float to the image therefore taking it out of the flow anchor tag (which means with some hokery pokery you could hide the anchor tag) but not the paragraph text.

    Is there such a CSS probably that will allow a parent element to tame a floated element when in between text?

  13. Permalink to comment#

    xD
    Simple but useful =)

  14. Helen P
    Permalink to comment#

    Chris thanks for a great site I check it most days to keep on learning.
    When I look at the demo in IE7 I see grey padding to the top and right of the image. The non fixed one has grey all round it.

  15. Permalink to comment#

    So you dd read my comment on your other blog after all :)

  16. frank
    Permalink to comment#

    Hi, no work in Internet explorer 7 xp , i see the color grey in the left of the images, solution?

  17. Permalink to comment#

    Negative margin for image in a hyperlink tag. Clever.

  18. frank
    Permalink to comment#

    It’s correct this css code for this, see ok en ie and firefox:

    p.cccp a {
    color: blue;
    text-decoration: none;
    padding: 2px 6px;
    background: #eee;
    -moz-border-radius: 4px;
    -webkit-border-radius: 4px;
    }
    p.cccp a:hover {
    text-decoration: none;
    color: #FFFFFF;
    padding: 2px 6px;
    background: #CC0000;
    -moz-border-radius: 4px;
    -webkit-border-radius: 4px;
    }

    Es correcto este código para hacer lo mismo, pero sólo en los enlaces que esten en un párrafo con el estilo cccp?
    p.cccp a {
    color: blue;
    text-decoration: none;
    padding: 2px 6px;
    background: #eee;
    -moz-border-radius: 4px;
    -webkit-border-radius: 4px;
    }
    p.cccp a:hover {
    text-decoration: none;
    color: #FFFFFF;
    padding: 2px 6px;
    background: #CC0000;
    -moz-border-radius: 4px;
    -webkit-border-radius: 4px;
    }

  19. I really like this new CSS 3. And with the fallback for old browsers it’s grate for usability.
    You will see the Porblem of the negative margin in IE6. IE6 does not do what you expact the Browser to do.

  20. Sam Miller
    Permalink to comment#

    I like the rounded corners around the in-text links. How you could get the curves to show in IE without using images? Jquery?

    Sam Miller

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".