36

http://jsfiddle.net/Log82brL/15/

This <img> isn't shrink wrapping as I would expect with min-width:100%

I'm trying to shrink the <img> until either height or width matches the container

Click anywhere in the <iframe> to toggle container shapes

Please try to edit the <img> CSS:

  1. MAINTAIN ASPECT RATIO
  2. COVER ENTIRE SURFACE AREA OF CONTAINER DIV
  3. ONLY EDIT THE IMAGE

My question is specifically: scale an <img> to maintain aspect ratio but cover the entire surface of parent <div> even as the parent <div> resizes.

Maybe I could somehow use css flex box-layout or something? Maybe a transform?

isherwood
  • 58,414
  • 16
  • 114
  • 157
neaumusic
  • 10,027
  • 9
  • 55
  • 83

12 Answers12

35

http://jsfiddle.net/Log82brL/7/

#img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

object-fit: cover allows the replaced content is sized to maintain its aspect ratio while filling the element’s entire content box: its concrete object size is resolved as a cover constraint against the element’s used width and height.

2ne
  • 5,766
  • 9
  • 30
  • 51
  • 1
    This method has terrible [browser support](http://caniuse.com/object-fit), but there's a [polyfill](https://github.com/anselmh/object-fit) for that. – David Mann Jul 12 '15 at 03:32
  • 1
    The support is not that bad at all. It is only IE that doesn't support it. http://caniuse.com/#feat=object-fit – 2ne Jul 12 '15 at 07:14
  • As much as I wish it weren't so, IE still makes up a good portion of browser usage. Still, this is the same answer I would have given, so I can't complain too much. I mostly just wanted to mention the polyfill. – David Mann Jul 12 '15 at 11:02
  • target usecase is webkit browsers, i fortunately dont have to deal with IE, i think this might be the real answer, i just can't get it to work with the fiddle – neaumusic Jul 13 '15 at 22:15
  • oh man, thanks! this saved me after hours of pulling my hair out. – samurai jack Sep 11 '20 at 06:03
  • This is the correct answer to the question. The accepted answer is a hack and goes against the semantic html. – Dziad Borowy Jan 14 '21 at 23:16
  • is there any easy way to center the image? it seems to be left-aligned – neaumusic Apr 29 '22 at 00:57
9

If you don't want to touch the container, put the background on the <img>

#img { 
  background: url(imgpath) no-repeat center;
  background-size: cover;
}

You can set HTML source to a transparent base64 pixel (credit CSS Tricks)

<img id="img" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" />

http://jsfiddle.net/Log82brL/17/

neaumusic
  • 10,027
  • 9
  • 55
  • 83
Light
  • 1,077
  • 10
  • 33
  • wow, how did nobody think of this. i can't touch the container div because it's a shared class, but the img can definitely have an empty source – neaumusic Jul 14 '15 at 18:06
  • 2
    This is a hack and goes against the semantic html. `object-fit: cover; width: 100%; height: 100%` is the correct answer. – Dziad Borowy Jan 14 '21 at 23:18
3

Did u try the bootstrap solution

http://getbootstrap.com/css/#images-responsive

which is pretty much

.img-responsive
{
max-width: 100%;
height: auto; 
display: block;
}

Adding to your update question

http://jsfiddle.net/arunzo/Log82brL/5/

.skinny>img
{
    max-width:none !important;
    min-height:none !important;    
    max-height:100%;
    -webkit-transform:translate3d(+50%, +50%, 0);
}

And still i am unsure what is that you seek, sorry for the jerky animation.

Riddler
  • 566
  • 2
  • 10
  • width cannot ever be less than 100% if i want it to fill the entire surface. i believe your solution fits the image within the container – neaumusic Jul 02 '15 at 22:48
  • i only want to have the top/bottom outside of the parent, or left/right outside of the parent, but not both, and it needs to stretch if the parent container grows – neaumusic Jul 08 '15 at 08:26
  • I understand and that is exactly what i have achieved. Try using chrome inspector tools to verify it yourself. Resize the Result window just in case – Riddler Jul 08 '15 at 08:55
2

You can use CSS background instead of HTML img.

.myDiv
{
  height: 400px;
  width: 300px;
  background-image: url('image-url.png');
  background-repeat: no-repeat;
  background-size: contain;
  background-position: center center;
  border: 1px solid #000000;
}

<div class="myDiv">
</div>  

Here is the JS Fiddle Demo.
Try to change height and width - you will see that image stretches to fill the div.

You can also different background-size values:

  1. Proportional stretch to contain: background-size: contain;
    Too tall div
    Too wide div

  2. Proportional stretch to fill: background-size: cover;
    Too tall div
    Too wide div

  3. Stretch to fill 100%: background-size: 100% 100%;
    Too tall div
    Too wide div

Yeldar Kurmangaliyev
  • 33,467
  • 12
  • 59
  • 101
2

use single css background shorthand property

.myDiv
{
  height: 400px;/*whatever you want*/
  width: 300px;/*whatever you want*/
  background: url('image-url.png') no-repeat center center;
  background-size: contain;
}

<div class="myDiv">
</div> 
Akhilesh Kumar
  • 9,085
  • 13
  • 57
  • 95
  • This is a good solution if the OP can get away with minor adjustments to the html, unless IE8 has to be supported (IE8 doesn't do `background-size`) – henry Jul 13 '15 at 17:19
1

A while back I found a jQuery solution called "backstretch". Now this looks possible with CSS3:

html { 
  background: url(images/bg.jpg) no-repeat center center fixed; 
  background-size: cover;
}
isherwood
  • 58,414
  • 16
  • 114
  • 157
berto
  • 8,215
  • 4
  • 25
  • 21
1

Updated answer. Now works as intended.

var toggle = false,
    containerElement = document.querySelector("#container");
window.onclick = function () {
    containerElement.className = (toggle = !toggle ? "skinny" : "");
}
window.alert("click anywhere to toggle shapes. img is a large square");
#container {
    overflow: hidden;
    width: 400px;
    height: 200px;
    transition: all .5s;
    margin: 0 auto; /* this is just for demonstration purposes */
}
#container.skinny {
    width: 200px;
    height:600px;
}
#img {
    height: auto;
    left: 50%;
    margin: auto;
    min-height: 100%;
    position: relative;
    top: 50%;
    transform: translate(-50%, -50%); /* changed to 2d translate */
    width: 100%; /* full width in wide mode */
}

#container.skinny #img {
    width: auto; /* width reset in tall mode */
}
<div id="container">
    <img id="img" src="http://farm8.static.flickr.com/7440/12125795393_3beca9c24d.jpg" />
</div>
IMI
  • 2,461
  • 1
  • 14
  • 20
  • @Neaumusic - I updated this answer and removed the absolute positioning requirements. It also now correctly shrinks the image width properly in wide mode. – IMI Jul 14 '15 at 21:59
0

http://krasimirtsonev.com/blog/article/CSS-Challenge-1-expand-and-center-image-fill-div

contained AND centered

I think this is the rendering you're trying to get, this might help ;)

https://jsfiddle.net/erq1otL4/

<div id="container" style="background-image: url(http://farm8.static.flickr.com/7440/12125795393_3beca9c24d.jpg);"></div>   

#container.skinny {
width: 400px;
height:600px;
}
#container {
    width: 400px;
    height: 200px;
    overflow: hidden;
    background-size: cover;
    background-color:pink;
    background-position: center center;
}

var toggle = false,
containerElement = document.querySelector("#container");
window.onclick = function () {
    containerElement.className = (toggle = !toggle ? "skinny" : "");
}
window.alert("click anywhere to toggle shapes. img is a large square");
Fundhor
  • 3,369
  • 1
  • 25
  • 47
-1

Usually to achieve that you need to use:

parentdiv img {
   width:100%;
   height:auto;}

in order to make your image resize with the parent div.

This can cause some cropping issues (visually) if you set the overflow to hidden.

Pierre Irani
  • 805
  • 5
  • 19
-1

Try this:

<div class="img_container">
   <img src="image/yourimage.jpg" alt="" />
</div>

<style type="text/css">
   .img_container{
      width: 400px;
      height: 400px;
      overflow: hidden;
    }
   .img_container img{
       width: 100%;
       height: auto;
     }
 </style>

setting the height or the with auto will not make the image look stretched.

-1

Use this class of Bootstrap .img-responsive and if parent div changes add media Queries to image and div both

Shashank
  • 31
  • 9
-1

Here is a very simple CSS solution that does not require changing the attributes of an img tag.

div{
            background-image: url("http://www.frikipedia.es/images/thumb/d/d5/Asdsa-asdas.jpg/300px-Asdsa-asdas.jpg");
            height: auto;
            width: 400px;
            overflow: hidden;
            background-size: cover;
            background-position: center;
        }
rassa45
  • 3,482
  • 1
  • 29
  • 43