2279

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

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

isherwood
61.4k16 gold badges122 silver badges173 bronze badges
asked Jan 28, 2009 at 21:01
0

26 Answers 26

2631

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://https://placeholdmon.vercel.app/60x60" alt="A grey image showing text 60 x 60">
 <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://https://placeholdmon.vercel.app/60x60">
 <span style="">Works.</span>
</div>
Thomas Gratier
2,3811 gold badge14 silver badges17 bronze badges
answered Jan 28, 2009 at 21:10
Sign up to request clarification or add additional context in comments.

3 Comments

The flex solution is better than the vertical-align solution because it handles the case of multiple lines of text also.
The vertical-align: middle approach works well only if you have one line of text and you apply vertical-align: middle to both elements.
It doesn't work perfectly, I had to add margin-top:-6px; on image to make it work.
362

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%);
Scoots
3,1242 gold badges25 silver badges35 bronze badges
answered Jan 28, 2009 at 21:45

1 Comment

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-.
110

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: auto 0; }

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.

answered Mar 24, 2014 at 7:54

2 Comments

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.
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
106

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).

answered Sep 11, 2014 at 12:58

Comments

64

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))

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

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

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)

The above fiddle contains vendor prefixes:

div { 
 display: flex; 
 align-items: center; 
}
img {
 min-width: 200px; /* width of image */
}
Samuel RIGAUD
1,6981 gold badge19 silver badges28 bronze badges
answered Dec 24, 2013 at 21:06

1 Comment

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
32

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>
Josh Crozier
242k56 gold badges401 silver badges316 bronze badges
answered Jul 2, 2012 at 14:41

Comments

22

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

Josh Crozier
242k56 gold badges401 silver badges316 bronze badges
answered Jan 28, 2009 at 21:05

1 Comment

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

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)

answered Nov 18, 2011 at 13:24

1 Comment

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).
13

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

-moz-box-align: center;
-webkit-box-align: center;
Josh Crozier
242k56 gold badges401 silver badges316 bronze badges
answered Nov 29, 2011 at 18:24

Comments

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>
answered May 20, 2013 at 23:50

Comments

11

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.

Josh Crozier
242k56 gold badges401 silver badges316 bronze badges
answered Jan 12, 2012 at 14:52

2 Comments

Note that this doesn't work correctly if your content is spread over multiple lines.
and then why not just line-height:100% ?
10

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;
}
answered Apr 10, 2016 at 11:26

1 Comment

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

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

Nikhil Patil
3,7099 gold badges34 silver badges44 bronze badges
answered Nov 8, 2016 at 6:26

Comments

6
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.

Josh Crozier
242k56 gold badges401 silver badges316 bronze badges
answered Apr 13, 2012 at 7:21

1 Comment

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

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>

answered Jan 30, 2017 at 14:54

Comments

4

Using flex property in css.

To align text vertically center by using in flex using align-items:center; if you want to align text horizontally center by using in flex using justify-content:center;.

div{
 display: flex;
 align-items: center;
}
<div>
 <img src="http://lorempixel.com/30/30/" alt="small img" />
 <span>It works.</span>
</div>

Using table-cell in css.

div{
 display: table;
}
div *{
 display: table-cell;
 vertical-align: middle;
}
<div>
 <img src="http://lorempixel.com/30/30/" alt="small img" />
 <span>It works.</span>
</div>

corn on the cob
2,3403 gold badges24 silver badges36 bronze badges
answered Sep 19, 2020 at 10:44

Comments

3

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;
}
Josh Crozier
242k56 gold badges401 silver badges316 bronze badges
answered Oct 24, 2012 at 15:22

Comments

3

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+

answered Feb 24, 2014 at 14:20

Comments

2

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.

answered Jul 6, 2017 at 2:12

Comments

2

Display flex with align-items: center; is the best way for vertically align the items

div {
 display: flex;
 align-items: center;
}
<div>
 <img src="https://via.placeholder.com/30" alt="small img" />
 <span>it works.</span>
</div>

isherwood
61.4k16 gold badges122 silver badges173 bronze badges
answered Oct 10, 2021 at 16:26

Comments

2

div {
 display: flex;
 align-items: center;
}
<div>
 <img src="http://lorempixel.com/30/30/" alt="small img" />
 <span>It works.</span>
</div>

isherwood
61.4k16 gold badges122 silver badges173 bronze badges
answered Aug 16, 2021 at 6:44

Comments

0

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.sstatic.net/ymxaR.png">
 <span class="align-middle">I'm in the middle of the image! thanks to CSS! hooray!</span>
</div>

answered May 25, 2017 at 12:47

1 Comment

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

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>
answered Nov 5, 2019 at 5:21

Comments

0

In 2022 and with nearly 96% unprefixed browser support, I'm surprised no one has suggested the use of a grid layout.

In this JSFiddle, 3 lines are all that are necessary to achieve the OP's objective (but multiple alignments are presented for comparison):

div {
 display: grid;
 grid-template-columns: min-content max-content;
 align-items: center
}

An additional UI nicety would include the optional use of the gap property, which enables modulation of the space between each grid-item within the parent grid container (div).

Advantages of grid layout

  1. Easy vertical AND horizontal alignment of grid-items
  2. Modulation of space between grid-items
  3. Any size image (using min-content) and text length (one line using max-content or wrapped (not shown in fiddle) using min-content) would work - no need to hard-code the image dimensions in the CSS (both usages demonstrated in the demonstrated in JSFiddle)
  4. Modern approach

Disadvantages of grid layout

  1. Older browser support is more challenging
  2. Grid layouts generally require more experienced developers to implement properly - not as simple as block/inline-block display
answered Feb 28, 2022 at 3:18

Comments

-1
<!DOCTYPE html>
<html>
<head>
<style>
 .block-system-branding-block {
 flex: 0 1 40%;
}
@media screen and (min-width: 48em) {
.block-system-branding-block {
flex: 0 1 420px;
margin: 2.5rem 0;
text-align: left;
}
}
.flex-containerrow {
display: flex;
}
.flex-containerrow > div {
 justify-content: center;
align-items: center;
 }
 .flex-containercolumn {
display: flex;
flex-direction: column;
}
.flex-containercolumn > div {
 width: 300px;
 margin: 10px;
 text-align: left;
 line-height: 20px;
 font-size: 16px;
}
.flex-containercolumn > site-slogan {font-size: 12px;}
.flex-containercolumn > div > span{ font-size: 12px;}
</style>
</head>
<body>
<div id="block-umami-branding" class="block-system block- 
system-branding-block">
 <div class="flex-containerrow">
 <div>
 <a href="/" rel="home" class="site-logo">
 <img src="https://placehold.it/120x120" alt="Home">
</a>
</div><div class="flex-containerrow"><div class="flex-containercolumn">
 <div class="site-name ">
 <a href="/" title="Home" rel="home">This is my sitename</a>
 </div>
 <div class="site-slogan "><span>Department of Test | Ministry of Test | 
 TGoII</span></div>
 </div></div>
</div>
 </div>
</body>
</html>
answered Jun 6, 2020 at 18:45

Comments

-4

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

answered Jan 28, 2009 at 21:10

2 Comments

And if the image height is dynamic? I'm screwed :( PS, just because documentation exists for CSS doesn't make it annoying or unintuitive.
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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.