1597

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 the 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>
Community
  • 1
  • 1
Arnaud Le Blanc
  • 90,979
  • 22
  • 192
  • 188
  • 4
    Hello, sorry but I disagree about use a helper here being the most valuated solution. But It is not the only way. Others are same supported by browsers. I offer a solution here down stackoverflow.com/a/43308414/7733724 and W3C.org about info. You could check. Cheers – Sam Apr 12 '17 at 19:49
  • Reading Centring Things article on W3C will be useful: https://www.w3.org/Style/Examples/007/center.en.html – QMaster May 14 '18 at 22:30
  • Perfect guide for align https://css-tricks.com/centering-css-complete-guide/ – Michael Yurin Apr 04 '19 at 12:44
  • I think the key is line-height in .frame to make this work – Randy Lam Nov 14 '20 at 03:14

36 Answers36

2233

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 another 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.
Yashwardhan Pauranik
  • 4,638
  • 2
  • 30
  • 53
kizu
  • 40,566
  • 4
  • 62
  • 92
  • 1
    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? – Webars Sep 05 '11 at 21:07
  • 2
    You can see for yourself: http://jsfiddle.net/kizu/Pw9NL/ — only inline boxes don't generate a box, but all other cases work ok. – kizu Sep 06 '11 at 05:01
  • 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. – thirtydot Sep 07 '11 at 15:01
  • @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. – kizu Sep 07 '11 at 15:09
  • 3
    Very good answer. I was struggling with the spaces between the inline block elements, meaning between `.frame` and `.frame:before`. A solution proposed [here](http://css-tricks.com/fighting-the-space-between-inline-block-elements/) is to add `margin-left: -4px` to `.frame`. Hope this helps. – Mick May 14 '13 at 09:07
  • 1
    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) – Jonathan Root Aug 14 '13 at 15:49
  • 51
    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. – juminoz Jan 01 '14 at 18:59
  • 119
    PAY ATTENTION that the: `` is NOT inside of the `` helper that was added. It is outside. I just about pulled every strand of my hair our by not realizing this. – ryan Dec 12 '13 at 21:50
  • 2
    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. – Eric Dubé Aug 18 '14 at 04:14
  • 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! – MrCroft Sep 18 '14 at 12:48
  • @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 – westcoast Jan 17 '15 at 10:35
  • 1
    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. – Jason Lin Jun 05 '15 at 14:58
  • 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. – medhatdawoud May 10 '16 at 12:12
  • 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. – Scott Sep 01 '16 at 15:22
  • 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: http://stackoverflow.com/a/43308414/7733724 and W3C.org about info. You could check. Cheers. – Sam Apr 09 '17 at 15:34
  • Doesn't work in my project. My outer DIV has to be position: fixed. I guess that screws up everything – Jonny Apr 12 '17 at 09:52
  • 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) – Jonny Apr 20 '17 at 08:48
  • 2
    It's 2019, we should start update our answers and start talking about flex – Cristian Traìna Oct 14 '19 at 14:44
  • It worked well without effecting any of the other elements! :) – MHBN May 25 '20 at 06:18
551

This might be useful:

div {
    position: relative;
    width: 200px;
    height: 200px;
}
img {
    position: absolute;
    top: 0;
    bottom: 0;
    margin: auto;
}
.image {
    min-height: 50px
}
Tahir Yasin
  • 10,631
  • 5
  • 38
  • 58
522

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;
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
jomo
  • 11,665
  • 4
  • 25
  • 28
345

A three-line solution:

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

This applies to anything.

From here.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Jorge Orpinel
  • 4,897
  • 1
  • 16
  • 32
152

A pure CSS solution:

.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;
}
<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>

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
dota2pro
  • 5,432
  • 5
  • 25
  • 52
Matej
  • 8,739
  • 7
  • 46
  • 66
  • 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) http://www.webmasterworld.com/css/3350566.htm – Matej Sep 05 '11 at 14:38
  • this solution is a good start, but oversized images get resized with **wrong ratio**. Please see my answer. – jomo Sep 18 '13 at 09:54
  • @HansWürstchen yeah, but the point is to center, whether it gets oversized is design choice. Adding more css = more clutter :) – Matej Sep 27 '13 at 13:12
  • 1
    @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. – jomo Sep 28 '13 at 15:57
  • ✔ Wow, this works with overflowing images (bigger than wrapper), the accepted answer does not. – Cedric Reichenbach Jan 07 '14 at 17:52
  • @CedricReichenbach that's because it is absolute.. It can apply to any element and not just images btw – Matej Jan 07 '14 at 21:46
  • This doesn't seem to work well with responsive images that don't have a size set. – DrCord Mar 23 '16 at 16:23
  • example for bottom-left: top: auto; bottom: 0; left: 0; right: auto; – Shir Gans Sep 26 '18 at 12:49
129

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

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Ricardo Zea
  • 8,927
  • 12
  • 67
  • 76
101

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;
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
  • 4
    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. – Luca Spiller Dec 13 '13 at 16:25
  • 3
    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 (). – Todd Price Feb 11 '14 at 18:19
  • 1
    Yes, much simpler then the accepted solution, and works beautifully. I also found this solution in jsfiddle. – vdboor Feb 18 '14 at 10:10
  • 1
    If you know what heights to cater for, this works pretty well – KrekkieD Jun 03 '14 at 07:04
  • 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. – alTus Feb 28 '15 at 17:44
  • 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! – PJ Brunet May 17 '15 at 07:33
  • 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 – Gershy Sep 28 '15 at 14:00
  • 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. – Vi_real Mar 06 '19 at 19:18
44

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>
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
tourniquet
  • 1,145
  • 2
  • 13
  • 18
37

There is a super easy solution with flexbox!

.frame {
    display: flex;
    align-items: center;
}
BBlackwo
  • 1,115
  • 1
  • 14
  • 13
  • 5
    Yes but you can hardly see it in all of the answers. I was trying to highlight it simply and clearly as it's a much much easier solution than all of the other answers. – BBlackwo Apr 21 '16 at 11:57
  • This is the best answer that also worked for me. But in my case in the frame "inline-flex" worked better for me. and for the image inside it i added: "vertical-align: middle". – Sophie Cooperman Nov 04 '19 at 15:35
  • Flexbox has a really wide range support nowadays. This is the easiest solution (and probably your responsive will thank you). support documentation: https://caniuse.com/#feat=flexbox – Marina M Aug 25 '20 at 12:10
22

You could try setting the CSS of PI to display: table-cell; vertical-align: middle;

Yeodave
  • 958
  • 1
  • 8
  • 15
21

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>
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Santosh Khalse
  • 9,358
  • 3
  • 32
  • 35
20

Imagine you have

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

And css:

.wrap {
    display: flex;
}
.wrap img {
    object-fit: contain;
}
fdrv
  • 656
  • 1
  • 8
  • 20
  • use object-fit cover if you want the child to take up the full width of the parent and still be vertically aligned to the middle. See https://css-tricks.com/snippets/css/a-guide-to-flexbox/ to move the image around in the parent using flex-box – mattdlockyer Jan 15 '20 at 23:41
14

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Benjamin Udink ten Cate
  • 12,052
  • 3
  • 43
  • 63
  • 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 Sep 04 '11 at 13:34
  • this is not a ".frame element" it is a "div with a class of .frame" – JGallardo Oct 17 '16 at 18:40
  • If image height does not exceed frame div's height, this is the best and simplest solution... – efirat Dec 07 '16 at 12:10
12

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");
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Webars
  • 4,668
  • 6
  • 34
  • 50
11

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";
})
Community
  • 1
  • 1
Joseph Marikle
  • 68,672
  • 14
  • 103
  • 120
8

CSS Grid

If you want to align a single image vertically inside an image container you can use this:

.img-container {
  display: grid;
}

img { 
  align-self: center;
}

.img-container {
  display: grid;
  grid-auto-flow: column; 
  background: #BADA55;
  width: 1200px;
  height: 500px;
}

img.vertical-align {
  align-self: center;
}
<div class="img-container">
  <img src="https://picsum.photos/300/300" />
  <img class="vertical-align" src="https://picsum.photos/300/300" />
  <img src="https://picsum.photos/300/300" />
</div>

If you want to align multiple images inside an image container you can use this:

.img-container {
  display: grid;
  align-items: center;
}

.img-container {
  display: grid;
  grid-auto-flow: column;
  align-items: center;
  background: #BADA55;
  width: 1200px;
  height: 500px;
}
<div class="img-container">
  <img src="https://picsum.photos/300/300" />
  <img src="https://picsum.photos/300/300" />
  <img src="https://picsum.photos/300/300" />
</div>

Please note that I have used grid-auto-flow: column in both the cases because otherwise the elements wrap to a row with specifying explicit grid items. In the question code, I see the item centered horizontally too. In that case, just make use of the place-items: center instead of align-items: center.

m4n0
  • 25,434
  • 12
  • 57
  • 77
8

This works for modern browsers (2016 at time of edit) as shown in this demo on codepen

.frame {
    height: 25px;
    line-height: 25px;
    width: 160px;
    border: 1px solid #83A7D3;          
}
.frame img {
    background: #3A6F9A;
    display:inline-block;
    vertical-align: middle;
}

It is very important that you either give the images a class or use inheritance to target the images that you need centered. In this example we used .frame img {} so that only images wrapped by a div with a class of .frame would be targeted.

JGallardo
  • 9,783
  • 7
  • 72
  • 84
anglimasS
  • 1,242
  • 2
  • 16
  • 40
7

My solution: http://jsfiddle.net/XNAj6/2/

<div class="container">
    <div class="frame">
        <img src="http://jsfiddle.net/img/logo.png" class="img" alt="" />
    </div>
</div>

.container {
    display: table;
    float: left;
    border: solid black 1px;
    margin: 2px;
    padding: 0;
    background-color: black;
    width: 150px;
    height: 150px;
}
.frame {
    display: table-cell;
    text-align: center;
    vertical-align: middle;
    border-width: 0;
}
.img {
    max-width: 150px;
    max-height: 150px;
    vertical-align: middle;
}
Ilya Lysenko
  • 1,497
  • 14
  • 21
7

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;
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
slava
  • 359
  • 1
  • 3
  • 13
7

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Sam
  • 1,318
  • 1
  • 14
  • 30
7

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

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
sandeep
  • 85,904
  • 23
  • 131
  • 151
  • 2
    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) – Arnaud Le Blanc Sep 05 '11 at 13:40
6

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
6

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>
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
juliangonzalez
  • 3,616
  • 28
  • 43
4

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>
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
algreat
  • 7,762
  • 5
  • 38
  • 52
  • 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. – Vasilios Paspalas Feb 20 '14 at 20:21
4

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…

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
feeela
  • 26,359
  • 6
  • 56
  • 68
2

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;
 }
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Masoumeh Karvar
  • 705
  • 1
  • 12
  • 27
1

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>
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Marius
  • 407
  • 1
  • 4
  • 16
1

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> 
Alireza
  • 83,698
  • 19
  • 241
  • 152
0

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");
  });
}
SE_net4 the downvoter
  • 21,043
  • 11
  • 69
  • 107
Chris
  • 1,640
  • 3
  • 18
  • 27
0

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;
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Kumar
  • 2,915
  • 4
  • 28
  • 44
0

I have been playing around with using padding for center alignment. You will need to define the top level outer-container size, but the inner container should resize, and you can set the padding at different percentage values.

jsfiddle

<div class='container'>
  <img src='image.jpg' />
</div>

.container {
  padding: 20%;
  background-color: blue;
}

img {
  width: 100%;
}
svnm
  • 17,405
  • 18
  • 82
  • 100
0

Use this one:

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

And you can vary font-size.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
th3pirat3
  • 480
  • 6
  • 17
0

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>
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Sandeep Sherpur
  • 1,507
  • 18
  • 18
-1

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>
Daud khan
  • 1,669
  • 2
  • 9
  • 14
  • 1
    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` – Interactive Oct 12 '17 at 09:50
-1

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/

Kissaki
  • 8,159
  • 4
  • 34
  • 36
-2

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Samuel Ramzan
  • 1,478
  • 1
  • 14
  • 23