How to vertically align an image inside a div
Matthew Martinez
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> <img src="" />
</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="" height=250 />
</div>
<div class=frame> <img src="" height=25 />
</div>
<div class=frame> <img src="" height=23 />
</div>
<div class=frame> <img src="" height=21 />
</div>
<div class=frame> <img src="" height=19 />
</div>
<div class=frame> <img src="" height=17 />
</div>
<div class=frame> <img src="" height=15 /> </div>
<div class=frame> <img src="" height=13 /> </div>
<div class=frame> <img src="" height=11 /> </div>
<div class=frame> <img src="" height=9 /> </div>
<div class=frame> <img src="" height=7 /> </div>
<div class=frame> <img src="" height=5 /> </div>
<div class=frame> <img src="" height=3 /> </div> 4 37 Answers
12 NextThe 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:
.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> <span></span><img src="" height=250px />
</div>
<div> <span></span><img src="" height=25px />
</div>
<div> <span></span><img src="" height=23px />
</div>
<div> <span></span><img src="" height=21px />
</div>
<div> <span></span><img src="" height=19px />
</div>
<div> <span></span> <img src="" height=17px />
</div>
<div> <span></span> <img src="" height=15px />
</div>
<div> <span></span> <img src="" height=13px />
</div>
<div> <span></span> <img src="" height=11px />
</div>
<div> <span></span> <img src="" height=9px />
</div>
<div> <span></span> <img src="" height=7px />
</div>
<div> <span></span> <img src="" height=5px />
</div>
<div> <span></span> <img src="" 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:
.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></span>'); t.runtimeStyle.behavior = 'none'; }(this) );
}<div><img src="" height=250px /></div>
<div><img src="" height=25px /></div>
<div><img src="" height=23px /></div>
<div><img src="" height=21px /></div>
<div><img src="" height=19px /></div>
<div><img src="" height=17px /></div>
<div><img src="" height=15px /></div>
<div><img src="" height=13px /></div>
<div><img src="" height=11px /></div>
<div><img src="" height=9px /></div>
<div><img src="" height=7px /></div>
<div><img src="" height=5px /></div>
<div><img src="" height=3px /></div>How it works:
When you have two
inline-blockelements near each other, you can align each to other's side, so withvertical-align: middleyou'll get something like this:When you have a block with fixed height (in
px,emor another absolute unit), you can set the height of inner blocks in%.- So, adding one
inline-blockwithheight: 100%in a block with fixed height would align anotherinline-blockelement in it (<img/>in your case) vertically near it.
This might be useful:
div { position: relative; width: 200px; height: 200px;
}
img { position: absolute; top: 0; bottom: 0; margin: auto;
}
.image { min-height: 50px
} 2 matejkramny's solution is a good start, but oversized images have a wrong ratio.
Here's my fork:
Demo:
HTML:
<div> <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;
} 1 A three-line solution:
position: relative;
top: 50%;
transform: translateY(-50%);This applies to anything.
From here.
2A 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="" height=250 />
</div>
<div class=frame> <img src="" height=25 />
</div>
<div class=frame> <img src="" height=23 />
</div>
<div class=frame> <img src="" height=21 />
</div>
<div class=frame> <img src="" height=19 />
</div>
<div class=frame> <img src="" height=17 />
</div>
<div class=frame> <img src="" height=15 />
</div>
<div class=frame> <img src="" height=13 />
</div>
<div class=frame> <img src="" height=11 />
</div>
<div class=frame> <img src="" height=9 />
</div>
<div class=frame> <img src="" height=7 />
</div>
<div class=frame> <img src="" height=5 />
</div>
<div class=frame> <img src="" 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 0 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> <img src="">
</div>Here's a Pen using Flexbox:
EDIT 1/13/22
There's a better way to do this using CSS Grid and the place-content shorthand:
.frame-text-grid { display: grid; place-content: center; /** ✪ "place-content" is the shorthand for "align-content" and "justify-content". ✪ The "place-content" shorthand requires two values, the first one is for "align-content" and the second one for "justify-content". If only one value is present (like in this demo), then that single value is applied to both directions. ✪ Comment the "place-content: center;" declaration above to see how the elements are spread along the height of the container. **/
}<div> <h2>Using Grid and <code>place-content</code></h2> <p>Only two lines are needed to center vertically and horizontally.</p>
</div>Here's a Pen using CSS Grid:
0This 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;
} 0 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> <img src="" />
</div> 1 There is a super easy solution with flexbox!
.frame { display: flex; align-items: center;
} 3 Imagine you have
<div> <img src="#">
</div>And css:
.wrap { display: flex;
}
.wrap img { object-fit: contain;
} 0 You could try setting the CSS of PI to display: table-cell; vertical-align: middle;
You can try the below code:
.frame{ display: flex; justify-content: center; align-items: center; width: 100%;
}<div> <img src="" />
</div> 0 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> <img src="" /> <img src="" /> <img src="" />
</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> <img src="" /> <img src="" /> <img src="" />
</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.
Background image solution
I removed the image element altogether and set it as background of the div with a class of .frame
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.
0.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");
} 0 You could do this:
Demo
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";
}) 5 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.
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> <div> <h1>Peace in the world</h1> </div>
</div>Personally I actually disagree about use helpers for this purpose.
My solution:
<div> <div> <img src="" 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;
} Try this solution with pure CSS
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:
Check this example about line-height different in different browsers: input height differences in Firefox and Chrome
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;
} 2 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.
0For centering an image inside a container (it could be a logo) besides some text like this:
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> <div> some text <img src=""> </div>
</div> 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.
Now it's not centered any more in Opera…
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> <img>
</div> 1 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; } 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> <div> <p>Centre me please!!!</p> </div> <div> <img src="" /> </div>
</div> 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> <br /> <img src=""> <h2>Text aligned after image inside a div by negative manipulate the img position</h2>
</div> 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.
<div class='container'> <img src='image.jpg' />
</div>
.container { padding: 20%; background-color: blue;
}
img { width: 100%;
} 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;
}
12 Next