问题
I'm trying to make my images responsive inside some flexbox containers using object-fit: contain
, and while the images do resize, the layout seems to be keeping the original image size, causing a scrollbar to appear.
Checking the width of the image using Chrome Dev Tools shows that the width is still 1024 (however the height has been reduced appropriately.)
(I've taken inspiration from Auto Resize Image in CSS FlexBox Layout and keeping Aspect Ratio? to get to this point)
Am I missing some additional CSS attributes?
JSFiddle: https://jsfiddle.net/w6hgqf18/1/
html,
body {
margin: 0;
height: 100%;
}
.page {
height: 100%;
display: flex;
}
.main-container {
flex: 1 1 0;
display: flex;
flex-direction: column;
}
.half-containers {
flex: 0 1 50%;
overflow: auto;
box-sizing: border-box;
border: 0.5px solid red;
display: flex;
}
.page-header {
flex: 0 0 auto;
background-color: #dcdcdc;
}
.page-footer {
flex: 0 0 auto;
background-color: #dcdcdc;
}
img {
object-fit: contain;
}
<div class="page">
<div class="main-container">
<div class="page-header">
This is a header
</div>
<div class="half-containers">
<img src='https://i.imgur.com/tqQvuFr.jpg' />
</div>
<div class="half-containers">
<img src='https://i.imgur.com/tqQvuFr.jpg' />
</div>
<div class="page-footer">
This is a footer
</div>
</div>
</div>
回答1:
What you have is logical, you simply need to understand how object-fit
works. Let's start with an easier example:
.box {
width:300px;
height:300px;
border:1px solid;
}
img {
width:100%;
height:100%;
object-fit:contain;
}
<div class="box">
<img src="https://picsum.photos/300/200?image=1069">
</div>
As you can see I have used a 300x200
image that I stretch inside the 300x300
box thus I break its ratio and if you check the width/height of the image you will see that it's dimension is still 300x300
(the dimenstion before applying object-fit
).
From the specification:
The object-fit property specifies how the contents of a replaced element should be fitted to the box established by its used height and width.
Basically, we visually change the content of the image so it fit the space established by the image. object-fit
doesn't change the size of the image but uses that size as a reference to change its content inside.
Let's take the same example and use 50%
instead:
.box {
width:300px;
height:300px;
border:1px solid;
}
img {
width:50%;
height:50%;
object-fit:contain;
}
<div class="box">
<img src="https://picsum.photos/300/200?image=1069">
</div>
Now the image has a dimension of 150x150
and inside this we change the content to have the contain effect.
Same logic will happen with all the values
.box {
width:300px;
height:300px;
border:1px solid;
}
img {
width:50%;
height:50%;
}
<div class="box">
<img src="https://picsum.photos/300/200?image=1069" style="object-fit:contain;">
</div>
<div class="box">
<img src="https://picsum.photos/300/200?image=1069" style="object-fit:cover;">
</div>
In you example you are having the same thing. without object-fit
the image is like below
html,
body {
margin: 0;
height: 100%;
}
.page {
height: 100%;
display: flex;
}
.main-container {
flex: 1 1 0;
display: flex;
flex-direction: column;
}
.half-containers {
flex: 0 1 50%;
overflow: auto;
box-sizing: border-box;
border: 0.5px solid red;
display: flex;
}
.page-header {
flex: 0 0 auto;
background-color: #dcdcdc;
}
.page-footer {
flex: 0 0 auto;
background-color: #dcdcdc;
}
img {
/*object-fit: contain;*/
}
<div class="page">
<div class="main-container">
<div class="page-header">
This is a header
</div>
<div class="half-containers">
<img src='https://i.imgur.com/tqQvuFr.jpg' />
</div>
<div class="half-containers">
<img src='https://i.imgur.com/tqQvuFr.jpg' />
</div>
<div class="page-footer">
This is a footer
</div>
</div>
</div>
Adding object-fit
won't change its size but only what we see:
html,
body {
margin: 0;
height: 100%;
}
.page {
height: 100%;
display: flex;
}
.main-container {
flex: 1 1 0;
display: flex;
flex-direction: column;
}
.half-containers {
flex: 0 1 50%;
overflow: auto;
box-sizing: border-box;
border: 0.5px solid red;
display: flex;
}
.page-header {
flex: 0 0 auto;
background-color: #dcdcdc;
}
.page-footer {
flex: 0 0 auto;
background-color: #dcdcdc;
}
img {
object-fit: contain;
}
<div class="page">
<div class="main-container">
<div class="page-header">
This is a header
</div>
<div class="half-containers">
<img src='https://i.imgur.com/tqQvuFr.jpg' />
</div>
<div class="half-containers">
<img src='https://i.imgur.com/tqQvuFr.jpg' />
</div>
<div class="page-footer">
This is a footer
</div>
</div>
</div>
Now, the other issue is that your image has a width of 1024px
and a flex items will not stretch past its content size due to the min-width constraint so what you need to add in order to obtain the needed effect is min-width:0
. Doing so you will no more have overflow issue then your image will be contained inside the area defined by the flexbox layout.
html,
body {
margin: 0;
height: 100%;
}
.page {
height: 100%;
display: flex;
}
.main-container {
flex: 1 1 0;
display: flex;
min-width: 0; /*added*/
flex-direction: column;
}
.half-containers {
flex: 0 1 50%;
overflow: auto;
box-sizing: border-box;
border: 0.5px solid red;
display: flex;
}
.page-header {
flex: 0 0 auto;
background-color: #dcdcdc;
}
.page-footer {
flex: 0 0 auto;
background-color: #dcdcdc;
}
img {
object-fit: contain;
min-width: 0; /*added*/
}
<div class="page">
<div class="main-container">
<div class="page-header">
This is a header
</div>
<div class="half-containers">
<img src='https://i.imgur.com/tqQvuFr.jpg' />
</div>
<div class="half-containers">
<img src='https://i.imgur.com/tqQvuFr.jpg' />
</div>
<div class="page-footer">
This is a footer
</div>
</div>
</div>
You can also have the same output considering background-image
and background-size:contain
where you no more have to bother with the min-width
contraint since there is no more content
html,
body {
margin: 0;
height: 100%;
}
.page {
height: 100%;
display: flex;
}
.main-container {
flex: 1 1 0;
display: flex;
flex-direction: column;
}
.half-containers {
flex: 0 1 50%;
overflow: auto;
box-sizing: border-box;
border: 0.5px solid red;
display: flex;
background:url(https://i.imgur.com/tqQvuFr.jpg) center/contain no-repeat;
}
.page-header {
flex: 0 0 auto;
background-color: #dcdcdc;
}
.page-footer {
flex: 0 0 auto;
background-color: #dcdcdc;
}
<div class="page">
<div class="main-container">
<div class="page-header">
This is a header
</div>
<div class="half-containers">
</div>
<div class="half-containers">
</div>
<div class="page-footer">
This is a footer
</div>
</div>
</div>
回答2:
You can wrap img
tag with a div
with width: 100%
and set image height
to 100%
and do that without object-fit
:
html,
body {
margin: 0;
height: 100%;
}
.page {
height: 100%;
display: flex;
}
.main-container {
flex: 1 1 0;
display: flex;
flex-direction: column;
}
.half-containers {
flex: 0 1 50%;
overflow: auto;
box-sizing: border-box;
border: 0.5px solid red;
display: flex;
}
.page-header {
flex: 0 0 auto;
background-color: #dcdcdc;
}
.page-footer {
flex: 0 0 auto;
background-color: #dcdcdc;
}
.img-container {
width: 100%;
}
img {
height: 100%;
}
<div class="page">
<div class="main-container">
<div class="page-header">
This is a header
</div>
<div class="half-containers">
<div class="img-container">
<img src='https://i.imgur.com/tqQvuFr.jpg' />
</div>
</div>
<div class="half-containers">
<div class="img-container">
<img src='https://i.imgur.com/tqQvuFr.jpg' />
</div>
</div>
<div class="page-footer">
This is a footer
</div>
</div>
</div>
来源:https://stackoverflow.com/questions/54375940/css-object-fit-contain-is-keeping-original-image-width-in-layout