CSS object-fit: contain; is keeping original image width in layout

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>

Leave a Comment