By Arnaud Le Blanc


2011-09-01 16:25:51 8 Comments

How can you align an image inside of a containing div?

Example

In my example, I need to vertically center the <img> in the <div> with class ="frame":

<div class="frame" style="height: 25px;">
    <img src="http://jsfiddle.net/img/logo.png" />
</div>

.frame's height is fixed and image's height is unknown. I can add new elements in .frame if that's the only solution. I'm trying to do this on Internet Explorer 7 and later, WebKit, Gecko.

See the jsfiddle here.

.frame {
    height: 25px;      /* Equals maximum image height */
    line-height: 25px;
    width: 160px;
    border: 1px solid red;

    text-align: center;
    margin: 1em 0;
}
img {
    background: #3A6F9A;
    vertical-align: middle;
    max-height: 25px;
    max-width: 160px;
}
<div class=frame>
   <img src="http://jsfiddle.net/img/logo.png" height=250 />
</div>
<div class=frame>
   <img src="http://jsfiddle.net/img/logo.png" height=25 />
</div>
<div class=frame>
   <img src="http://jsfiddle.net/img/logo.png" height=23 />
</div>
<div class=frame>
   <img src="http://jsfiddle.net/img/logo.png" height=21 />
</div>
<div class=frame>
   <img src="http://jsfiddle.net/img/logo.png" height=19 />
</div>
<div class=frame>
    <img src="http://jsfiddle.net/img/logo.png" height=17 />
</div>
<div class=frame>
    <img src="http://jsfiddle.net/img/logo.png" height=15 />
 </div>
<div class=frame>
    <img src="http://jsfiddle.net/img/logo.png" height=13 />
 </div>
<div class=frame>
    <img src="http://jsfiddle.net/img/logo.png" height=11 />
 </div>
<div class=frame>
    <img src="http://jsfiddle.net/img/logo.png" height=9 />
 </div>
<div class=frame>
    <img src="http://jsfiddle.net/img/logo.png" height=7 />
 </div>
<div class=frame>
    <img src="http://jsfiddle.net/img/logo.png" height=5 />
 </div>
<div class=frame>
    <img src="http://jsfiddle.net/img/logo.png" height=3 />
 </div>

30 comments

@fdrv 2019-08-25 13:17:13

Imagine you have

<div class="wrap">
    <img src="#">
</div>

And css:

.wrap {
    display: flex;
}
.wrap img {
    object-fit: contain;
}

@Chris 2014-04-10 18:44:44

Just for the sake of this being a valid answer I still want to post the jQuery solution again. This works for every element that has the v_align class applied to it. It will be vertical centered in the parent and on resizing of the window it will be recalculated.

Link to the JSFiddle

$(document).ready(function() {
  // Define the class that vertically aligns stuff
  var objects = '.v_align';
  // initial setup
  verticalAlign(objects);

  // Register resize event listener
  $(window).resize(function() {
    verticalAlign(objects);
  });
});

function verticalAlign(selector) {
  $(selector).each(function(val) {
    var parent_height = $(this).parent().height();
    var dif = parent_height - $(this).height()
    // Should only work if the parent is larger than the element
    var margin_top = dif > 0 ? dif/2 : 0;
    $(this).css("margin-top", margin_top + "px");
  });
}

@Prabakaran Raja 2014-09-29 12:10:49

Great! some times we depend on code instead of CSS!

@Samuel Ramzan 2019-02-22 21:21:55

I was looking for a similar answer and some of the suggestions snapped the image to the left or the vertical ratio squashed the image, so I came up with this solution... It centers the content vertically and horizontally.

 .div{
    position: relative;
    overflow: hidden;
 }
 .bantop img {
    position: absolute;
    margin: auto;
    width: 103%;
    height: auto;
    top: -50%;
    bottom: -50%;
    left: -50%;
    right: -50%;
  }

I use it on several projects and it works like a charm.

@Masoume Karvar 2018-09-19 12:52:17

You can use this:

 .loaderimage {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 60px;
    height: 60px;
    margin-top: -30px; /* 50% of the height */
    margin-left: -30px;
 }

@tourniquet 2018-08-24 13:09:43

Also, you can use Flexbox to achieve the correct result:

.parent {
  align-items: center; /* For vertical align */
  background: red;
  display: flex;
  height: 250px;
  /* justify-content: center; <- for horizontal align */
  width: 250px;
}
<div class="parent">
  <img class="child" src="https://cdn2.iconfinder.com/data/icons/social-icons-circular-black/512/stackoverflow-128.png" />
</div>

@sandeep kumar 2017-10-10 10:06:14

This code work well for me.

<style>
    .listing_container{width:300px; height:300px;font: 0/0 a;}
    .listing_container:before { content: ' ';display: inline-block;vertical-align: bottom;height: 100%;}
    .listing_container img{ display: inline-block; vertical-align: middle;font: 16px/1 Arial sans-serif; max-height:100%; max-width:100%;}
<style>

<div class="listing_container">
    <img src="http://www.advancewebsites.com/img/theme1/logo.png">
</div>

@juliangonzalez 2017-08-31 01:36:16

For centering an image inside a container (it could be a logo) besides some text like this:

Enter image description here

Basically you wrap the image

.outer-frame {
  border: 1px solid red;
  min-height: 200px;
  text-align: center; /* Only to align horizontally */
}

.wrapper{
  line-height: 200px;
  border: 2px dashed blue;
  border-radius: 20px;
  margin: 50px
}

img {
  /* height: auto; */
  vertical-align: middle;   /* Only to align vertically */
}
<div class="outer-frame">
  <div class="wrapper">
    some text
    <img src="http://via.placeholder.com/150x150">
  </div>
</div>

@mariusfv 2017-06-08 07:01:33

Want to align an image which have after a text / title and both are inside a div?

See on JSfiddle or Run Code Snippet.

Just be sure to have an ID or a class at all your elements (div, img, title, etc.).

For me works this solution on all browsers (for mobile devices you must to adapt your code with: @media).

h2.h2red {
    color: red;
    font-size: 14px;
}
.mydivclass {
    margin-top: 30px;
    display: block;
}
img.mydesiredclass {
    margin-right: 10px;
    display: block;
    float: left; /* If you want to allign the text with an image on the same row */
    width: 100px;
    heght: 100px;
    margin-top: -40px /* Change this value to adapt to your page */;
}
<div class="mydivclass">
    <br />
    <img class="mydesiredclass" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b3/Wikipedia-logo-v2-en.svg/2000px-Wikipedia-logo-v2-en.svg.png">
    <h2 class="h2red">Text aligned after image inside a div by negative manipulate the img position</h2>
</div>

@th3pirat3 2017-06-02 01:17:32

Use this one:

position: absolute;
top: calc(50% - 0.5em);
left: calc(50% - 0.5em);
line-height: 1em;

And you can vary font-size.

@Sam 2017-04-09 15:16:01

Solution using a table and table cells

Sometimes it should be solved by displaying as table/table-cell. For example, a fast title screen. It is a recommended way by W3 also. I recommend you check this link called Centering a block or image from W3C.org.

The tips used here are:

  • Absolute positioning container displayed as table
  • Vertical aligned to center content displayed as table-cell

.container {
    position: absolute;
    display: table;
    width: 100%;
    height: 100%;
}
.content {
    display: table-cell;
    vertical-align: middle;
}
<div class="container">
  <div class="content">
    <h1 style="text-align:center">Peace in the world</h1>
 </div>
</div>

Personally I actually disagree about use helpers for this purpose.

@Santosh Khalse 2016-12-15 11:17:57

You can try the below code:

.frame{
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
}
<div class="frame" style="height: 25px;">
    <img src="http://jsfiddle.net/img/logo.png" />
</div>

@Ricardo Zea 2015-12-29 20:13:27

For a more modern solution, and if there is no need to support legacy browsers, you can do this:

.frame {
    display: flex;
    /**
    Uncomment 'justify-content' below to center horizontally.
    ✪ Read below for a better way to center vertically and horizontally.
    **/

    /* justify-content: center; */
    align-items: center;
}

img {
    height: auto;

    /**
    ✪ To center this image both vertically and horizontally,
    in the .frame rule above comment the 'justify-content'
    and 'align-items' declarations,
    then  uncomment 'margin: auto;' below.
    **/

    /* margin: auto; */
}

/* Styling stuff not needed for demo */
.frame {
    max-width: 900px;
    height: 200px;
    margin: auto;
    background: #222;
}
p {
    max-width: 900px;
    margin: 20px auto 0;
}
img {
    width: 150px;
}
<div class="frame">
    <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/9988/hand-pointing.png">
</div>

Here's a Pen: http://codepen.io/ricardozea/pen/aa0ee8e6021087b6e2460664a0fa3f3e

@Drew 2015-12-29 20:22:47

Looks good. Might change the text though

@Dave Barnett 2018-05-10 15:47:17

This is especially useful if the height of the container is not set

@Michael 2019-05-14 22:06:33

or align-self for individual items

@Ricardo Zea 2019-05-15 15:49:24

The problem with align-self is that the flex items will stretch the height of the parent container.

@DOCTYPE HTML 2015-10-18 17:03:53

An easy way which work for me:

img {
    vertical-align: middle;
    display: inline-block;
    position: relative;
}

It works for Google Chrome very well. Try this one out in a different browser.

@Jorge Orpinel 2015-02-10 04:48:03

A three-line solution:

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

This applies to anything.

From here.

@Justin 2015-02-12 23:31:56

For those wondering, this works for IE9+

@Jorge Orpinel 2015-04-19 03:03:01

Prefixes: -ms- or -webkit- (before transform). w3schools.com/cssref/css3_pr_transform.asp

@Reign.85 2015-09-02 12:45:11

Prefixes for IE9, but not working at all in IE8 and lower : caniuse.com/#search=transform But my opinion : I don't care about IE8

@Andrei Gheorghiu 2017-02-02 22:08:29

Nobody noticed what happens when the child to be centered is taller than the device screen and the parent is the first child in DOM...?

@villasv 2017-03-06 15:51:48

It does work, but that transformation may not be instantaneous, giving a bad hack visual effect.

@plong0 2017-03-14 19:03:38

Nice one when you can't use position: absolute; because you need a flowing width.

@Alexis Wilke 2017-03-26 07:02:59

This is nearly correct, but in my text I can see it's a 1 pixel off...

@Aristides 2017-07-23 17:30:42

I'm surprised that the real solution that doesn't require any extra elements is buried this far down.

@albanx 2018-11-25 10:56:40

Best solution so far, even better than flexbox, with a support for most all browsers modern and olds ones. Upvote this please

@ViliusL 2019-01-10 07:59:56

warning: in some cases images will appear blurry.

@Kumar 2015-02-03 06:16:33

The best solution is that

.block{
    /* Decor */
    padding:0 20px;
    background: #666;
    border: 2px solid #fff;
    text-align: center;
    /* Important */
    min-height: 220px;
    width: 260px;
    white-space: nowrap;
}
.block:after{
    content: '';
    display: inline-block;
    height: 220px; /* The same as min-height */
    width: 1px;
    overflow: hidden;
    margin: 0 0 0 -5px;
    vertical-align: middle;
}
.block span{
    vertical-align: middle;
    display: inline-block;
    white-space: normal;
}

@slava 2014-01-29 07:10:19

I am not sure about Internet Explorer, but under Firefox and Chrome, if you have an img in a div container, the following CSS content should work. At least for me it works well:

div.img-container {
    display: table-cell;
    vertical-align: middle;
    height: 450px;
    width: 490px;
}

div.img-container img {
    max-height: 450px;
    max-width: 490px;
}

@TheCarver 2014-05-28 00:27:01

IE8+, unfortunately. Fine for me, but maybe not for others.

@Mutmatt 2014-09-02 19:38:58

also note that display:table-cell; doesn't accept % as widths

@user669677 2013-11-22 16:03:29

This way you can center an image vertically (demo):

div{
  height: 150px; // Internet Explorer 7 fix
  line-height: 150px;
}
img{
  vertical-align: middle;
  margin-bottom: 0.25em;
}

@Luca Spiller 2013-12-13 16:25:36

Strangely I couldn't get the accepted answer to work in my situation (I was also cropping the image with overflow: hidden). This worked prefectly though.

@Todd Price 2014-02-11 18:19:31

I've only tested this in Chrome, but line-height appears to be the key. I put the vertical-align attribute on the div rather than the img though, as my img is inside an anchor (<a/>).

@vdboor 2014-02-18 10:10:23

Yes, much simpler then the accepted solution, and works beautifully. I also found this solution in jsfiddle.

@KrekkieD 2014-06-03 07:04:59

If you know what heights to cater for, this works pretty well

@alTus 2015-02-28 17:44:26

From my expierence this solution only work with font-size: 0 for div. For quite big containers you can miss it but if your div is 100px and img is 80px it will be a few pixels lower.

@PJ Brunet 2015-05-17 07:33:28

Problem is, the absurd line-height pushes down nearby content. Also the image is not really centered--in my experience, every device renders "line-height" slightly different. I would avoid this method if you can help it!

@Gershom Maes 2015-09-28 14:00:57

another issue is that it relies on the container's height remaining the same (150px in this case) - as soon as the container's height may be dynamic this solution fails without javascript

@Viren 2019-03-06 19:18:08

Finally after trying all different methods, I got solution from this answer. Big Thanks. When I tried img { position: absolute; }, my images going out of table/div. And yes as @Savage said, line-height did the trick. and also vertical-align: middle; to the img element. So for the div { height, line-height } and for the img { max-height, max-width, vertical-align } are my required attributes.

@jomo 2013-09-18 09:53:32

matejkramny's solution is a good start, but oversized images have a wrong ratio.

Here's my fork:

Demo: https://jsbin.com/lidebapomi/edit?html,css,output

preview


HTML:

<div class="frame">
  <img src="foo"/>
</div>

CSS:

.frame {
    height: 160px; /* Can be anything */
    width: 160px; /* Can be anything */
    position: relative;
}
img {
    max-height: 100%;
    max-width: 100%;
    width: auto;
    height: auto;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}

@Justin 2015-04-20 17:51:50

Any way to adapt this so that you could zoom on the oversized image, say 2x, and it would still stay centered horizontally and vertically?

@jomo 2015-04-20 19:12:27

@Justin it totally is possible: jsbin.com/sejejemudi/2/edit (hover)

@bobo 2016-03-16 23:53:40

If we want to make it work for vertical align bottom instead of middle, what codes should be modified?

@jomo 2016-03-17 11:06:10

@bobo just remove the top: 0;. This results in only bottom: 0; being applied vertically.

@algreat 2013-01-26 19:46:52

I had the same problem. This works for me:

<style type="text/css">
    div.parent {
        position: relative;
    }

    img.child {
        bottom: 0;
        left: 0;
        margin: auto;
        position: absolute;
        right: 0;
        top: 0;
    }
</style>

<div class="parent">
    <img class="child">
</div>

@Vasilios Paspalas 2014-02-20 20:21:30

actually the "position: fixed" on the image worked for me where i've been frustrated over the numerous false answers of people suggesting the table-cell method that didn't work in neighter of my works. With the method suggested by algreat you don't need an extra container too.

@Tahir Yasin 2012-07-30 05:57:45

This might be useful:

div {
    position: relative;
    width: 200px;
    height: 200px;
}
img {
    position: absolute;
    top: 0;
    bottom: 0;
    margin: auto;
}
.image {
    min-height: 50px
}

Reference: http://www.student.oulu.fi/~laurirai/www/css/middle/

@jameskind 2013-02-02 03:09:19

If you wish to also horizontally align the image, add left:0; right: 0; to img

@Jenny O'Reilly 2013-05-29 10:51:26

This is nice, but doesn't work in IE 10 :(

@Max Yari 2015-02-09 17:28:39

is this one rly not working in IE10? I kinda using this all over the place

@PJ Brunet 2015-05-17 07:23:45

Also works (for me) with container div having position:fixed;

@Scheintod 2019-09-26 15:35:35

The Link is dead

@feeela 2011-09-07 16:49:53

If you can live with pixel-sized margins, just add font-size: 1px; to the .frame. But remember, that now on the .frame 1em = 1px, which means, you need to set the margin in pixels too.

http://jsfiddle.net/feeela/4RPFa/96/

Now it's not centered any more in Opera…

@sandeep 2011-09-05 12:26:33

Try this solution with pure CSS http://jsfiddle.net/sandeep/4RPFa/72/

Maybe it is the main problem with your HTML. You're not using quotes when you define class & image height in your HTML.

CSS:

.frame {
    height: 25px;      /* Equals maximum image height */
    width: 160px;
    border: 1px solid red;
    position: relative;
    margin: 1em 0;
    top: 50%;
    text-align: center;
    line-height: 24px;
    margin-bottom: 20px;
}

img {
    background: #3A6F9A;
    vertical-align: middle;
    line-height: 0;
    margin: 0 auto;
    max-height: 25px;
}

When I work around with the img tag it's leaving 3 pixels to 2 pixels space from top. Now I decrease line-height, and it's working.

CSS:

    .frame {
        height: 25px;      /* Equals maximum image height */
        width: 160px;
        border: 1px solid red;
        margin: 1em 0;
        text-align: center;
        line-height: 22px;
        *:first-child+html line-height:24px; /* For Internet Explorer 7 */
    }

    img {
        background: #3A6F9A;
        vertical-align: middle;
        line-height: 0;    
        max-height: 25px;
        max-width: 160px;
    }
@media screen and (-webkit-min-device-pixel-ratio:0) {
    .frame {
        line-height:20px; /* WebKit browsers */
    }

The line-height property is rendered differently in different browsers. So, we have to define different line-height property browsers.

Check this example: http://jsfiddle.net/sandeep/4be8t/11/

Check this example about line-height different in different browsers: input height differences in Firefox and Chrome

@Arnaud Le Blanc 2011-09-05 13:40:16

Doesn't work (at least in Firefox). For the missing quotes, this is allowed in HTML5 (don't know which doctype is used in jsfiddle though)

@code ninja 2011-09-05 11:09:52

A pure CSS solution:

http://jsfiddle.net/3MVPM/

The CSS:

.frame {
    margin: 1em 0;
    height: 35px;
    width: 160px;
    border: 1px solid red;
    position: relative;
}
img {
    max-height: 25px;
    max-width: 160px;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    background: #3A6F9A;
}

Key stuff

// position: relative; - in .frame holds the absolute element within the frame
// top: 0; bottom: 0; left: 0; right: 0; - this is key for centering a component
// margin: auto; - centers the image horizontally & vertically

@code ninja 2011-09-05 14:38:02

Please let me refer you to a guide here that even works for IE5 (deducting from what i've read so far in the post) webmasterworld.com/css/3350566.htm

@jomo 2013-09-18 09:54:44

this solution is a good start, but oversized images get resized with wrong ratio. Please see my answer.

@code ninja 2013-09-27 13:12:28

@HansWürstchen yeah, but the point is to center, whether it gets oversized is design choice. Adding more css = more clutter :)

@jomo 2013-09-28 15:57:01

@matejkramny it does not get oversized. if the image is oversized, it has a wrong ratio. that means it is stretched in height and doesn't look properly.

@Cedric Reichenbach 2014-01-07 17:52:08

✔ Wow, this works with overflowing images (bigger than wrapper), the accepted answer does not.

@code ninja 2014-01-07 21:46:55

@CedricReichenbach that's because it is absolute.. It can apply to any element and not just images btw

@DrCord 2016-03-23 16:23:01

This doesn't seem to work well with responsive images that don't have a size set.

@Shir Gans 2018-09-26 12:49:47

example for bottom-left: top: auto; bottom: 0; left: 0; right: auto;

@Webars 2011-09-04 18:04:36

http://jsfiddle.net/MBs64/

.frame {
    height: 35px;      /* Equals maximum image height */
    width: 160px;
    border: 1px solid red;
    text-align: center;
    margin: 1em 0;
    display: table-cell;
    vertical-align: middle;
}
img {
    background: #3A6F9A;
    display: block;
    max-height: 35px;
    max-width: 160px;
}

The key property is display: table-cell; for .frame. Div.frame is displayed as inline with this, so you need to wrap it in a block element.

This works in Firefox, Opera, Chrome, Safari and Internet Explorer 8 (and later).

UPDATE

For Internet Explorer 7 we need to add a CSS expression:

*:first-child+html img {
    position: relative;
    top: expression((this.parentNode.clientHeight-this.clientHeight)/2+"px");
}

@Arnaud Le Blanc 2011-09-04 18:40:54

Great. Any hack for IE7 that would avoid the javascript?

@Webars 2011-09-05 05:46:32

I'm not sure, but maybe css expressions would help. But they are javascript too. The only difference, that you write them in css files, not in js.

@Arnaud Le Blanc 2011-09-05 08:30:37

Yes, nice idea. That would be more manageable (the script is automatically ran as needed), and as it's supposed to be IE7-only it's ok.

@Joseph Marikle 2011-09-04 17:34:04

You could do this:

Demo

http://jsfiddle.net/DZ8vW/1

CSS

.frame {
    height: 25px;      /* Equals maximum image height */
    line-height: 25px;
    width: 160px;
    border: 1px solid red;

    text-align: center; 
    margin: 1em 0;
    position: relative; /* Changes here... */
}
img {
    background: #3A6F9A;
    max-height: 25px;
    max-width: 160px;
    top: 50%;           /* Here.. */
    left: 50%;          /* Here... */
    position: absolute; /* And here */
}    


JavaScript

$("img").each(function(){
    this.style.marginTop = $(this).height() / -2 + "px";
})

@Arnaud Le Blanc 2011-09-04 18:38:23

Nice. Any chance for a pure-css solution ?

@Joseph Marikle 2011-09-04 18:54:26

Unfortunately no unless you want to use tables or drop compatibility with older versions of IE. :( If you knew the exact size of the images before hand it would be different, but not without that it's not possible with CSS alone.

@Benjamin Udink ten Cate 2011-09-04 19:59:25

@Joseph How would you fix it with tables?

@Joseph Marikle 2011-09-04 20:33:04

@Benjamin Udink ten Cate It's messy but it could be done this way: jsfiddle.net/DZ8vW/2 (this is not advised, but should work)

@Benjamin Udink ten Cate 2011-09-05 00:41:45

Well it suits arnauds needs perfectly. No JS, only CSS and HTML.

@Arnaud Le Blanc 2011-09-05 13:43:18

@Joseph jsfiddle.net/DZ8vW/2 doesn't seem to work properly in firefox

@Joseph Marikle 2011-09-05 21:19:11

@arnaud576875 It's a little glitchy but here's one that will work on FF also... though now I know why using tables is ill-advised :P jsfiddle.net/DZ8vW/3

@Benjamin Udink ten Cate 2011-09-04 13:17:02

Background image solution

I removed the image element altogether and set it as background of the div with a class of .frame

http://jsfiddle.net/URVKa/2/

This at least works fine on Internet Explorer 8, Firefox 6 and Chrome  13.

I checked, and this solution will not work to shrink images larger than 25 pixels height. There is a property called background-size which does set the size of the element, but it is CSS 3 which would conflict with Internet Explorer 7 requirements.

I would advice you to either redo your browser priorities and design for the best available browsers, or get some server-side code to resize the images if you'd want to use this solution.

@Arnaud Le Blanc 2011-09-04 13:18:24

jsfiddle.net/4RPFa/58 doesn't works :(

@Arnaud Le Blanc 2011-09-04 13:34:31

Very nice solution, however I expect some images to be bigger than the container, and in this case I planed to use max-height / max-width on them. Any way to do this with background images?

@Arnaud Le Blanc 2011-09-04 13:38:08

yes; I've updated the question and the jsfiddle: jsfiddle.net/4RPFa/61

@JGallardo 2016-10-17 18:40:06

this is not a ".frame element" it is a "div with a class of .frame"

@efirat 2016-12-07 12:10:12

If image height does not exceed frame div's height, this is the best and simplest solution...

@kizu 2011-09-05 16:04:27

The only (and the best cross-browser) way as I know is to use an inline-block helper with height: 100% and vertical-align: middle on both elements.

So there is a solution: http://jsfiddle.net/kizu/4RPFa/4570/

.frame {
    height: 25px;      /* Equals maximum image height */
    width: 160px;
    border: 1px solid red;
    white-space: nowrap; /* This is required unless you put the helper span closely near the img */

    text-align: center;
    margin: 1em 0;
}

.helper {
    display: inline-block;
    height: 100%;
    vertical-align: middle;
}

img {
    background: #3A6F9A;
    vertical-align: middle;
    max-height: 25px;
    max-width: 160px;
}
<div class="frame">
    <span class="helper"></span><img src="http://jsfiddle.net/img/logo.png" height=250px />
</div>
<div class="frame">
    <span class="helper"></span><img src="http://jsfiddle.net/img/logo.png" height=25px />
</div>
<div class="frame">
    <span class="helper"></span><img src="http://jsfiddle.net/img/logo.png" height=23px />
</div>
<div class="frame">
    <span class="helper"></span><img src="http://jsfiddle.net/img/logo.png" height=21px />
</div>
<div class="frame">
    <span class="helper"></span><img src="http://jsfiddle.net/img/logo.png" height=19px />
</div>
<div class="frame">
    <span class="helper"></span>
    <img src="http://jsfiddle.net/img/logo.png" height=17px />
</div>
<div class="frame">
    <span class="helper"></span>
    <img src="http://jsfiddle.net/img/logo.png" height=15px />
</div>
<div class="frame">
    <span class="helper"></span>
    <img src="http://jsfiddle.net/img/logo.png" height=13px />
</div>
<div class="frame">
    <span class="helper"></span>
    <img src="http://jsfiddle.net/img/logo.png" height=11px />
</div>
<div class="frame">
    <span class="helper"></span>
    <img src="http://jsfiddle.net/img/logo.png" height=9px />
</div>
<div class="frame">
    <span class="helper"></span>
    <img src="http://jsfiddle.net/img/logo.png" height=7px />
</div>
<div class="frame">
    <span class="helper"></span>
    <img src="http://jsfiddle.net/img/logo.png" height=5px />
</div>
<div class="frame">
    <span class="helper"></span>
    <img src="http://jsfiddle.net/img/logo.png" height=3px />
</div>

Or, if you don't want to have an extra element in modern browsers and don't mind using Internet Explorer expressions, you can use a pseudo-element and add it to Internet Explorer using a convenient expression, that runs only once per element, so there won't be any performance issues:

The solution with :before and expression() for Internet Explorer: http://jsfiddle.net/kizu/4RPFa/4571/

.frame {
    height: 25px;      /* Equals maximum image height */
    width: 160px;
    border: 1px solid red;
    white-space: nowrap;

    text-align: center;
    margin: 1em 0;
}

.frame:before,
.frame_before {
    content: "";
    display: inline-block;
    height: 100%;
    vertical-align: middle;
}

img {
    background: #3A6F9A;
    vertical-align: middle;
    max-height: 25px;
    max-width: 160px;
}

/* Move this to conditional comments */
.frame {
    list-style:none;
    behavior: expression(
        function(t){
            t.insertAdjacentHTML('afterBegin','<span class="frame_before"></span>');
            t.runtimeStyle.behavior = 'none';
        }(this)
    );
}
<div class="frame"><img src="http://jsfiddle.net/img/logo.png" height=250px /></div>
<div class="frame"><img src="http://jsfiddle.net/img/logo.png" height=25px /></div>
<div class="frame"><img src="http://jsfiddle.net/img/logo.png" height=23px /></div>
<div class="frame"><img src="http://jsfiddle.net/img/logo.png" height=21px /></div>
<div class="frame"><img src="http://jsfiddle.net/img/logo.png" height=19px /></div>
<div class="frame"><img src="http://jsfiddle.net/img/logo.png" height=17px /></div>
<div class="frame"><img src="http://jsfiddle.net/img/logo.png" height=15px /></div>
<div class="frame"><img src="http://jsfiddle.net/img/logo.png" height=13px /></div>
<div class="frame"><img src="http://jsfiddle.net/img/logo.png" height=11px /></div>
<div class="frame"><img src="http://jsfiddle.net/img/logo.png" height=9px /></div>
<div class="frame"><img src="http://jsfiddle.net/img/logo.png" height=7px /></div>
<div class="frame"><img src="http://jsfiddle.net/img/logo.png" height=5px /></div>
<div class="frame"><img src="http://jsfiddle.net/img/logo.png" height=3px /></div>


How it works:

  1. When you have two inline-block elements near each other, you can align each to other's side, so with vertical-align: middle you'll get something like this:

    Two aligned blocks

  2. When you have a block with fixed height (in px, em or other absolute unit), you can set the height of inner blocks in %.

  3. So, adding one inline-block with height: 100% in a block with fixed height would align another inline-block element in it (<img/> in your case) vertically near it.

@Webars 2011-09-05 21:07:23

As I understood, only inline-block elements can be stretched to height: 100%;. And we can't do this with either inline or block elements, am I right?

@kizu 2011-09-06 05:01:37

You can see for yourself: jsfiddle.net/kizu/Pw9NL — only inline boxes don't generate a box, but all other cases work ok.

@thirtydot 2011-09-07 15:01:30

I like the use of :before+expression(), in the past I've always stuck to having the extra element. I don't care about IE6/7 with JavaScript disabled, so I'll probably use that technique in the future.

@kizu 2011-09-07 15:09:35

@thirtydot the best part of such expressions is that you can move them to an external .js file (included in CC for IE too) as named functions and only use references in a stylesheet, you can even create classname for _before on the fly by parsing the classname of the original element.

@Mick 2013-05-14 09:07:35

Very good answer. I was struggling with the spaces between the inline block elements, meaning between .frame and .frame:before. A solution proposed here is to add margin-left: -4px to .frame. Hope this helps.

@Jonathan Root 2013-08-14 15:49:26

One problem though. When I zoom in and the image exceeds all screen borders, I get a huge empty bar above the image. First, as long as I only cross the top and bottom border, everything is fine. But when the left and right border is crossed, somehow the helper element gets in the way. And I really thought, this is the perfect solution. But thank you for your efforts. (Ubuntu 12.04, Firefox 23, xhtml11-strict.dtd)

@ryan 2013-12-12 21:50:03

PAY ATTENTION that the: <img src=""/> is NOT inside of the <span></span> helper that was added. It is outside. I just about pulled every strand of my hair our by not realizing this.

@juminoz 2014-01-01 18:59:59

It seems like you also need to add "white-space: nowrap;" to the frame or you will run into an issue if you have line break between your image and the helper span. It took me an hour why this solution wasn't working for me.

@Eric Dubé 2014-08-18 04:14:18

In my case, my image had max-height and max-width both set to 100% so the image would scale the container, and this method did not work. My solution was to change these values to 90% (which in my case was okay; in another situation you may need to scale the container accordingly), and also add a helper to the other side of the image so the padding would remain even on both sides.

@MrCroft 2014-09-18 12:48:01

Thank you very much! I needed this :) I've always used two divs to wrap the image (one with display: table and another with display: table-cell) - never had to also put another one in-between with display: table-row, but I don't know why it doesn't work on IE on windows mobile if a have position: fixed; on any of the divs or margin in percentage on the image :| BUT your css did the trick, works flawlessly on IEmobile, IE7+ and Chrome/Firefox (tested only on the latest versions at the moment) Thanks again!

@westcoast 2015-01-17 10:35:50

@EricDubé i had a similar problem, I just put the span after the img instead of before it (or use :after instead of :before) and the image stays in the container perfectly

@Jason Lin 2015-06-05 14:58:58

In case anyone has an issue with the image being slightly shifted to the right. the trick is to add "font-size: 0;" to the parent.

@Med7at 2016-05-10 12:12:40

when using it inside bootstrap thumbnail container you will find that the span is shifted 4 pixels from the left and you have to add this to the styling of the helper span ""margin-left: -4px"" to get it in the right place.

@Scott 2016-09-01 15:22:43

I don't know why this didn't work for me but I had to add display: inline-block; in my image CSS as described in the text above the code snippet - but not actually in the code snippet.

@Sam 2017-04-09 15:34:10

Hello, sorry but I disagree about use a helper here. And also It is not the only way. Others are same supported by browsers. I offer a solution here: stackoverflow.com/a/43308414/7733724 and W3C.org about info. You could check. Cheers.

@Jonny 2017-04-12 09:52:52

Doesn't work in my project. My outer DIV has to be position: fixed. I guess that screws up everything

@Jonny 2017-04-20 08:48:45

This solution works only on known height of image, else use: "display: table-cell; text-align: center; vertical-align: middle;" on the element around the image (f.e. DIV)

@Cristian Traìna 2019-10-14 14:44:37

It's 2019, we should start update our answers and start talking about flex

@Kissaki 2018-04-22 16:16:49

You can use a grid layout to vertically center the image.

.frame {
  display: grid;
  grid-template-areas: "."
                       "img"
                       "."
  grid-template-rows: 1fr auto 1fr;
  grid-template-columns: auto;
}
.frame img {
  grid-area: img;
}

This will create a 3 row 1 column grid layout with unnamed 1 fraction wide spacers at the top and bottom, and an area named img of auto height (size of the content).

The img will use the space it prefers, and the spacers at top and bottom will use the remaining height split to two equal fractions, resulting in the img element to be vertically centered.

http://jsfiddle.net/Kissaki0/4RPFa/20713/

@Alireza 2017-06-28 13:51:25

Using table and table-cell method do the job, specially because you targeting some old browsers as well, I create a snippet for you which you can run it and check the result:

.wrapper {
  position: relative;
  display: table;
  width: 300px;
  height: 200px;
}

.inside {
  vertical-align: middle;
  display: table-cell;
}
<div class="wrapper">
  <div class="inside">
    <p>Centre me please!!!</p>
  </div>
  <div class="inside">
    <img src="https://cdn2.iconfinder.com/data/icons/social-icons-circular-black/512/stackoverflow-128.png" />
  </div>
</div> 

@Daud khan 2017-06-21 08:42:49

You can use table structure inside a div

<div class="frame">
     <table width="100%">
         <tr>
            <td vertical-align="middle" align="center" height="25">
                <img src="https://jsfiddle.net/img/logo.png" >  
            </td>
        </tr>
    </table>
</div>

@Interactive 2017-10-12 09:50:24

Never use a table structure for images... Tables must only be used for displaying textual content and even then I would prefer a wel styled div

Related Questions

Sponsored Content

42 Answered Questions

[SOLVED] How to disable text selection highlighting

38 Answered Questions

[SOLVED] How do I vertically center text with CSS?

29 Answered Questions

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

101 Answered Questions

[SOLVED] How to horizontally center a <div>?

44 Answered Questions

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

20 Answered Questions

[SOLVED] Vertically align text next to an image?

28 Answered Questions

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

25 Answered Questions

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

10 Answered Questions

[SOLVED] Vertically align text within a div

31 Answered Questions

[SOLVED] How do I auto-resize an image to fit a 'div' container?

Sponsored Content