By sam


2009-01-28 21:01:50 8 Comments

Why won't vertical-align: middle work? And yet, vertical-align: top does work.

span{
  vertical-align: middle;
}
<div>
  <img src="http://lorempixel.com/30/30/" alt="small img" />
  <span>Doesn't work.</span>
</div>

21 comments

@Jean Paul A.K.A el_vete 2019-11-05 05:21:33

Not sure as to why it doesn't render it on your navigation's browser, but I normally use an snippet like this when trying to display a header with an image and a centered text, hope it helps!

https://output.jsbin.com/jeqorahupo

            <hgroup style="display:block; text-align:center;  vertical-align:middle;  margin:inherit auto; padding:inherit auto; max-height:inherit">

            <header style="background:url('http://lorempixel.com/30/30/') center center no-repeat; background-size:auto; display:inner-block; vertical-align:middle; position:relative; position:absolute; top:inherit; left:inherit; display: -webkit-box; display: -webkit-flex;display: -moz-box;display: -ms-flexbox;display: flex;-webkit-flex-align: center;-ms-flex-align: center;-webkit-align-items: center;align-items: center;">

            <image src="http://lorempixel.com/60/60/" title="Img title" style="opacity:0.35"></img>
                    http://lipsum.org</header>
                    </hgroup>

@Danield 2013-12-24 21:06:14

The technique used in the accepted answer works only for single-lined text (demo), but not multi-line text (demo) - as noted there.

If anyone needs to vertically center multi-lined text to an image, here are a few ways (Methods 1 and 2 inspired by this CSS-Tricks article)

Method #1: CSS tables (FIDDLE) (IE8+ (caniuse))

CSS:

div {
    display: table;
}
span {
    vertical-align: middle;
    display: table-cell;
}

Method #2: Pseudo element on container (FIDDLE) (IE8+)

CSS:

div {
   height: 200px; /* height of image */
}

div:before {
  content: '';
  display: inline-block;
  height: 100%;
  vertical-align: middle;
  margin-right: -0.25em; /* Adjusts for spacing */
}

img {
    position: absolute;
}

span {
  display: inline-block;
  vertical-align: middle;
  margin-left: 200px;  /* width of image */
}

Method #3: Flexbox (FIDDLE) (caniuse)

CSS (The above fiddle contains vendor prefixes):

div {   
    display: flex; 
    align-items: center;    
}
img {
    min-width: 200px; /* width of image */
}

@Thomas 2015-04-09 16:35:04

The methods work fine if the image is bigger (in height) than the text. But if the image is smaller then all but the last one sadly fail

@Michael Haren 2009-01-28 21:10:50

Actually, in this case it's quite simple: apply the vertical align to the image. Since it's all in one line, it's really the image you want aligned, not the text.

<!-- moved "vertical-align:middle" style from span to img -->
<div>
  <img style="vertical-align:middle" src="https://placehold.it/60x60">
  <span style="">Works.</span>
</div>

Tested in FF3.

Now you can use flexbox for this type of layout.

.box {
   display: flex;
   align-items:center;
}
<div class="box">
    <img src="https://placehold.it/60x60">
    <span style="">Works.</span>
</div>

@BrainSlugs83 2011-09-28 02:51:55

"Since it's all in one line, it's really the image you want aligned, not the text." -- No, the image is fine where it's at. We want the text aligned. Not the image. -- I get that this works (in some circumstances, ex: when you're not using "float:left" on the image...), but it's just bizarre and unintuitive that to physically move the text to the vertical middle you would have to apply an attribute to the image next to it instead.

@jamesrom 2011-12-07 00:57:14

@BrainSlug83 It's certainly not bizarre but I can see how newcomers can be tripped up by this. By default an image will be placed on the text baseline. All you are doing is moving where the image is attached relative to the text. As for using float:left, you should be doing that either on the block that contains the image and text, or on the text itself.

@Greg Pettit 2012-01-25 04:26:37

@BrainSlugs83 Agreed that it can be seen as counter-intuitive. It takes a bit of a mental shift, because according to CSS, what you need to do is center the image to the text. Not the text to the image.

@Craig Celeste 2012-09-21 19:10:59

Whether it's intuitive the image is centered to the text or the text to the image depends on their relative size. If the image is smaller (height) than the text, it's becomes clear that the image is center.

@Kenneth Benjamin 2013-08-26 16:33:56

This answer is better: stackoverflow.com/a/489528/949055 as it works when your text wraps lines. The method shown only works if the text never wraps at end of line.

@Mori 2014-03-24 08:06:27

It doesn't work if you increase the span font size. See my answer.

@asimovwasright 2015-09-18 08:33:56

In case anyone has this issue, and reads this far down the comments: This solution will not work for text within any <h*> tags. There is probably css to fix that, but that's over my pay grade.

@Dan 2015-09-18 10:51:41

Mori: Try surrounding the whole lot in a div that sets your font-size - worked for me to adjust the size but keep the alignment.

@Guillem Cucurull 2015-12-03 11:39:47

I encountered the case when the text had two lines, and then it wasn't vertical centered anymore. My solution was to add vertical-align:middle to both the image and the text, and it works now.

@Matthieu Charbonnier 2016-01-08 13:53:36

But if you set image size to a smaller one (like width:16px;height:16px), you can see the image will be too low...

@Anil8753 2017-06-16 17:14:10

Does not work if we have long text and text wrap goes to bottom of the image.

@Bitterblue 2017-09-25 13:49:28

Does not work. I gave that div a visible border and set height to greater than image height and it did not work.

@Leo 2018-07-27 13:48:34

If you already have bootstrap included as a library in your css, the property vertical-aligned: middle; comes as default for all img elements just in case this helps someone.

@Usman Iqbal 2019-02-12 09:37:08

will this work in boostrap 4 chrome ? because right now if i have an image whose height and width are set to 18px, and there is a span right next to it in which a text is simply being displayed. Now IF I GIVE VERTICAL ALIGN MIDDLE TO image i wont work, but if i give vertical align middle to text, the image center aligns with text. wow

@Fabien Snauwaert 2019-04-22 10:19:42

Neither of the two methods works well. If you use multi-line text: the first method will produce an ugly gap between the first line and the second one; with the second method, the size of the image will be reduced, regardless of the dimensions you gave it. See here for a demonstration of the issue.

@Fabien Snauwaert 2019-04-22 11:03:35

Here are the fixes for the multi-line text issue. With the first method (relying on vertical-align), use display: table and display: table-cell. With the second method – preferred – (relying on flex), simply set flex-shrink: 0; on the img. See Codepen here. (Other ways to achieve the same thing on my codepen, but flex feels by far the cleanest and most readable of all.)

@JAY PATEL 2020-01-17 13:31:04

Thanks! your answer is helpful to me.

@Alireza 2017-05-25 12:47:49

Firstly inline CSS is not recommended at all, it really mess up your HTML.

For aligning image and span, you can simply do vertical-align:middle.

.align-middle {
  vertical-align: middle;
}
<div>
  <img class="align-middle" src="https://i.stack.imgur.com/ymxaR.png">
  <span class="align-middle">I'm in the middle of the image! thanks to CSS! hooray!</span>
</div>

@jlyonsmith 2018-03-19 13:22:33

There are many good reasons to use inline CSS. React: CSS in JS for example.

@Adam Lassek 2009-01-28 21:45:03

Here are some simple techniques for vertical-align:

One-line vertical-align:middle

This one is easy: set the line-height of the text element to equal that of the container

<div>
  <img style="width:30px; height:30px;">
  <span style="line-height:30px;">Doesn't work.</span>
</div>

Multiple-lines vertical-align:bottom

Absolutely position an inner div relative to its container

<div style="position:relative;width:30px;height:60px;">
  <div style="position:absolute;bottom:0">This is positioned on the bottom</div>
</div>

Multiple-lines vertical-align:middle

<div style="display:table;width:30px;height:60px;">
  <div style="display:table-cell;height:30px;">This is positioned in the middle</div>
</div>

If you must support ancient versions of IE <= 7

In order to get this to work correctly across the board, you'll have to hack the CSS a bit. Luckily, there is an IE bug that works in our favor. Setting top:50% on the container and top:-50% on the inner div, you can achieve the same result. We can combine the two using another feature IE doesn't support: advanced CSS selectors.

<style type="text/css">
  #container {
    width: 30px;
    height: 60px;
    position: relative;
  }
  #wrapper > #container {
    display: table;
    position: static;
  }
  #container div {
    position: absolute;
    top: 50%;
  }
  #container div div {
    position: relative;
    top: -50%;
  }
  #container > div {
    display: table-cell;
    vertical-align: middle;
    position: static;
  }
</style>

<div id="wrapper">
  <div id="container">
    <div><div><p>Works in everything!</p></div></div>
  </div>
</div>

Variable container height vertical-align:middle

This solution requires a slightly more modern browser than the other solutions, as it makes use of the transform: translateY property. (http://caniuse.com/#feat=transforms2d)

Applying the following 3 lines of CSS to an element will vertically centre it within its parent regardless of the height of the parent element:

position: relative;
top: 50%;
transform: translateY(-50%);

@banncee 2013-04-03 13:51:56

The display:table and display:table-cell CSS selectors work great, except, of course, in IE7 and below. After tearing my hair out for several hours, I decided that I didn't really need to deal with anyone that still used IE7-.

@jahu 2015-04-28 12:20:09

display:table has some limitations in various browsers (in IE11 max-height doesn't work if the element is inside a table cell), so in some edge cases it's not a good idea to align vertically using table cells.

@CodeGems 2017-07-06 02:12:31

It can be confusing, I agree. Try utilizing table features. I use this simple CSS trick to position modals at the center of the webpage. It has large browser support:

<div class="table">
    <div class="cell">
        <img src="..." alt="..." />
        <span>It works now</span>
    </div>
</div>

and CSS part:

.table { display: table; }
.cell { display: table-cell; vertical-align: middle; }

Note that you have to style and adjust the size of image and table container to make it work as you desire. Enjoy.

@Super User 2017-01-30 14:54:55

You can set image as inline element using display property

<div>
  <img style="vertical-align: middle; display: inline;" src="https://placehold.it/60x60">
  <span style="vertical-align: middle; display: inline;">Works.</span>
</div>

@Mr.Pandya 2016-11-08 06:26:18

Write these span properties

span{
    display:inline-block;
    vertical-align:middle;
}

Use display:inline-block; When you use vertical-align property.Those are assosiated properties

@Fleuv 2016-04-10 11:26:02

Haven't seen a solution with margin in any of these answers yet, so here is my solution to this problem.

This solution only works if you know the width of your image.

The HTML

<div>
    <img src="https://placehold.it/80x80">
    <span>This is my very long text what should align. This is my very long text what should align.</span>
</div>

The CSS

div {
  overflow:hidden;
}
img {
   width:80px
   margin-right:20px;
   display:inline-block;
   vertical-align:middle;
}
span {
   width:100%;
   margin-right:-100px;
   padding-right:100px;
   display:inline-block;
   vertical-align:middle;
   box-sizing:border-box;
   -moz-box-sizing:border-box;
   -webkit-box-sizing:border-box;
}

@efirat 2016-09-02 14:10:02

Here is exact solution. It works for multi-line texts, too... Aboves are not proper for multi lines.

@christopheraue 2014-09-11 12:58:35

You have to apply vertical-align: middle to both elements to have it been centered perfectly.

<div>
  <img style="vertical-align:middle" src="http://lorempixel.com/60/60/">
  <span style="vertical-align:middle">Perfectly centered</span>
</div>

The accepted answer does center the icon around half of the x-height of the text next to it (as defined in the CSS specs). Which might be good enough but can look a little bit off, if the text has ascenders or descenders standing out just at top or bottom:

centered icon comparison

On the left, the text is not aligned, on the right it is as shown above. A live demo can be found in this article about vertical-align.

Has anyone talked about why vertical-align: top works in the scenario? The image in the question is probably taller than the text and thus defines the top edge of the line box. vertical-align: top on the span element then just positions it at the top of the line box.

The main difference in behavior between vertical-align: middle and top is that the first moves elements relative to the box's baseline (which is placed wherever needed to fulfill all vertical alignments and thus feels rather unpredictable) and the second relative to the outer bounds of the line box (which is more tangible).

@Curtis 2017-10-23 20:40:03

I noticed top works and bottom works but not middle. Basically the "middle" is not defined as halfway between the top and the bottom. It more means "when it's taller than text, stick out both ways equally." And here you don't need vertical-align:middle on the text at all, just the image.

@Mori 2014-03-24 07:54:59

Change your div into a flex container:

div {display:flex;}


Now there are two methods to center the alignments for all the content:

Method 1:

div {align-items:center;}

DEMO


Method 2:

div * {margin-top:auto; margin-bottom:auto;}

DEMO


Try different width and height values on the img and different font size values on the span and you'll see they always remain in the middle of the container.

@CSS 2015-12-03 01:39:59

In order to center the text next to or between images (horizontally on the page), you need to also add justify-content: center; and for spacing (without using <br/> tags) you might also want to throw in a padding: 1em;. Great update for us modern browser devs.

@semaj0 2016-05-24 13:58:26

This worked well. I tried each and everyone of the other answers, and while they worked to a degree, it didn't work for me. I had about 3 lines of text to align, and this answer worked perfectly. Thanks @Mori

@Benjamin Crouzier 2014-02-24 14:20:27

Multiline solution:

http://jsfiddle.net/zH58L/6/

<div style="display:table;width:30px;height:160px;">
    <img style="display:table-cell;width:30px;height:60px;padding:50px" src='...' />
    <div style="display:table-cell;height:30px;vertical-align:middle">
      Multiline text centered vertically
    </div>
</div>
<!-- note: img (height + 2x padding) must be equal to root div height -->

Works in all browers and ie9+

@den232 2012-10-24 15:22:55

On a button in jQuery mobile, for instance, you can tweak it a bit by applying this style to the image:

.btn-image {
    vertical-align:middle;
    margin:0 0 3px 0;
}

@HTMLnewBie 2012-07-02 14:41:34

This code works in IE as well as FF:

<div>
  <img style="width:auto; height:auto;vertical-align: middle;">
  <span>It does work on all browsers</span>
</div>

@AspiringCanadian 2012-04-13 07:21:30

background:url(../images/red_bullet.jpg) left 3px no-repeat;

I generally use 3px in place of top. By increasing/decreasing that value, the image can be changed to the required height.

@Dan 2015-09-18 12:42:33

Doesn't help in situations where the image size is unknown or dynamic.

@nullpoint81 2012-01-12 14:52:01

Another thing you can do is set the text's line-height to the size of the images within the <div>. Then set the images to vertical-align: middle;

That's seriously the easiest way.

@Ahmad Alfy 2012-11-06 11:31:56

Note that this doesn't work correctly if your content is spread over multiple lines.

@Jean Paul A.K.A el_vete 2019-11-05 05:31:22

and then why not just line-height:100% ?

@Dan 2011-11-29 18:24:13

Basically, you'll have to get down to CSS3.

-moz-box-align: center;
-webkit-box-align: center;

@Ikke 2009-01-28 21:05:08

Because you have to set the line-height to the height of the div for this to work

@sam 2009-01-28 21:08:41

I tried setting line-height to 30px and it still doesn't work.

@Touhid Rahman 2013-05-20 23:50:12

Use line-height:30px for the span so that text is align with the image:

<div>
  <img style="width:30px; height:30px;">
  <span style="line-height:30px;">Doesn't work.</span>
</div>

@David 2011-11-18 13:24:05

For the record, alignment "commands" shouldn't work on a SPAN, because it is an in-line tag, not a block-level tag. Things like alignment, margin, padding, etc won't work on an in-line tag because the point of inline is not to disrupt the text flow.

CSS divides HTML tags up into two groups: in-line and block-level. Search "css block vs inline" and a great article shows up...

http://www.webdesignfromscratch.com/html-css/css-block-and-inline/

(Understanding core CSS principles is a key to it not being quite so annoying)

@Kevin Peno 2012-06-15 17:45:58

text-align and vertical-align (with the exception of its application on td elements for legacy purposes) are specifically meant for inline and inline-block elements (span, img, etc).

@strager 2009-01-28 21:10:00

You probably want this:

<div>
   <img style="width:30px; height:30px;">
   <span style="vertical-align:50%; line-height:30px;">Didn't work.</span>
</div>

As others have suggested, try vertical-align on the image:

<div>
   <img style="width:30px; height:30px; vertical-align:middle;">
   <span>Didn't work.</span>
</div>

CSS isn't annoying. You just don't read the documentation. ;P

@sam 2009-01-28 21:13:14

And if the image height is dynamic? I'm screwed :( PS, just because documentation exists for CSS doesn't make it annoying or unintuitive.

@strager 2009-01-28 21:15:00

Do you mean unannoying and intuitive? You didn't specify if he image's height is dynamic at all in your question, so I assumed the fixed height was what you were going to stick with.

@Michael Haren 2009-01-28 21:16:27

I'm with sam on this one. I assumed that items ought to be centered with whatever the img height turned out to be. I think we could all stand to cool down a bit though.

Related Questions

Sponsored Content

28 Answered Questions

[SOLVED] How to Vertical align elements in a div?

45 Answered Questions

[SOLVED] How to disable text selection highlighting

28 Answered Questions

[SOLVED] How do I give text or an image a transparent background using CSS?

  • 2009-04-30 09:00:02
  • Stijn Sanders
  • 1515435 View
  • 2237 Score
  • 28 Answer
  • Tags:   html css opacity

45 Answered Questions

[SOLVED] How to vertically center a div for all browsers?

35 Answered Questions

[SOLVED] How to vertically align an image inside a div

30 Answered Questions

[SOLVED] How do I vertically align text in a div?

38 Answered Questions

[SOLVED] How to align checkboxes and their labels consistently cross-browsers

25 Answered Questions

[SOLVED] How to align content of a div to the bottom

Sponsored Content