Fluid image inside a resizable DIV

2019-07-24 01:54发布

问题:

I'm trying fit a fluid image inside a resizable DIV. The image must retain its proportions and never go beyond 100% (both width and height) - even if the containing DIV is larger than the image.

The image must also be centered, both horizontally and vertically. Chrome and Safari does this perfectly - Internet Explorer 10 doesn't.

I've set up a quick jsfiddle to illustrate the issue.

HTML:

<div id="diver">
    <img src="http://ie.microsoft.com/testdrive/Performance/Minesweeper/images/ie-logo.png" style="" />
</div>

And the css:

#diver {
    border:1px solid #000000;
    width:200px;
    height:200px;
    text-align:center;
    display: table-cell;
    vertical-align: middle;
}

img {
    max-width:100%;
    max-height:100%;
}

Try resizing the box to less than 100% width and height in Chrome and you will get something similar to these images:

Less than 100% height:

Less than 100% width:

Internet Explorer 10 however, only scales the height. The width will not go below 100%, which is the main issue.

I can get IE to scale the width, similar to Chrome/Safari, but it requires the DIV height (yes, height) to be set to something low, like 10px, which is kindda weird imo.

I know it's possible to scale the image dynamically in javascript, but I don't see the need for extra javascript, when Internet Explorer should be able to handle the scaling correctly.

回答1:

Table cells and size contraints

The problem occurs in IE, Firefox, and Opera. It's caused by using display: table-cell in combination with max-width: 100% and max-height: 100%. Table cells behave differently in this case than an element with display: block.

It has nothing to do with the container being resizable. It also has nothing to do with aligning the content (although that's presumably the motivation for using display: table-cell). Both can be removed from the equation for the time being, in the interest of reducing the code to the simplest state in which the underlying problem can still be reproduced.

Simplified Demo

In the simplified demo, there's a pair of images and a pair of span tags with a blue background. In each pair, the first one uses display: block and the second one uses display: table-cell. The rest of the CSS is identical.

For each one, if the CSS is successful, the width and height of the image or span will be reduced to 100px. If not, the width or height will remain at 200px.

Images

  • When using display: block, it works fine in all browsers.
  • When using display: table-cell, Chrome and Safari (Webkit browsers) work fine, while IE, Firefox, and Opera fail to reduce the width of the image.

span tags

  • When using display: block, it works fine in all browsers.
  • When using display: table-cell, Chrome and Safari fail to reduce the width and height, while IE, Firefox, and Opera fail to reduce the width.

For images, the behavior is consistent with the results of testing the original demo added to the question.

Here's an updated version of the original demo, replacing the image with a span with a blue background, that may demonstrate a little more clearly how the underlying problem exists in Chrome and Safari as well. If the demo is changed to use display: block, the sizing of the content works fine in all browsers (though the alignment is lost).

jQuery

Unless a way can be found to correctly size an image in a table cell, in a simplified case like this, solving this for the original demo will likely require adding some additional jQuery, or experimenting with a more-advanced CSS3 feature like flexbox or grids.

If additional jQuery is needed, it could be used for the alignment of the image (so that display: block can be used for the container), or it could be used for the resizing of the image (removing the use of max-width: 100% and max-height: 100%, so that display: table-cell can be used for the alignment).

In either case, jQuery UI Resizable has a resize event that can be used for this.



回答2:

If you do the below, it will make the max-width work in Internet explorer 10.

#diver {
    border:1px solid #000000;
    width:200px;
    height:200px;
    text-align:center;
    /*display: table-cell;*/
    vertical-align: middle;    
}

I assume this solves half the issue as vertical alignment of the image is lost. A bounty will motivate me to look into the issue further ;)