object-fit, object-positioning and absolute positioning - css

Whilst trying to make an image fit into a rectangle, I came across a weird problem and wondered if anyone knew why these three ways of using object fit act differently:
.container {
width: 250px;
padding-top: 20%;
border: 1px solid red;
position: relative;
display:inline-block
}
.container>img {
position: absolute;
top: 0;
left: 0;
object-fit: contain;
object-position: center center;
}
.image {
width: 100%;
height: 100%;
}
.image-1 {
right: 0;
bottom: 0;
}
.image-2 {
right: 0;
bottom: 0;
max-height: 100%;
max-width: 100%;
}
<div class="container">
<img src="https://www.fillmurray.com/200/300" class="image">
</div>
<div class="container">
<img src="https://www.fillmurray.com/200/300" class="image-1">
</div>
<div class="container">
<img src="https://www.fillmurray.com/200/300" class="image-2">
</div>
As you can see from the first image - everything works fine with a width and height. In the second image, I try to set the image so it fills the space with absolute positioning instead of width and height, but this is totally ignored and the image just overflows or stays it's original size.
To fix this, I use a max-width and height on the third image, but then this totally ignores the object-position and doesn't grow to a width or height larger than itself.
Why does object fit only work with a declared width and height and not if the image is just taking up space with coordinates and why does object-position not work with max-width and height?

The image is a replaced element so the use of top/left/right/bottom will not work like it will do with a non-replaced element (a simple div for example). Here is the relevant parts from the specification:
https://www.w3.org/TR/CSS2/visudet.html#abs-replaced-width
https://www.w3.org/TR/CSS2/visudet.html#abs-replaced-height
To make it easier the computed height/width of your image aren't defined by the top/bottom and right/left values but it's using the default one of the image thus there is no ratio distortion and object-fit will do nothing.
Use different value for bottom/right and you will see that they are ignored:
.container {
width: 250px;
padding-top: 20%;
border: 1px solid red;
position: relative;
display:inline-block
}
.container>img {
position: absolute;
top: 0;
left: 0;
object-fit: contain;
object-position: center center;
}
.image-1 {
right: 0;
bottom: 0;
}
<div class="container">
<img src="https://www.fillmurray.com/100/200" class="image-1" >
</div>
<div class="container">
<img src="https://www.fillmurray.com/100/200" class="image-1" style="right:100px;bottom:10000px">
</div>
<div class="container">
<img src="https://www.fillmurray.com/100/200" class="image-1" style="right:-10px;bottom:-10000px">
</div>
<div class="container">
<img src="https://www.fillmurray.com/100/200" class="image-1" style="right:-100px;bottom:50%">
</div>
Basically the top/left are simply adjusting the position and the intrinsic size of the image are used. If you explicitely specify the width/height or you add max-width/max-height constraint then you will be able to change the computed height/width like you already did.
Related question where the same happen with an input element: Width of absolute positioned input doesn't follow CSS rules
In your situation object-fit is only working for the first case where we have ratio distortion since you set height:100% and width:100%. Nothing will happen on the second case (like explained above) and also for the third case since you simply defined max-height/max-width thus the image will simply follow this constraint and will try to keep it's initial ratio.
In other words, object-fit will only work if you change the width AND the height AND this change break the initial ratio. Changing only one of them or none of them make the use of object-fit useless.
Related questions:
CSS object-fit: contain; is keeping original image width in layout
How does object-fit work with canvas element?

Related

Having issues with images overlapping using CSS

Initially, I had this formatted the way that I wanted. After adding and removing code over the last few hours, I'm unsure of what revision that I made that prevents me from separating the individual images. They're supposed to be side-by-side with about 5em in between.
HTML —
<div class="techStackContainer02">
<div class="techImg">
<img class="techImg" src="client image.svg" alt="client">
<img class="techImg" src="server image.svg" alt="server">
<img class="techImg" src="database.svg" alt="database">
</div>
CSS —
.techStackContainer02 {
display: grid;
gap: 5em;
height: 15vh;
max-width: 100%;
position: relative;
width: auto;
}
.techImg {
height: 180px;
position: absolute;
width: 80%;
}
Preview of Issue
I've tried using a few resources online but majority of them just discuss positioning attributes (sticky, absolute, fixed, etc.). Using the relative position for my parent container and absolute for my images has them at least placed in a singular row. Everything is sized properly minus the aforementioned overlapping issues.
When you specify position: absolute; you have to specify the exact position you want for each element.
In this case, they are naturaly overlapping because their positions are determined by the values of top, right, bottom, and left. since you didn't specify any they are in the exact same position.
You can just remove your position: absolute in your .techImg css class and they will not overlap anymore. Maybe you have to adjust you width to get every images on the same lines.
Here is an example with random images :
.techStackContainer02 {
display: grid;
gap: 5em;
height: 15vh;
max-width: 100%;
width: auto;
}
.techImg {
height: 180px;
width: auto;
}
<div class="techStackContainer02">
<div class="techImg"> <!-- problem here -->
<img class="techImg" src="https://picsum.photos/50" alt="client">
<img class="techImg" src="https://picsum.photos/50" alt="server">
<img class="techImg" src="https://picsum.photos/50" alt="database">
</div>
EDIT : i juste realize the code you posted got 1 additional div with the techImg class aswell. Maybe you have to use another class name if you don't want to have strange effects.

CSS position: absolute; and inset: 0; has zero effect on image element [duplicate]

Whilst trying to make an image fit into a rectangle, I came across a weird problem and wondered if anyone knew why these three ways of using object fit act differently:
.container {
width: 250px;
padding-top: 20%;
border: 1px solid red;
position: relative;
display:inline-block
}
.container>img {
position: absolute;
top: 0;
left: 0;
object-fit: contain;
object-position: center center;
}
.image {
width: 100%;
height: 100%;
}
.image-1 {
right: 0;
bottom: 0;
}
.image-2 {
right: 0;
bottom: 0;
max-height: 100%;
max-width: 100%;
}
<div class="container">
<img src="https://www.fillmurray.com/200/300" class="image">
</div>
<div class="container">
<img src="https://www.fillmurray.com/200/300" class="image-1">
</div>
<div class="container">
<img src="https://www.fillmurray.com/200/300" class="image-2">
</div>
As you can see from the first image - everything works fine with a width and height. In the second image, I try to set the image so it fills the space with absolute positioning instead of width and height, but this is totally ignored and the image just overflows or stays it's original size.
To fix this, I use a max-width and height on the third image, but then this totally ignores the object-position and doesn't grow to a width or height larger than itself.
Why does object fit only work with a declared width and height and not if the image is just taking up space with coordinates and why does object-position not work with max-width and height?
The image is a replaced element so the use of top/left/right/bottom will not work like it will do with a non-replaced element (a simple div for example). Here is the relevant parts from the specification:
https://www.w3.org/TR/CSS2/visudet.html#abs-replaced-width
https://www.w3.org/TR/CSS2/visudet.html#abs-replaced-height
To make it easier the computed height/width of your image aren't defined by the top/bottom and right/left values but it's using the default one of the image thus there is no ratio distortion and object-fit will do nothing.
Use different value for bottom/right and you will see that they are ignored:
.container {
width: 250px;
padding-top: 20%;
border: 1px solid red;
position: relative;
display:inline-block
}
.container>img {
position: absolute;
top: 0;
left: 0;
object-fit: contain;
object-position: center center;
}
.image-1 {
right: 0;
bottom: 0;
}
<div class="container">
<img src="https://www.fillmurray.com/100/200" class="image-1" >
</div>
<div class="container">
<img src="https://www.fillmurray.com/100/200" class="image-1" style="right:100px;bottom:10000px">
</div>
<div class="container">
<img src="https://www.fillmurray.com/100/200" class="image-1" style="right:-10px;bottom:-10000px">
</div>
<div class="container">
<img src="https://www.fillmurray.com/100/200" class="image-1" style="right:-100px;bottom:50%">
</div>
Basically the top/left are simply adjusting the position and the intrinsic size of the image are used. If you explicitely specify the width/height or you add max-width/max-height constraint then you will be able to change the computed height/width like you already did.
Related question where the same happen with an input element: Width of absolute positioned input doesn't follow CSS rules
In your situation object-fit is only working for the first case where we have ratio distortion since you set height:100% and width:100%. Nothing will happen on the second case (like explained above) and also for the third case since you simply defined max-height/max-width thus the image will simply follow this constraint and will try to keep it's initial ratio.
In other words, object-fit will only work if you change the width AND the height AND this change break the initial ratio. Changing only one of them or none of them make the use of object-fit useless.
Related questions:
CSS object-fit: contain; is keeping original image width in layout
How does object-fit work with canvas element?

Why absolutely positioned img cannot be auto stretched? [duplicate]

Whilst trying to make an image fit into a rectangle, I came across a weird problem and wondered if anyone knew why these three ways of using object fit act differently:
.container {
width: 250px;
padding-top: 20%;
border: 1px solid red;
position: relative;
display:inline-block
}
.container>img {
position: absolute;
top: 0;
left: 0;
object-fit: contain;
object-position: center center;
}
.image {
width: 100%;
height: 100%;
}
.image-1 {
right: 0;
bottom: 0;
}
.image-2 {
right: 0;
bottom: 0;
max-height: 100%;
max-width: 100%;
}
<div class="container">
<img src="https://www.fillmurray.com/200/300" class="image">
</div>
<div class="container">
<img src="https://www.fillmurray.com/200/300" class="image-1">
</div>
<div class="container">
<img src="https://www.fillmurray.com/200/300" class="image-2">
</div>
As you can see from the first image - everything works fine with a width and height. In the second image, I try to set the image so it fills the space with absolute positioning instead of width and height, but this is totally ignored and the image just overflows or stays it's original size.
To fix this, I use a max-width and height on the third image, but then this totally ignores the object-position and doesn't grow to a width or height larger than itself.
Why does object fit only work with a declared width and height and not if the image is just taking up space with coordinates and why does object-position not work with max-width and height?
The image is a replaced element so the use of top/left/right/bottom will not work like it will do with a non-replaced element (a simple div for example). Here is the relevant parts from the specification:
https://www.w3.org/TR/CSS2/visudet.html#abs-replaced-width
https://www.w3.org/TR/CSS2/visudet.html#abs-replaced-height
To make it easier the computed height/width of your image aren't defined by the top/bottom and right/left values but it's using the default one of the image thus there is no ratio distortion and object-fit will do nothing.
Use different value for bottom/right and you will see that they are ignored:
.container {
width: 250px;
padding-top: 20%;
border: 1px solid red;
position: relative;
display:inline-block
}
.container>img {
position: absolute;
top: 0;
left: 0;
object-fit: contain;
object-position: center center;
}
.image-1 {
right: 0;
bottom: 0;
}
<div class="container">
<img src="https://www.fillmurray.com/100/200" class="image-1" >
</div>
<div class="container">
<img src="https://www.fillmurray.com/100/200" class="image-1" style="right:100px;bottom:10000px">
</div>
<div class="container">
<img src="https://www.fillmurray.com/100/200" class="image-1" style="right:-10px;bottom:-10000px">
</div>
<div class="container">
<img src="https://www.fillmurray.com/100/200" class="image-1" style="right:-100px;bottom:50%">
</div>
Basically the top/left are simply adjusting the position and the intrinsic size of the image are used. If you explicitely specify the width/height or you add max-width/max-height constraint then you will be able to change the computed height/width like you already did.
Related question where the same happen with an input element: Width of absolute positioned input doesn't follow CSS rules
In your situation object-fit is only working for the first case where we have ratio distortion since you set height:100% and width:100%. Nothing will happen on the second case (like explained above) and also for the third case since you simply defined max-height/max-width thus the image will simply follow this constraint and will try to keep it's initial ratio.
In other words, object-fit will only work if you change the width AND the height AND this change break the initial ratio. Changing only one of them or none of them make the use of object-fit useless.
Related questions:
CSS object-fit: contain; is keeping original image width in layout
How does object-fit work with canvas element?

I've got a issue related with position and height auto

I've made responsible web slide img with 3 parts of div, give them(.slide_centent) position absolute and the parent(.slides) position relative, after that the parent(.slides) doesn't have height anymore. i give it px,% height but when i reduce browser only div(.slide_centent) become reduce together with images, parent(.slides)' bottom fixed at the point, it make huge black which not look so good. any ideas?
here is HTML
<section class="slides">
<div class="slide_centent">
<img src="images/images1.jpg" alt="images1">
<button class="slidesbtn1">자세히 보기</button>
</div>
<div class="slide_centent">
<img src="images/images2.jpg" alt="images2">
<button class="slidesbtn2">자세히 보기</button>
</div>
<div class="slide_centent">
<img src="images/images3.jpg" alt="images3">
<button class="slidesbtn3">자세히 보기</button>
</div>
</section>
Here is CSS
section.slides {
width: 100%;
height: auto;
position: relative;
}
section .slide_centent{
width: 100%;
position: absolute;
transition: all 3s;
}
section .slide_centent img{
width: 100%;
height: 100%;
min-width: 1500px;}
When you add position absolute to an element, you remove it from the flow of the page, so other elements are 'unaware' of its presence. In your case, the 'slides' won't know about the 'slides_centent' (because 'slides_ceneten' is out of the flow of the page), and can't keep the height of children.
I think it would be better to try to avoid position absolute in this case, but there are some things you could try.
Take a look here: Make absolute positioned div expand parent div height

How to shrink a DIV around a scaled IMG?

A simple (one might think!) question to all CSS gurus: I would like to shrink a DIV snugly around an IMG. The IMG is 600 x 800 and I needed it much smaller. So I go {height: 100%; width: auto;} and constrain the height via a wrapper DIV. However, to maintain the (unknown to me) AR, I cannot fix the width on the DIV. I tried to set the wrapping DIV to "display: inline-block" or "float: left" or "position: absolute" or ... - no matter: most browsers will stretch that DIV 800px wide - the original width of the full-size IMG - so it looks sthg like this:
[[IMG].............................]
Bizarrely, I can add some text to the DIV (just to test), and that text will actually appear right next to the scaled IMG:
[[IMG]Hello world..................]
Does anyone here know why the original size of the IMG matters (for dimensioning the width, it does not affect the height)? And what I might be able to do to shrink the DIV?
Thanks for looking.
EDIT:
To test Pär Wieslander's idea, I wrote a little test bed that should help clarify what I am on about:
<style type="text/css">
html, body {
height: 100%;
}
#dialog {
background: green;
height: 50%;
position: relative;
}
#frame {
border: 2px solid black;
display: inline-block;
height: 100%;
position: absolute;
}
#img {
height: 100%;
width: auto;
}
</style>
<body>
<div id="dialog">
<div id="frame">
<img id='img' src='...' />
</div>
</div>
</body>
Just pick any large IMG of your choice. You should find an inexplicably wide frame around and image that has squeezed - height-wise - onto the green carpet.
If you specify the image's width or height as a percentage, that percentage is calculated in proportion to the size of the parent block. So specifying width: 50% on the image doesn't mean 50% of the original image width -- it means 50% of the width of the parent block. The same goes for the height. Thus, there will always be extra space around the image as long as you specify the width or height as a percentage.
The solution is simple -- specify the dimensions in pixels, ems or any other unit other than a percentage:
HTML
<div class="wrapper">
<img class="small" src="myimage.jpg">
</div>
CSS
img.small {
width: 150px; /* or whatever you like */
display: block; /* to avoid empty space below the image */
}
div.wrapper {
display: inline-block;
border: 1px solid #000;
}
Edit: Based on your comments and updated post, I understand that what you really want to do is to set the width of the surrounding div and make the image fill up that div. Here's an example that does that:
HTML
<div class="wrapper big">
<img src="myimage.jpg">
</div>
<div class="wrapper small">
<img src="myimage.jpg">
</div>
CSS
img {
display: block;
width: 100%;
}
.wrapper {
margin-top: 1em;
border: 1px solid #000;
}
.big {
width: 600px;
}
.small {
width: 300px;
}
So I go height="50%", say, and width="auto" (to maintain AR).
Why not just go width="50%" too as this would resolve it.
I think Pär's approach is right: don't do { height: fix; width: auto; } but do instead { height: auto; width: fix; } Works better.

Resources