Scale the image to maximize free space and center it.

I am creating a single page application. In one of the views, I want to show an image that should occupy the maximum possible space:

  • Most importantly: it must maintain aspect ratio
  • it cannot be cut
  • it must be stretched horizontally and / or vertically (without changing the aspect ratio) to cover the maximum possible space
  • image size and viewing area unknown
  • it should be centered.
  • no js must be used
  • the element should be an img element and the background should not be used - I already have the background (in the container)

For example, let's say that the image is 100px x 100px, and that we have a container sized 500px x 300px. The image will then stretch to 300px x 300px and be horizontally centered, so that 100px will remain as a complement on both sides.

Is it possible?

Here is my incomplete code of what I'm trying to execute.

 .container1 { width: 500px; height: 300px; border: 2px; border-color: red; border-style: solid; } .container2 { width: 300px; height: 500px; border: 2px; border-color: blue; border-style: solid } .fill-vertical { border: 2px; border-style: solid; border-color: green; display: block; max-width: 100%; } .fill-horizontal { width: 100%; border: 2px; border-style: solid; border-color: green; } 
  <h1>Container 1, 500px x 300px, not filled</h1> <div class="container1"> <img src="http://files.giercownia.pl/upload/avatars/r/ravax.png?v=0"> </div> <h1>Container 1, filled vertically (should be horizontally centered)</h1> <div class="container1"> <img class="fill-vertical" src="http://files.giercownia.pl/upload/avatars/r/ravax.png?v=0"> </div> <h1>Container 300px x 500px, not filled</h1> <div class="container2"> <img class="fillIt" src="http://files.giercownia.pl/upload/avatars/r/ravax.png?v=0"> </div> <h1>Container 300px x 500px, filled horizontally, should be vertically centered</h1> <div class="container2"> <img class="fill-horizontal" src="http://files.giercownia.pl/upload/avatars/r/ravax.png?v=0"> </div> 

In this code, I am forced to use a different class for the image depending on whether I want to stretch vertically or horizontally, but in fact I want CSS to do this automatically: only one stretch class needs to be defined .

In short, what I want to do CSS: stretch width and / or height to fit the available space while maintaining aspect ratio

+6
source share
3 answers

This can be achieved in CSS with a few changes.

Necessary changes:

  • Create a new .centerImage css rule. overflow: hidden; ensures that the image does not exit the container. position: relative; required since the img child must be placed absolutely relative to the container.
  • Create a new .centerImage img css rule. max-height: 100%; and max-width: 100% ensures that the aspect ratio is maintained. Setting bottom , left , right and top to 0 and margin: auto; centers the image.
  • Add the centerImage class to the containing div s.
  • Change .fill-vertical to height: 100%; which will make img fill the vertical space.
  • Change .fill-horizontal to width: 100%; which will make img fill the horizontal space.

 .container1 { border: 2px; border-color: red; border-style: solid; height: 300px; width: 500px; } .container2 { border: 2px; border-color: blue; border-style: solid; height: 500px; width: 300px; } .fill-vertical { height: 100%; } .fill-horizontal { width: 100%; } .centerImage { display: block; overflow: hidden; position: relative; text-align: center; } .centerImage img { bottom: 0; left: 0; margin: auto; max-height: 100%; max-width: 100%; position: absolute; right: 0; top: 0; } 
 <h1>Container 1, 500px x 300px, not filled</h1> <div class="container1 centerImage"> <img src="http://files.giercownia.pl/upload/avatars/r/ravax.png?v=0"> </div> <h1>Container 1, filled vertically (should be horizontally centered)</h1> <div class="container1 centerImage"> <img class="fill-vertical" src="http://files.giercownia.pl/upload/avatars/r/ravax.png?v=0"> </div> <h1>Container 300px x 500px, not filled</h1> <div class="container2 centerImage"> <img src="http://files.giercownia.pl/upload/avatars/r/ravax.png?v=0"> </div> <h1>Container 300px x 500px, filled horizontally, should be vertically centered</h1> <div class="container2 centerImage"> <img class="fill-horizontal" src="http://files.giercownia.pl/upload/avatars/r/ravax.png?v=0"> </div> 

http://jsbin.com/bupuwohica/2/

In addition to the above changes, this can be achieved using the CSS object-fit property

For this you need:

  • Add object-fit: contain; to image
  • Set height and width to 100%

The only caveat to this is browser support, as Firefox, Chrome, Safari and Opera have supported this for some time, and IE and Edge do not require and will need a polyfill or backup.

 .container { border: 2px solid red; height: 200px; overflow: hidden; resize: both; width: 300px; } img { object-fit: contain; height: 100%; width: 100%; } 
 <p>The below div is resizable, drag the bottom right corner to see how the image scales</p> <div class="container"> <img alt="" src="http://files.giercownia.pl/upload/avatars/r/ravax.png?v=0" /> </div> 

https://jsfiddle.net/efyey801/

+7
source

Here is one way to do this by relying on background-size . This uses img tags if required, but the visible image is loaded as a background to take advantage of the available CSS rules.

 .container { background-color: #edc; position: relative; margin: 2em; } .container img { display: block; width: 100%; height: 100%; background-image: url(http://www.clipartbest.com/cliparts/yck/eXb/yckeXboMi.png); background-size: contain; background-repeat: no-repeat; background-position: center; } #c1 { width: 400px; height: 100px; } #c2 { width: 400px; height: 600px; } 
 <div id="c1" class="container"> <img src=""> </div> <div id="c2" class="container"> <img src=""> </div> 

Here's more background size information: https://developer.mozilla.org/en-US/docs/Web/CSS/background-size

+2
source

Yes, it is quite possible. You just need to make sure that you have β€œBounds” or limits on your maximum size for X or horizontal and Y or vertical limits. Once you know the maximum sizes, you can match these constants. The easiest method I know is to compare X and Y as vectors so you can see their change. To get it in the center is also easy:

 (((horizontalScreenLimit - widthOfImage)/2), ((verticalScreenLimit - heightOfImage)/2)') 
0
source

Source: https://habr.com/ru/post/982288/


All Articles