Vertically center image when image is higher than container - html

I have a responsive design with a header image which is placed in a container. The image has width:100%; and height:auto; so it grows as you enlarge the viewport. I don't want to exceed a certain height so the container has a max-height. The image still grows but now the bottom part is cut off now because it aligns to the top of the container.
I would like the image to stay vertically centered in it's container so that parts of the image are cut off at the top and at the bottom. The outcome should look like this:
The header images are uploaded by users so they might have different heights therefore I cannot work with specific pixel-values. Is there a CSS-solution for this or do I have to use JavaScript?
Here is the code:
.wrapper {
width: 90%;
max-width: 600px;
margin: 1em auto;
background-color: #E9ADAD;
}
.container {
text-align: center;
height: auto;
line-height: 200px;
max-height: 200px;
overflow: hidden;
}
img {
width: 100%;
height: auto !important;
vertical-align: middle;
}
<div class="wrapper">
<div class="container">
<img src="http://placehold.it/600x300/C00000/FFFFFF&text=Image+vertically+centered">
</div>
</div>
And I prepared a fiddle.

You can use absolute positioning for your image , negative top/bottom values and margin:auto; to verticaly center the image in the container :
.wrapper {
width: 90%;
max-width: 600px;
margin: 1em auto;
background-color: #E9ADAD;
max-height: 200px;
}
.container {
position:relative;
padding-bottom:40%;
overflow: hidden;
}
img {
position:absolute;
top:-50%; bottom:-50%;
margin:auto;
width: 100%;
height: auto;
}
<div class="wrapper">
<div class="container">
<img src="http://placehold.it/600x300/C00000/FFFFFF&text=Image+vertically+centered">
</div>
</div>

Not so long ago there was only a javascript way to do this but now we have some css rules: object-fit and object-position
They work just like the background-size rules cover and contain:
.container img{
width: 100%;
height: auto;
}
#supports(object-fit: cover){
.container img{
height: 100%;
object-fit: cover;
object-position: center center;
}
}
The problem with this approach is that is very new and doesn't work on ie or Edge yet.
Pen here: http://codepen.io/vandervals/pen/MwKKrm
EDIT: Please, see that you need to declare the width and the height of the image, or it won't work.

.wrapper {
width: 90%;
max-width: 600px;
margin: 1em auto;
}
.container {
height: 200px;
overflow: hidden;
}
.imgWrapper {
position: relative;
width: 200%;
height: 200%;
top: -50%;
left: -50%;
}
img {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
height: auto;
width: 50%;
}
<div class="wrapper">
<div class="container">
<div class="imgWrapper"><img src="http://placehold.it/600x300"></div>
</div>
</div>
http://jsfiddle.net/ghygpw8t/5/
inspired by: https://css-tricks.com/perfect-full-page-background-image/

Try like this: Demo
If image size is small it will be arranged in vertical middle and if its big, it will fit in box.
CSS:
.wrapper {
width: 90%;
max-width: 600px;
margin: 1em auto;
}
.container {
text-align: center;
line-height: 200px;
overflow: hidden;
background-color:#ccc;
vertical-align:middle;
height: 200px;
border:2px solid green;
display: flex;
width: 100%;
align-items: center;
justify-content: center;
}
img {
width: 100%;
max-height: 196px;
border:2px solid red;
vertical-align: middle;
line-height: 196px;
}
Hope this is what you want!

On the element you want centered.
.element {
position: relative;
top: 50%;
transform: translateY(-50%);
}
on its parent.
.parent { transform-style: preserve-3d; }
Use a polyfill to render cross browser styles.

Related

Image not centered when larger than viewport

When the viewport is larger than the width of the image, the image is centered, but when the width of the image is larger than the width of the viewport, the image is aligned to the left rather than to the center. The effect I am aiming for is for the image to always be cropped to the width of the viewport and always be aligned to the center.
body,
html {
margin: 0;
padding: 0;
}
.crop {
width: 100%;
height: 50%;
overflow: hidden;
background-color: red;
}
#cropped-img {
position: relative;
height: 100%;
display: block;
margin: auto;
}
<div class="crop">
<img id="cropped-img" src="http://img1.jurko.net/wall/paper/donald_duck_4.jpg" />
</div>
You can achieve what you want with flexbox:
body,
html {
margin: 0;
padding: 0;
}
.crop {
overflow: hidden;
background-color: red;
display:flex;
justify-content:center;
}
<div class="crop">
<img id="cropped-img" src="http://img1.jurko.net/wall/paper/donald_duck_4.jpg" >
</div>
Nevermind, I managed to get the exact effect I needed using the background-image property. Here is the HTML and CSS I used if anyone else is interested:
HTML:
<div class="crop"></div>
CSS:
body, html {
margin:0;
padding:0;
}
.crop {
width: 100%;
height: 500px;
overflow: hidden;
background-image: url("http://img1.jurko.net/wall/paper/donald_duck_4.jpg");
background-repeat: no-repeat;
background-position: center;
}
Try giving variable values ​​the image that occupy 100% of width of the element
body,
html {
margin: 0;
padding: 0;
}
.crop {
width: 100%;
height: 50%;
overflow: hidden;
background-color: red;
text-align: center;
}
#cropped-img {
position: relative;
height: 100%;
width: 100%;
max-width: 100%;
display: block;
margin: 0 auto;
}
<div class="crop">
<img id="cropped-img" src="http://img1.jurko.net/wall/paper/donald_duck_4.jpg" />
</div>

Is it possible to make an image as small as possible while still filling its container, and keeping its aspect ratio?

I have a container of a given size, and I have an image inside it. I want the image to expand to either 100% height or 100% width, depending on whichever comes last, and I want it to keep its aspect ratio, so anything sticking on over the container is cropped off. If it's cropped on the sides, I'd also like it to be centered.
So to be clear, if it's a very wide picture, it would have height: 100%, and if it's a very tall picture, it would have width: 100%.
For example, here's the container and the image, with is neither sized correctly, nor centered:
https://jsfiddle.net/y5px1ch9/1/
<div class="wrapper">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f1/S%C3%A4ugende_H%C3%BCndin.JPG/800px-S%C3%A4ugende_H%C3%BCndin.JPG" class="picture">
</div>
.wrapper {
position: relative;
left: 40%;
width: 100px;
height: 200px;
border: 1px black solid;
overflow: hidden;
text-align: center;
}
.picture {
position: relative;
min-height: 100%;
min-width: 100%;
height: auto;
width: auto;
margin: auto;
left: 0;
right: 0;
background-position: center;
}
Anyone know if this is possible to do with CSS?
Since you have a fixed size wrapper, and as object-fit does not have that good browser support, I suggest you use background/background-size on the wrapper
Now, by setting its position, you control where it should get cropped. In below sample I used left top, which means it crops at right/bottom, and in your case, you might want center center, which will crop equally top/bottom or left/right, based on which of the two overflows.
Updated based on a comment
One can also set the image source in the markup, just how one do with the img, here done by setting background-image: url() inline.
.wrapper {
position: relative;
left: 40%;
width: 100px;
height: 200px;
border: 1px black solid;
overflow: hidden;
text-align: center;
background-repeat: no-repeat;
background-position: left top;
background-size: cover;
}
<div class="wrapper" style="background-image: url(https://upload.wikimedia.org/wikipedia/commons/thumb/f/f1/S%C3%A4ugende_H%C3%BCndin.JPG/800px-S%C3%A4ugende_H%C3%BCndin.JPG)">
</div>
And here is the version using object-fit
.wrapper {
position: relative;
left: 40%;
width: 100px;
height: 200px;
border: 1px black solid;
overflow: hidden;
text-align: center;
}
.picture {
position: relative;
height: 100%;
width: 100%;
object-fit: cover;
object-position: left top;
}
<div class="wrapper">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f1/S%C3%A4ugende_H%C3%BCndin.JPG/800px-S%C3%A4ugende_H%C3%BCndin.JPG" class="picture">
</div>
It is possible but you have to know the aspect ratio beforehand, knowing this you can reserve space for the image
div {
width: 100%;
overflow:hidden;
position:relative;
}
div::after {
padding-top: 56.25%; /* percentage of containing block _width_ */
display: block;
content: '';
}
div img {
display: block;
width:100%;
height:auto;
position: absolute;
top: -9999px;
bottom: -9999px;
left: -9999px;
right: -9999px;
margin: auto;
}
<div>
<img src="https://placehold.it/200x300"/>
</div>
The main trick is the padding-top: 56.25%;... the aspect ratio
If you define the image as a background-image, then you can use background-size: contain - this does what you want:
.wrapper {
position: relative;
left: 40%;
width: 100px;
height: 200px;
border: 1px black solid;
background: url(https://upload.wikimedia.org/wikipedia/commons/thumb/f/f1/S%C3%A4ugende_H%C3%BCndin.JPG/800px-S%C3%A4ugende_H%C3%BCndin.JPG) no-repeat center center;
background-size: contain;
}
<div class="wrapper">
</div>
try this
vertical
.picture {
position: relative;
height: 100%;
width: auto;
margin: auto;
left: 0;
right: 0;
background-position: center;
}
horizontal
.picture {
position: relative;
width: 100%;
height: auto;
margin: auto;
left: 0;
right: 0;
background-position: center;
}
jsfiddle horizontal case
jsfiddle vertical case
please add height property auto and image width in percentage %, in this property you can manage aspect ratio,
width:50%,
height:auto,

Firefox bug: image does not scale down?

Is this a bug in firefox?
CSS,
html, body {
height: 100%;
margin: 0;
padding: 0 0;
/*border: 4px solid black;*/
}
.container-fluid {
height: 100%;
width: 100%;
display: table;
padding-right: 0;
padding-left: 0;
/*border: 4px solid blue;*/
}
.row-fluid {
height: 100%;
width: 100%;
display: table-cell;
vertical-align: middle;
background-color:#990000;
/*border: 4px solid red;*/
}
.img-container {
height: 100vh;
width: 100%;
display: flex;
align-items: center;
}
.img-container img{
max-width:100%;
max-height:100%;
margin-left: auto;
margin-right: auto;
}
HTML,
<div class="container-fluid">
<div class="row-fluid">
<div class="img-container">
<!-- <img src="http://placehold.it/400x450"> -->
<img src="http://placehold.it/2000x450">
<!-- <img src="http://placehold.it/400x480"> -->
</div>
</div>
</div>
Chrome,
The large image will be scaled down to fit the screen width which is what I want.
Firefox,
The image is not scaled down to fit the screen.
Any ideas how I can fix this?
EDIT:
#-moz-document url-prefix() {
.img-container img {
width: 100%;
max-width: -moz-max-content;
}
}
Since you are using CSS table for the layout already, I'm suggesting this approach without flexbox. It works nicely on Chrome and Firefox according to my tests. I added a div around the img.
jsFiddle
body { margin:0; }
.img-container {
display: table;
table-layout: fixed; /*required for responsive width in Firefox*/
width: 100%; /*required for fixed table layout*/
}
.img-container .image {
display: table-cell;
text-align: center;
vertical-align: middle;
height: 100vh; /*required for responsive height*/
}
.img-container .image img {
max-width: 100%;
max-height: 100%;
vertical-align: middle; /*remove whitespace*/
}
<div class="img-container">
<div class="image">
<img src="http://placehold.it/400x300">
<!-- <img src="http://placehold.it/2000x450"> -->
<!-- <img src="http://placehold.it/400x480"> -->
</div>
</div>
Alternatively, you can use pseudo element :before or :after + inline block for vertical alignment. No markup change is required.
jsFiddle
body { margin:0; }
.img-container {
width: 100vw; /*required for responsive width in Firefox*/
height: 100vh;
text-align: center;
font-size: 0; /*remove whitespace*/
}
.img-container:after {
content: "";
display: inline-block;
height: 100%;
vertical-align: middle;
}
.img-container img {
max-width: 100%;
max-height: 100%;
vertical-align: middle;
}
<div class="img-container">
<img src="http://placehold.it/400x300">
<!-- <img src="http://placehold.it/2000x450"> -->
<!-- <img src="http://placehold.it/400x480"> -->
</div>
Yes there is problem in firefox. It will not maintaining aspect ratio. To make it working just add width: 100%; to image will solve issue.
.img-container img {
margin-left: auto;
margin-right: auto;
max-height: 100%;
max-width: 100%;
width: 100%;
}
Working Fiddle
Check same type of issue here.
Edit:
To solve issue for all size image use max-width: -moz-max-content;
#-moz-document url-prefix() {
.img-container img { width: 100%; max-width: -moz-max-content; }
}
Updated Fiddle
Based on a bug report (see below), this is a known issue with Firefox. (Although IE11 also fails to scale the image as desired).
This seems to solve the problem in Firefox:
Instead of:
.img-container img {
max-width: 100%;
max-height: 100%;
margin-left: auto;
margin-right: auto;
}
Try this:
.img-container img {
width: 100%; /* adjusted */
height: auto; /* adjusted */
margin-left: auto;
margin-right: auto;
}
DEMO
Another possible solution involves adding table-layout: fixed to the main container (.container-fluid). This method is detailed in this bug report:
Bug 975632 - max-width: 100%; doesn't work inside tables or display: table

How to make this inner div vertically centered? (Using CSS)

There are two divs. I want the inner div to be vertically centered, without giving margins, as I want height of inner div to be auto, because its content can change and height can increase.
Here are the two divs:
Outer div:
.frontleft{
width: 602px;
height: 450px;
float: left;
margin: 35px auto;
z-index: 10;
}
Inner div:
.c1{
height: auto;
width: inherit;
}
Thanks.
You can use Flexbox. display: flex on parent and align-self: center on the child item will center it vertically.
.frontleft {
width: 602px;
height: 450px;
float: left;
margin: 35px auto;
z-index: 10;
background: #2C2955;
display: flex;
}
.c1 {
height: auto;
width: inherit;
background: #4C5FB1;
align-self: center;
}
<div class="frontleft">
<div class="c1">Center</div>
</div>
Why don't you use a table instead? With vertical-align in td tag.
<html>
<body>
<table class="frontleft">
<tr><td>I am a sentence</td></tr>
</table>
</body>
</html>
You should position inner element absolute and use transform property for vertical centering.
.frontleft {
width: 602px;
height: 450px;
float: left;
margin: 35px auto;
z-index: 10;
position: relative;
background: orange;
}
.c1 {
height: auto;
width: inherit;
position: absolute;
top: 50%;
transform: translateY(-50%);
background: blue;
}
<div class="frontleft">
<div class="c1">test</div>
</div>

position absolute with height 100%

I am having a problem with displaying a div. For some reason it is not displaying the inner div.
The position of parent div is relative where as the child div is absolute.
Here is the demo http://jsfiddle.net/squidraj/6R3Hr/6/
HTML Code :
<div class="page-center">
<div class="question_slide inidfeedback">Test</div>
</div>
CSS Code :
.question_slide {
background: #000000;
height: 569px;
width:100%
}
.question_slide {
overflow: hidden;
position: absolute;
top: 0;
width: 100%;
}
.page-center {
margin: 0 auto;
max-width: 1100px;
overflow: hidden;
position: relative;
text-align: center;
width: 100%;
}
Just interchange their positions.
.question_slide {
overflow: hidden;
position: relative;
top: 0;
width: 100%;
}
.page-center {
margin: 0 auto;
max-width: 1100px;
overflow: hidden;
position: absolute;
text-align: center;
width: 100%;
}
Here is a demo:http://jsfiddle.net/6R3Hr/3/
Give it a height style. Since the only content is relatively positioned, it doesn't have any inherent height value and because the overflow is hidden, it's not onscreen.
http://jsfiddle.net/squidraj/6R3Hr/2/
.page-center {
margin: 0 auto;
max-width: 1100px;
overflow: hidden;
position: relative;
text-align: center;
width: 100%;
height:20px;
}
Edit:
If overflow:hidden is a must, then you must specify a height for your relative div:
.page-center {
margin: 0 auto;
max-width: 1100px;
position: relative;
text-align: center;
width: 100%;
overflow:hidden;
height:100px;
}
Just choose how much height will work for you.
Here's a working jsfiddle with your code.