68

I have a markup like this:

<div>
  <img />
</div>

The div is higher than img:

div {
  height: 100px;
}

img {
  height: dynamic-value-smaller-than-100px;
}

I need the image to be in the middle of the div (have same amout of white space above and below it).

I tried this and it does not work:

div {
  vertical-align: middle;
}
ib.
  • 27,830
  • 11
  • 80
  • 100
Josef Sábl
  • 7,538
  • 9
  • 54
  • 66
  • Here are two simple methods to center objects within a div, vertically, horizontally or both (pure CSS): http://stackoverflow.com/a/31977476/3597276 – Michael Benjamin Aug 20 '15 at 14:42

16 Answers16

73

if your image is purely decorative, then it might be a more semantic solution to use it as a background-image. You can then specify the position of the background

background-position: center center;

If it is not decorative and constitutes valuable information then the img tag is justified. What you need to do in such case is style the containing div with the following properties:

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

Read more about this technique here. Reported to not work on IE6/7 (works on IE8).

pixeline
  • 17,669
  • 12
  • 84
  • 109
55

Another way is to set your line-height in the container div, and align your image to that using vertical-align: middle.

html:

<div class="container"><img></div>

css:

.container {
  width: 200px; /* or whatever you want */
  height: 200px; /* or whatever you want */
  line-height: 200px; /* or whatever you want, should match height */
  text-align: center;
}

.container > img {
  vertical-align: middle;
}

It's off the top of my head. But I've used this before - it should do the trick. Works for older browsers as well.

akimsko
  • 904
  • 6
  • 7
  • 2
    As far as I can see this is the best solution there is. Weird that this is the second solution on the page. It's way easier to implement and works with all browsers. Tested it amongst all the oldies of IE and works well. Thank you. – Warre Buysse Feb 06 '14 at 11:57
  • This one should be the accepted answer. `display: table-cell;` will cause much more pain compared to this solution – trushkevich Oct 30 '14 at 13:21
9

Let's say you want to put the image (40px X 40px) on the center (horizontal and vertical) of the div class="box". So you have the following html:

<div class="box"><img /></div>

What you have to do is apply the CSS:

.box img {
    position: absolute;
    top: 50%;
    margin-top: -20px;
    left: 50%;
    margin-left: -20px;
}

Your div can even change it's size, the image will always be on the center of it.

Diogo Melo
  • 1,735
  • 3
  • 20
  • 29
5

This is a solution I've used before to accomplish vertical centering in CSS. This works in all the modern browsers.

http://www.jakpsatweb.cz/css/css-vertical-center-solution.html

Excerpt:

  <div style="display: table; height: 400px; position: relative; overflow: hidden;">
    <div style="position: absolute; top: 50%;display: table-cell; vertical-align: middle;">
      <div style="position: relative; top: -50%">
        any text<br>
        any height<br>
        any content, for example generated from DB<br>
        everything is vertically centered
      </div>
    </div>
  </div>

(Inline styles for demonstration purposes)

Omer M.
  • 630
  • 7
  • 17
Shawn Steward
  • 6,773
  • 3
  • 24
  • 45
3

Another option is to set display:block on the img and then set margin: 0px auto;

img{
    display: block;
    margin: 0px auto;
}
Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
2

As I too am constantly being let down by cross-browser CSS, I'd like to offer a JQuery solution here. This takes the height of each image's parent div, divide it by two and set it as a top margin between the image and the div:

$('div img').each(function() {
 m = Math.floor(($(this).parent('div').height() - $(this).height())/2);
 mp = m+"px";
 $(this).css("margin-top",mp);
});
Cantrelby
  • 21
  • 2
2

There are five possible ways for centering an image with any size with pure CSS.

  1. Using flex and making the img tag be inside (best solution for modern browsers):

    div {
        display: flex;
        align-items: center;
        justify-content: center
    }
    
  2. Putting the image in background-image and using background-position (as @pixeline explained):

    div {
        background-image: url(...);
        background-position:center center
    }
    
  3. Using display: table for parent element, and using display: table-cell with vertical-align: middle for child element:

    div.parent {
        display: table;
    }
    div.child {
        display: table-cell;
        vertical-align: middle;
    }
    
  4. Using position:absolute with transform for the image and parent element position be not unset:

    div {
        position: relative;
    }
    div > img {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%,-50%);
    }
    
  5. Using line-height as same height of the element, then using vertical-align (in my opinion, the best solution for supporting more browsers like IE9>).

    Note: In some old browsers, sometimes for using this way safely, you need to have at least one character in the line that the image exist. For fixing this issue, I used a non-breakable space in a pseudo-element of the parent.

    As in the following example:

    div {
        display: block;
        height: 200px;
        width: 200px;
        background-color: purple;
        line-height: 200px;
        text-align: center;
    }
    div:after {
      content: "\a0";
    }
    div > img {
        vertical-align: middle;
    }
    <div><img src="https://via.placeholder.com/100.png/09f/fff" /></div>
ib.
  • 27,830
  • 11
  • 80
  • 100
1

I've posted about vertical alignment it in cross-browser way (Vertically center multiple boxes with CSS)

Create one-cell table. Only table has cross-browser vertical-align

Community
  • 1
  • 1
Dewfy
  • 23,277
  • 13
  • 73
  • 121
1

image to be in the middle of the div

div img{ 
    bottom: 0;
    left: 0;
    margin: auto;
    position: absolute;
    right: 0;
    top: 0;
    height:50px;
    width:50px;
}
Ashish Maradiya
  • 113
  • 1
  • 8
0
<div style="background-color:#006600; width:300px; text-align:center; padding:50px 0px 50px 0px;">
<img src="imges/import.jpg" width="200" height="200"/>
</div>
Dinoop
  • 1
  • 1
0

The accepted answer did not work for me. vertical-align needs a partner so that they can be aligned at their centers. So I created an empty div with full height of the parent div but with no width for the image to align with. inline-block is needed for both objects to stay in one line.

<div>
    <div class="placeholder"></div>
    <img />
</div>

CSS:

.class {
    height: 100%;
    width: 0%;
    vertical-align: middle;
    display: inline-block
}
img {
    display: inline-block;
    vertical-align: middle;
}
MK Yung
  • 4,344
  • 6
  • 30
  • 35
0
div {

width:200px; 
height:150px; 

display:-moz-box; 
-moz-box-pack:center; 
-moz-box-align:center; 

display:-webkit-box; 
-webkit-box-pack:center; 
-webkit-box-align:center; 

display:box; 
box-pack:center; 
box-align:center;

}

<div>
<img src="images/logo.png" />
</div>
  • This works in Firefox and Chrome, but probably not in IE. Plus it is being deprecated. They created flex instead: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes – Alexis Wilke Feb 05 '14 at 06:44
0

In your example, the div's height is static and the image's height is static. Give the image a margin-top value of ( div_height - image_height ) / 2

If the image is 50px, then

img {
    margin-top: 25px;
}
mwcz
  • 8,949
  • 10
  • 42
  • 63
0

Have you tried setting margin on the div? e.g.

div {
    padding: 25px, 0
}

for top and bottom. You may also be able to use a percentage:

div {
    padding: 25%, 0
}
Keith Bloom
  • 2,391
  • 3
  • 18
  • 30
0
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
(function ($) {

$.fn.verticalAlign = function() {
    return this.each(function(i){
    var ah = $(this).height();
    var ph = $(this).parent().height();
    var mh = Math.ceil((ph-ah)/2);
    $(this).css('margin-top', mh);
    });
};
})(jQuery);

$(document).ready(function(e) {


$('.in').verticalAlign();


});

</script>

<style type="text/css">
body { margin:0; padding:0;}
.divWrap { width:100%;}
.out { width:500px; height:500px; background:#000; text-align:center; padding:1px; }
.in { width:100px; height:100px; background:#CCC; margin:0 auto; }
</style>
</head>

<body>
<div class="divWrap">
<div class="out">
<div class="in">
</div>
</div>
</div>

</body>
</html>
0

If you want content to be what ever you need to have inside a div, this did the job for me:

<div style="
  display: table-cell;
  vertical-align: middle;
  background-color: blue;
  width: ...px;
  height: ...px;
">
    <div style="
      margin: auto;
      display: block;
      width: fit-content;
    ">
        <!-- CONTENT -->
        <img src="...">
        <p> some text </p>
    </div>
 </div>
Arttu Pakarinen
  • 101
  • 1
  • 4