Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

make image fill remaining vertical space, no scroll

I have a page with a title, paragraph and a single image, that can be of very different sizes/aspect ratios.

I would like the image to adapt so that it will either fill maximum available height, or be limited by its width, without loosing aspect ratio, neither causing scrolling.

this is my basic config:

angular.module("myApp", ["ngMaterial"]);
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0-rc7/angular-material.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-aria.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"></script>

<script src="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0-rc7/angular-material.min.js"></script>

<div ng-app="myApp" layout="column" layout-fill> 
  <div flex style="background: red;">
    <h1>Title</h1>
    <p>Details. Blablabla.</p> 
  </div>
  <div flex="60" style="background: blue;" object-fit="fill">
    <img id="myImg" ng-src="http://placehold.it/200x400"/>
    <!-- Should work with such extreme case as well -->
    <!-- <img id="myImg" ng-src="http://placehold.it/1000x200" /> -->
  </div>
</div>

I have looked at a lot of SO posts, websites, blogs, etc. I can't figure out where to start to get this done. Most articles about fluid images or responsive images only talk about scrollable web pages. So even a good reference on the topic would be helpful. Thank you.

EDIT: Updated the snipped to use flex layout. As you can see, the image goes outside the blue div bounds. I have used object-fit="content"; or object-fit="fill"; but none seems to constraint the image to respect div bounds

like image 905
Overdrivr Avatar asked Oct 30 '22 12:10

Overdrivr


1 Answers

It can be done by object-fit(it doesn't support IE) and css calc(it supports most of broswer).

What did you do?

I wrap image by a div(.wrapper), calculate height of it by css calc.

height: calc(100vh - 19px - 38px); //100% of viewport - height of p - height of h1

and then use object-fit to image is fitted the height of .wrapper by keeping the ration of image.

Image by high height

angular.module("myApp", ["ngMaterial"]);
h1,
p {
  padding: 0;
  margin: 0;
}
.wrapper {
  width: 100%;
  height: calc(100vh - 19px - 38px);
}
img {
  object-fit: fill;
  height: 100%;
  max-width: 100%;
  display: block;
  margin: 0 auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0-rc7/angular-material.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-aria.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"></script>

<script src="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0-rc7/angular-material.min.js"></script>

<div ng-app="myApp" layout="column" layout-align="center center" style-parent>
  <h1>Title</h1>
  <p>Details. Blablabla.</p>
  <div class="wrapper">
    <img id="myImg" ng-src="http://placehold.it/200x400" /> 
    <!-- Should work with such extreme case as well -->
    <!-- <img id="myImg" ng-src="http://placehold.it/1000x200" /> -->
  </div>
</div>

Image by less height

angular.module("myApp", ["ngMaterial"]);
h1,
p {
  padding: 0;
  margin: 0;
}
.wrapper {
  width: 100%;
  height: calc(100vh - 19px - 38px);
}
img {
  object-fit: fill;
  height: 100%;
  max-width: 100%;
  display: block;
  margin: 0 auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0-rc7/angular-material.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-aria.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"></script>

<script src="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0-rc7/angular-material.min.js"></script>

<div ng-app="myApp" layout="column" layout-align="center center" style-parent>
  <h1>Title</h1>
  <p>Details. Blablabla.</p>
  <div class="wrapper">
    <!-- <img id="myImg" ng-src="http://placehold.it/200x400" />  -->
    <!-- Should work with such extreme case as well -->
    <img id="myImg" ng-src="http://placehold.it/1000x200" />
  </div>
</div>
like image 157
Alex Avatar answered Nov 12 '22 17:11

Alex