Images in a flexbox doesn't scale properly - html

I put 2 images inside a flexbox with column direction and I want images to resize when I resize a browser window. They don't change as I expect.
I want images to change in their original ratio, but no matter what css style I use it fails.
It works fine when I resize a window horizontally buy not when I resize it vertically.
Additionally images go outside of the flexbox div, how can I prevent it?
#box{
width: 100%;
height: 100%;
}
#container {
display: flex;
flex-direction: column;
width: 50%;
height: 30%;
background-color: red;
}
#photo {
width: 100%;
height: auto;
}
<div id="box">
<div id="container">
<img id="photo" src="1.JPG">
<img id="photo" src="2.JPG">
</div>
</div>

One think i normally use in this scenarios is set the image as background image using css an use background-size:contain;
An example:
#box{
width: 100vw;
height: 100vh;
}
#container {
display: flex;
flex-direction: column;
width: 50%;
height: 30%;
background-color: red;
}
.photo {
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-size:contain;
}
<div id="box">
<div id="container">
<div class="photo" style="background-image: url('https://picsum.photos/200/300/?random')"></div>
<div class="photo" style="background-image: url('https://picsum.photos/300/200/?random')"></div>
</div>
</div>
https://jsfiddle.net/vbanj8st/

Related

Center fit images of any size to parent div

I've got an image slider, the selected image is set as the main image above. All the images are not same size. How do I make sure that each image is centered in the parent div and the entire parent div?
I'm now doing it with:
width: 100%;height: 100%;object-fit:fill;
but then my image loses the bottom of its content. I would like to center the image vertically.
My parent div has following class style:
.wrapper_image{
max-width:100%;
max-height:100%;
min-height:100%;
min-width: 100%;
margin: 0 auto;
}
code:
<div class="o-grid__col u-12/12" style="width: 400px;
height: 400px;
position: relative;
display: inline-block;
overflow: hidden;
text-align: center;
margin: 0;">
<div class="mySlides wrapper_image_horses">
<img src='url' style="width: 100%;height: 100%;object-fit:fill;">
</div>
</div>
I suggest you use display: flex; to achieve this. With flex it is much easier for you to align you images to center vertically and horizontally. Below is a test code I have done. Hope it helps with your problem
HTML
<div class="d-flex h-100">
<div class="img-slide">
<img src="https://via.placeholder.com/150">
</div>
</div>
CSS
.d-flex {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.h-100 {
height: -webkit-fill-available;
}
JS Fiddle Link : https://jsfiddle.net/SJ_KIllshot/y5fzvox8/
Here is a modern solution, hope it will help you
DEMO
<div class="o-grid__col u-12/12" style="width: 400px;
height: 400px;
position: relative;
display: inline-block;
overflow: hidden;
text-align: center;
margin: 0;
border: 1px solid #000;">
<div class="mySlides wrapper_image_horses" style="position: absolute;
top: 50%; left: 50%;
transform: translate(-50%,-50%);">
<img src='https://picsum.photos/id/159/200/200' style="width: auto;height: auto;">
</div>

Trying to get a bordered image to autofit a flexbox div

Scenario :
I am having trouble getting an image to autofit a flexbox with a border around it. The image will be dynamically generated so sometimes the width or the height might be the longer side. Sometimes the image will be smaller or larger than the box it should be in, but it should automatically fit the size of the box and retain its proper proportions.
Tried Case :
The best I've come up with is to set both width and height of the image to 100%, and then use object-fit: contain.
However, object-fit: contain does not work well with borders. Instead of surrounding just the image the border is surrounding the entire parent div.
The Problem: If there is a tall skinny image it might enlarge or shrink to 30% width and 100% height. I would like the border to be also at the 30% and 100% region as well. However, the border is being placed at the 100% width and 100% height area which is not what I want.
What other method would work better for me here?
Here is a simplified look at my code:
<!DOCTYPE html>
<html>
<style>
html, body { width: 100%; height: 100% }
#outer {
width: 100%;
height: 100%;
display: flex;
background-color: green;
flex-direction: column
}
#top, #bottom {
flex: 1;
display: flex;
border: solid black 1px;
}
#first, #third {
flex: 1;
background-color: blue;
}
#second {
flex: 3;
background-color: yellow;
}
#second img {
border: solid black 5px;
object-fit: contain;
width: 100%;
height: 100%;
box-sizing: border-box;
}
</style>
<body>
<div id="outer">
<div id="top">
<div id="first">First</div>
<div id="second">
<img src="https://via.placeholder.com/350x800/faa">
</div>
<div id="third">Third</div>
</div>
<div id="bottom">
Bottom
</div>
</div>
</body>
</html>
If you run the above code snippet you will see the thick border is surrounding the entire parent region (shown in yellow), rather than just appearing around the image itself (pink area).
What can I do so that the border is only around the image itself?
Clarification
I need something that meets the following criteria:
Smaller images are scaled up to meet the size of the parent div
Larger images are scaled down to meet the size of the parent div
Images should be proportional (i.e. images must retain their aspect ratio and not become distorted)
The image should be centered within the parent div
The image should have a border only around the image and not the larger area
Code must work for both portrait and landscape images
In most cases only two sides of the image will touch the parent boundary, leaving the rest of the parent div empty (i.e. the yellow background in my code sample)
I'm actually quite surprised given how far CSS has come that there seems to be no simple solution for this.
Do you want only with height 100%? If not height 100% is depend on image's prop, you can use object-fit: fill; and height:auto;
<!DOCTYPE html>
<html>
<style>
html, body { width: 100%; height: 100% }
#outer {
width: 100%;
height: 100%;
display: flex;
background-color: green;
flex-direction: column
}
#top, #bottom {
flex: 1;
display: flex;
border: solid black 1px;
}
#first, #third {
flex: 1;
background-color: blue;
}
#second {
flex: 3;
background-color: yellow;
}
#second img {
border: solid black 5px;
object-fit: contain;
width: 100%;
height: auto;
box-sizing: border-box;
}
</style>
<body>
<div id="outer">
<div id="top">
<div id="first">First</div>
<div id="second">
<img src="https://picsum.photos/800/800">
</div>
<div id="third">Third</div>
</div>
<div id="bottom">
Bottom
</div>
</div>
</body>
</html>
Used object-fit: cover
so that the image will cover the entire parent.
Other solution will be inserting an image already having a border on it.Image can be edited online to attach a border to itself.
<!DOCTYPE html>
<html>
<style>
html, body { width: 100%; height: 100% }
#outer {
width: 100%;
height: 100%;
display: flex;
background-color: green;
flex-direction: column
}
#top, #bottom {
flex: 1;
display: flex;
border: solid black 1px;
}
#first, #third {
flex: 1;
background-color: blue;
}
#second {
flex: 3;
background-color: yellow;
}
#second img {
border: solid black 5px;
object-fit: cover;
width: 100%;
height: 100%;
box-sizing: border-box;
}
</style>
<body>
<div id="outer">
<div id="top">
<div id="first">First</div>
<div id="second">
<img src="https://via.placeholder.com/350x800/faa">
</div>
<div id="third">Third</div>
</div>
<div id="bottom">
Bottom
</div>
</div>
</body>
</html>
Updated Solution:
So, to achieve this, we can put image inside a container that will be
take height and width according to image. Put this image container div inside the main div container.
So, in this case, we have put the following code into #second conatiner, and adjusted the corresponding css to achieve the desired result.
html, body { width: 100%; height: 100% }
img {
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
transform: translate(-50%, -50%);
position: relative;
left: 50%;
top: 50%;
}
#testing {
display: inline-block;
/* text-align: center; */
}
#outer {
width: 100%;
height: 100%;
display: flex;
background-color: green;
flex-direction: column
}
#top, #bottom {
flex: 1;
display: flex;
border: solid black 1px;
}
#first, #third {
flex: 1;
background-color: blue;
}
#second {
flex: 3;
background-color: yellow;
display: flex;
margin: 0 auto;
justify-content: center;
}
#second img {
border: solid black 5px;
object-fit: contain;
box-sizing: border-box;
}
<!DOCTYPE html>
<html>
<body>
<div id="outer">
<div id="top">
<div id="first">First</div>
<div id="second">
<div id='testing'>
<img src="https://via.placeholder.com/1000x350/faa">
</div>
</div>
<div id="third">Third</div>
</div>
<div id="bottom">
Bottom
</div>
</div>
<div id="outer">
<div id="top">
<div id="first">First</div>
<div id="second">
<div id='testing'>
<img src="https://via.placeholder.com/350x1000/faa">
</div>
</div>
<div id="third">Third</div>
</div>
<div id="bottom">
Bottom
</div>
</div>
</body>
</html>
did you mean something like this?
changes are, move width: 100% and height: 100% to parent, add max-height: 100% on img, and add text-align: center on parent
update:
- add another div inside #second
- make #second display: flex; flex-direction: column; justify-content: center
- add max-width: 100% to img
- add max-height: 100%; max-width: 100%; height: fit-content; to the added div
html, body { width: 100%; height: 100% }
#outer {
width: 100%;
height: 100%;
display: flex;
background-color: green;
flex-direction: column
}
#top, #bottom {
flex: 1;
display: flex;
border: solid black 1px;
}
#first, #third {
flex: 1;
background-color: blue;
}
#second {
flex: 3;
background-color: yellow;
width: 100%;
height: 100%;
text-align:center;
display: flex;
flex-direction: column;
justify-content: center;
}
#second img {
border: solid black 5px;
box-sizing: border-box;
max-height: 100%;
max-width: 100%;
}
#vcenter{
max-height: 100%;
max-width: 100%;
height: fit-content;
}
<!DOCTYPE html>
<html>
<body>
<div id="outer">
<div id="top">
<div id="first">First</div>
<div id="second">
<div id="vcenter">
<img src="https://via.placeholder.com/350x800/faa">
</div>
</div>
<div id="third">Third</div>
</div>
<div id="bottom">
Bottom
</div>
</div>
</body>
</html>
same code for landscape images
html, body { width: 100%; height: 100% }
#outer {
width: 100%;
height: 100%;
display: flex;
background-color: green;
flex-direction: column
}
#top, #bottom {
flex: 1;
display: flex;
border: solid black 1px;
}
#first, #third {
flex: 1;
background-color: blue;
}
#second {
flex: 3;
background-color: yellow;
width: 100%;
height: 100%;
text-align:center;
display: flex;
flex-direction: column;
justify-content: center;
}
#second img {
border: solid black 5px;
box-sizing: border-box;
max-height: 100%;
max-width: 100%;
}
#vcenter{
max-height: 100%;
max-width: 100%;
height: fit-content;
}
<!DOCTYPE html>
<html>
<body>
<div id="outer">
<div id="top">
<div id="first">First</div>
<div id="second">
<div id="vcenter">
<img src="https://via.placeholder.com/1350x200/faa">
</div>
</div>
<div id="third">Third</div>
</div>
<div id="bottom">
Bottom
</div>
</div>
</body>
</html>

CSS: Get inline image to use 100% of width and height of container

I am trying to find a solution without having to use background-image, but being able to use an inline <img>.
I would like to make it so that if the image container's dimensions are not the same as the image, the image will still fill the width and height of the container, cropping whatever part it has to.
Also, if a part of the image is smaller than the container, it will stretch over 100% to fill the container.
In the example below, I have a huge image that can easily fill the width and height of the container. The container is a different aspect ratio from the image, so I end up with blank space, either horizontally or vertically. I want to fill that container no matter what, even though part of the image will be cropped away.
class[*='container'] {
margin-bottom: 50px;
}
.container img {
width: 20%;
height: 20%;
}
.container-1 {
background: #f0f0f0;
width: 400px;
height: 150px;
}
.container-1 img {
object-fit: cover;
max-width: 100%;
max-height: 100%;
}
.container-2 {
background: #f0f0f0;
width: 150px;
height: 400px;
}
.container-2 img {
object-fit: cover;
max-width: 100%;
max-height: 100%;
}
<p>Original image:</p>
<div class="container">
<img src="https://themetry.com/wp-content/uploads/pug.jpg" />
</div>
<p>Container 1:</p>
<div class="container-1">
<img src="https://themetry.com/wp-content/uploads/pug.jpg" />
</div>
<p>Container 2:</p>
<div class="container-2">
<img src="https://themetry.com/wp-content/uploads/pug.jpg" />
</div>
.container-1 img {
object-fit: cover;
/* max-width: 100%; */
/* max-height: 100%; */
width: 100%;
height: 100%;
}
class[*='container'] {
margin-bottom: 50px;
}
.container img {
width: 20%;
height: 20%;
}
.container-1 {
background: #f0f0f0;
width: 400px;
height: 150px;
}
.container-1 img {
object-fit: cover;
width: 100%;
height: 100%;
}
.container-2 {
background: #f0f0f0;
width: 150px;
height: 400px;
}
.container-2 img {
object-fit: cover;
width: 100%;
height: 100%;
}
<p>Original image:</p>
<div class="container">
<img src="https://themetry.com/wp-content/uploads/pug.jpg" />
</div>
<p>Container 1:</p>
<div class="container-1">
<img src="https://themetry.com/wp-content/uploads/pug.jpg" />
</div>
<p>Container 2:</p>
<div class="container-2">
<img src="https://themetry.com/wp-content/uploads/pug.jpg" />
</div>
Since you're already using object-fit, I used it in my answer, as well. Just keep in mind it's not supported by IE / Edge. Here are some workarounds: https://stackoverflow.com/a/37127590/3597276

Make image take full height of flex item

I have a container that is 100vh (minus the fixed nav height).
<section class="container">
Inside this container I have some text:
<div class="text">
<p>title</p>
</div>
Which can be of any length as the content is dynamic.
Below this text I have an image:
<div class="image">
<img src="https://s-media-cache-ak0.pinimg.com/736x/d1/a6/64/d1a664bca214bf785a293cbc87950fc4.jpg">
</div>
The image needs to fill the rest of the 100vh (- nav height) container.
I use:
.container{
display:flex;
flex-flow: column nowrap;
....
Fiddle
The issue I am having is that I need the image to be the height of the rest of the space.
How can I do this? In my fiddle, if your screen is small it is being cut off and if your screen is large it does not fill the space. Height: 100% fails to work, making it too large.
Flex solutions only please, no table tricks - thanks!
Make the image container (.image) a flex container with height: 100%.
You can then fine-tune the image's aspect ratio and alignment with object-fit / object-position.
nav {
position:fixed;
background:grey;
width:100%;
height: 100px;
}
main {
padding-top: 100px;
}
.container {
display:flex;
flex-flow: column nowrap;
height: calc(100vh - 100px);
background: green;
border: 3px solid brown;
}
.text { background: yellow; }
/* ***** NEW ***** */
.image {
display: flex;
justify-content: center;
height: 100%;
}
img {
width: 100%;
object-fit: contain;
}
<nav>Nav</nav>
<main>
<section class="container">
<div class="text"><p>title</p></div>
<div class="image">
<img src="https://s-media-cache-ak0.pinimg.com/736x/d1/a6/64/d1a664bca214bf785a293cbc87950fc4.jpg">
</div>
</section>
<section class="container">
<div class="text"><p>hello</p></div>
<div class="image">
<img src="https://s-media-cache-ak0.pinimg.com/736x/d1/a6/64/d1a664bca214bf785a293cbc87950fc4.jpg">
</div>
</section>
</main>
Revised Fiddle
Note that the object-fit property is not supported by IE. For more details and a workaround see: https://stackoverflow.com/a/37127590/3597276
Maybe not exactly what you wanted, but if you move the image to a div and use it as a background, you can get the desired effect.
Fiddle
HTML:
Nav
title
<section class="container">
<div class="text">
<p>hello</p>
</div>
<div class="imageWrap">
<div class="image"></div>
</div>
</section>
</main>
CSS:
nav {
background: grey;
width: 100%;
height: 100px;
position: fixed;
}
main{
padding-top: 100px;
}
.container{
display: flex;
flex-flow: column nowrap;
height: calc(100vh - 100px);
background: green;
border: 3px solid brown;
}
.imageWrap {
flex: 1;
display: flex;
}
.image {
flex: 1;
background-size: contain;
background-repeat: no-repeat;
background-image: url(https://s-media-cache-ak0.pinimg.com/736x/d1/a6/64/d1a664bca214bf785a293cbc87950fc4.jpg)
}
.text{
background: yellow;
}

img in flexbox overflows at top and bottom

I have a problem with the flexbox. The image inside should fit into the outer box without overflow. The first and last works perfectly, but the second overflows at the top and the bottom.
How could I fix this?
.outer {
border: 1px solid red;
margin: 25px;
width: 160px;
height: 160px;
display: flex;
justify-content: center;
align-items: center;
}
.outer img {
max-width: 100%;
}
<div class="outer">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/72/16x9_by_Pengo.svg/220px-16x9_by_Pengo.svg.png" />
</div>
<div class="outer">
<img src="http://www.thepixiecollective.com/files/imagecache/product_full/product_images/blue.png" />
</div>
<div class="outer">
<img src="http://41.media.tumblr.com/fa335632f1b474dd55493757839d2a3a/tumblr_n0ukv5MLqG1qz5uc4o1_500.jpg" />
</div>
This is because the height of the second image is greater than the width. The width of the first and third images is either greater than or equal to the height so are constrained by max-width: 100%; which ensures they will never exceed the width of the parent container.
To fix make the following changes to css:
Add max-height: 100%; to .outer img - This will ensure the height of the image can never exceed the height of the container
.outer {
border: 1px solid red;
margin: 25px;
width: 160px;
height: 160px;
display: flex;
justify-content: center;
align-items: center;
}
.outer img {
max-height: 100%;
max-width: 100%;
}
<div class="outer">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/72/16x9_by_Pengo.svg/220px-16x9_by_Pengo.svg.png" />
</div>
<div class="outer">
<img src="http://www.thepixiecollective.com/files/imagecache/product_full/product_images/blue.png" />
</div>
<div class="outer">
<img src="http://41.media.tumblr.com/fa335632f1b474dd55493757839d2a3a/tumblr_n0ukv5MLqG1qz5uc4o1_500.jpg" />
</div>
You should insert your image in CSS, it's easier to have this behaviour.
.outer {
border: 1px solid red;
margin: 25px;
width: 160px;
height: 160px;
}
#pengo {
background-image: url('https://upload.wikimedia.org/wikipedia/commons/thumb/7/72/16x9_by_Pengo.svg/220px-16x9_by_Pengo.svg.png');
}
#blue {
background-image: url('http://www.thepixiecollective.com/files/imagecache/product_full/product_images/blue.png');
}
#tumblr {
background-image: url('http://41.media.tumblr.com/fa335632f1b474dd55493757839d2a3a/tumblr_n0ukv5MLqG1qz5uc4o1_500.jpg');
}
HTML
<div id="pengo" class="outer"></div>
<div id="blue" class="outer"></div>
<div id="tumblr" class="outer"></div>
Then play with background-position and background-size (see MDN) to do place the images, for example:
background-position: center;
background-size: cover; /* or contain*/