I have the following code which sets up a container which has a height that changes with the width when the browser is re-sized (to maintain a square aspect ratio).
HTML
<div class="responsive-container">
<div class="dummy"></div>
<div class="img-container">
<IMG HERE>
</div>
</div>
CSS
.responsive-container {
position: relative;
width: 100%;
border: 1px solid black;
}
.dummy {
padding-top: 100%; /* forces 1:1 aspect ratio */
}
.img-container {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
How can I vertically align the IMG inside the container? All my images have variable heights and the container can't have a fixed height/line height because it's responsive... Please help!
All you need is a div with display: table; and within it, a div with display: table-cell; and vertical-align: middle; . Just give the parent div a height and you'll have perfectly entered content. Look at me being all vertically aligned!
To center an image vertically, you can wrap it in a block element like a div and use a combination of the CSS position property, the left and top properties, and the transform property.
The CSS vertical align property works smoothly with tables, but not with divs or any other elements. When you use it in a div, it aligns the element alongside the other divs and not the content — which is what we usually want). This only works with display: inline-block; .
Here is a technique to align inline elements inside a parent, horizontally and vertically at the same time:
1) In this approach, we create an inline-block
(pseudo-)element as the first (or last) child of the parent, and set its height
property to 100%
to take all the height of its parent.
2) Also, adding vertical-align: middle
keeps the inline(-block) elements at the middle of the line space. So, we add that CSS declaration to the first-child and our element (the image) both.
3) Finally, in order to remove the white space character between inline(-block) elements, we could set the font size of the parent to zero by font-size: 0;
.
Note: I used Nicolas Gallagher's image replacement technique in the following.
There's no need to specify the dimensions of the image element explicitly.
We can easily use this approach to align a <div>
element vertically as well; which may have a dynamic content (height and/or width). But note that you have to re-set the font-size
property of the div
to display the inside text. Online Demo.
<div class="container">
<div id="element"> ... </div>
</div>
.container {
height: 300px;
text-align: center; /* align the inline(-block) elements horizontally */
font: 0/0 a; /* remove the gap between inline(-block) elements */
}
.container:before { /* create a full-height inline block pseudo=element */
content: ' ';
display: inline-block;
vertical-align: middle; /* vertical alignment of the inline element */
height: 100%;
}
#element {
display: inline-block;
vertical-align: middle; /* vertical alignment of the inline element */
font: 16px/1 Arial sans-serif; /* <-- reset the font property */
}
This section is not going to answer the question as the OP already knows how to create a responsive container. However, I'll explain how it works.
In order to make the height of a container element changes with its width (respecting the aspect ratio), we could use a percentage value for top/bottom padding
property.
A percentage value on top/bottom padding or margins is relative to the width of the containing block.
For instance:
.responsive-container {
width: 60%;
padding-top: 60%; /* 1:1 Height is the same as the width */
padding-top: 100%; /* width:height = 60:100 or 3:5 */
padding-top: 45%; /* = 60% * 3/4 , width:height = 4:3 */
padding-top: 33.75%; /* = 60% * 9/16, width:height = 16:9 */
}
Here is the Online Demo. Comment out the lines from the bottom and resize the panel to see the effect.
Also, we could apply the padding
property to a dummy child or :before
/:after
pseudo-element to achieve the same result. But note that in this case, the percentage value on padding
is relative to the width of the .responsive-container
itself.
<div class="responsive-container">
<div class="dummy"></div>
</div>
.responsive-container { width: 60%; }
.responsive-container .dummy {
padding-top: 100%; /* 1:1 square */
padding-top: 75%; /* w:h = 4:3 */
padding-top: 56.25%; /* w:h = 16:9 */
}
Demo #1.
Demo #2 (Using :after
pseudo-element)
Using padding-top
property causes a huge space at the top or bottom of the content, inside the container.
In order to fix that, we have wrap the content by a wrapper element, remove that element from document normal flow by using absolute positioning, and finally expand the wrapper (bu using top
, right
, bottom
and left
properties) to fill the entire space of its parent, the container.
Here we go:
.responsive-container {
width: 60%;
position: relative;
}
.responsive-container .wrapper {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
}
Here is the Online Demo.
<div class="responsive-container">
<div class="dummy"></div>
<div class="img-container">
<img src="http://placehold.it/150x150" alt="">
</div>
</div>
.img-container {
text-align:center; /* Align center inline elements */
font: 0/0 a; /* Hide the characters like spaces */
}
.img-container:before {
content: ' ';
display: inline-block;
vertical-align: middle;
height: 100%;
}
.img-container img {
vertical-align: middle;
display: inline-block;
}
Here is the WORKING DEMO.
Obviously, you could avoid using ::before
pseudo-element for browser compatibility, and create an element as the first child of the .img-container
:
<div class="img-container">
<div class="centerer"></div>
<img src="http://placehold.it/150x150" alt="">
</div>
.img-container .centerer {
display: inline-block;
vertical-align: middle;
height: 100%;
}
UPDATED DEMO.
max-*
propertiesIn order to keep the image inside of the box in lower width, you could set max-height
and max-width
property on the image:
.img-container img {
vertical-align: middle;
display: inline-block;
max-height: 100%; /* <-- Set maximum height to 100% of its parent */
max-width: 100%; /* <-- Set maximum width to 100% of its parent */
}
Here is the UPDATED DEMO.
With flexbox this is easy:
FIDDLE
Just add the following to the image container:
.img-container {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex; /* add */
justify-content: center; /* add to align horizontal */
align-items: center; /* add to align vertical */
}
Use this css, as you already have the markup for it:
.img-container {
position: absolute;
top: 50%;
left: 50%;
}
.img-container > img {
margin-top:-50%;
margin-left:-50%;
}
Here is a working JsBin: http://jsbin.com/ihilUnI/1/edit
This solution only works for square images (because a percentage margin-top value depends on the width of the container, not the height). For random-size images, you can do the following:
.img-container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); /* add browser-prefixes */
}
Working JsBin solution: http://jsbin.com/ihilUnI/2/edit
You can center an image, both horizontally and vertically, using margin: auto
and absolute positioning. Also:
.responsive-container {
margin: 1em auto;
min-width: 200px; /* cap container min width */
max-width: 500px; /* cap container max width */
position: relative;
overflow: hidden; /* crop if image is larger than container */
background-color: #CCC;
}
.responsive-container:before {
content: ""; /* using pseudo element for 1:1 ratio */
display: block;
padding-top: 100%;
}
.responsive-container img {
position: absolute;
top: -999px; /* use sufficiently large number */
bottom: -999px;
left: -999px;
right: -999px;
margin: auto; /* center horizontally and vertically */
}
<p>Note: images are center-cropped on <400px screen width.
<br>Open full page demo and resize browser.</p>
<div class="responsive-container">
<img src="http://lorempixel.com/400/400/sports/9/">
</div>
<div class="responsive-container">
<img src="http://lorempixel.com/400/200/sports/8/">
</div>
<div class="responsive-container">
<img src="http://lorempixel.com/200/400/sports/7/">
</div>
<div class="responsive-container">
<img src="http://lorempixel.com/200/200/sports/6/">
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With