21

What's the best way to align icons (left) and text (right) or the opposite text on left and icon on right?

Does the icon image and text have to be the same size? Ideally I would like them to be different but be on the same vertical alignment.

I am using background-position css property to get the icons from a larger image.

Here is how I do it now, but I am struggling with either getting them to be on the same line or be vertically aligned to the bottom.

Text

This is what I get after I try your suggestions.

Though the text is now aligned with the icon, it is superimposed over the icon to the right of the icon that I want. Please note that i am using the background position to show the icon from a larger set of images.

Basically I am getting

<icon><10px><text_and_unwanted_icon_to_the_right_under_it>
<span class="group3_drops_icon group3_l_icon" style="">50</span>

group3_drops_icon {
background-position:-50px -111px;
}

.group3_l_icon {
-moz-background-clip:border;
-moz-background-inline-policy:continuous;
-moz-background-origin:padding;
background:transparent url(/images/group3.png) no-repeat scroll left center;
height:35px;
overflow:hidden;
padding-left:55px;
}
badnaam
  • 1,876
  • 4
  • 29
  • 53

3 Answers3

38

I usually use background:

<style type="text/css">
.icon {
background-image: url(path/to/my/icon.jpg);
background-position: left center;
background-repeat: no-repeat;

padding-left: 16px; /* Or size of icon + spacing */
}
</style>

<span class="icon">Some text here</span>
rossipedia
  • 56,800
  • 10
  • 90
  • 93
  • +1 This is what I use, with variations. It's the only way to get images to line up with respect to the text baseline in all browsers. – Robusto Jun 23 '10 at 23:43
  • If you're tiling your background icons, and text is going to be to the right, then you should tile your icons vertically, not horizontally. – rossipedia Jun 24 '10 at 15:31
  • thank you, finally this with `display:inline-block;height: 25px;` from [here](http://stackoverflow.com/questions/2343989/how-to-set-height-property-for-span) helped me , – Shaiju T Mar 17 '15 at 16:58
27

You can do it on the same line using vertical-align and line-height

<p style='line-height: 30px'>
  <img src='icon.gif' style='vertical-align: middle' />Icon Text
</p>

Alternatively, you can go the background approach with no-repeat and positioning:

span.icontext {
  background: transparent url(icon.gif) no-repeat inherit left center;
  padding-left: 10px /* at least the width of the icon */
}

<span class="icontext">
  Icon Text
</span>
Jamie Wong
  • 18,104
  • 8
  • 63
  • 81
14

Sadly, neither of these answers are bullet proof and each have one big flaw.

@rossipedia I used to implement all my icons this way and it works quite well. But, and this is a big but, it does not work with sprites, since you're using the background-position property to position the icon inside the container that includes your text. And not using sprites where you can is bad for performance and SEO, making them imperative for any good modern website.

@Jamie Wong The first solution has two markup flaws. Using elements semantically correctly is sadly underrated by some, but you'll see the benefits in prioritizing form in your search engine ranking. So first of all, you shouldn't use a p-tag when the content is not a paragraph. Use span instead. Secondly, the img-tag is meant for content only. In very specific cases, you might have to ignore this rule, but this isn't one of them.

My Solution: I won't lie to you, I've checked in a lot of places in my time and IMHO there is no optimal solution. These two solutions are the ones that come closest to that, though:

Inline-Block Solution

HTML:
<div class="container">
  <div class="icon"></div>
  <span class="content">Hello</span>
</div>

CSS:
.container {
   margin-top: 50px;
}

.container .icon {
    height: 30px;
    width: 30px;
    background: #000;
    display: inline-block;
    vertical-align: middle;
}
.container .content {
    display: inline-block;
    vertical-align: middle;
}

"display:inline-block;" is a beautiful thing. You can do so much with it and it plays very nicely with responsive design. But it depends on your client. Inline-Block does not work well with IE6, IE7 and still causes problems with IE8. I personally no longer support IE6 and 7, but IE8 is still out there. If your client really needs his website to be usable in IE8, inline-block is sadly no option. Assess this first. Replace the black background of the icon-element with your sprite, position it, throw no-repeat in there and voilà, there you have it. Oh yeah, and as a plus, you can align the text any way you want with vertical-align.

P.S.: I am aware that there's an empty HTML-tag in there, if anyone has a suggestion as to how to fill it, I'd be thankful.

Fixed Height Solution

.clearfix:after {
    content: ".";
    display: block;
    clear: both;
    visibility: hidden;
    line-height: 0;
    height: 0;
}

.clearfix {
    display: inline-block;
}

html[xmlns] .clearfix {
    display: block;
}

* html .clearfix {
    height: 1%;
}
.container {
    margin-top: 50px;
    border: 1px solid #000;
}

.container .icon {
    height: 30px;
    width: 30px;
    background: #000;
    float:left;
}
.container .content {
    line-height: 30px;
    float: left;
    display: block;
}

I hate this one. It uses a fixed line height for the text, and if you choose the same height as the Icon's box, the text is centered to that height. To align the text to the top, cut the line height, and as to the bottom, you'll have to fix that with position: absolute and a fixed width and height for the container. I'm not going to get into that unless someone requests it, because it's a whole issue for itself, and brings with it a lot of disadvantages. The main disadvantage of this path is the fixed height. Fixed heights are always unflexible and especially with text, it can cause a bunch of problems (You can no longer scale the text as a user without it being cut off, plus different browsers render text differently). So be sure that in no browser the text is cut off and that it has some wiggle room inside its line height. P.S.: Don't forget the clearfix for the container. And, of course, replace the black background with your sprite and according position + no-repeat.

Conclusion

Use inline-block if at all possible. ;) If it's not, breath deeply and try the second solution.

Merritt6616
  • 187
  • 1
  • 4
  • 2
    'And not using sprites where you can is bad for performance and SEO, making them imperative for any good modern website.' The above solutions are the perfect example of a situation where you may need to break away from sprites (for just a few images). To say it is going to hurt SEO is a stretch. – JeremyE Mar 12 '15 at 04:25
  • Very true! By now I use Icon Fonts almost exclusively, unless of course I have to use multicolored Icons. Also, there's a hack for inline-block, so this isn't the issue I thought it was. – Merritt6616 Feb 18 '16 at 17:53