Tony Bogdanov Tony Bogdanov - 6 months ago 154
CSS Question

SVG image not rendering properly in IE11 / Edge unless container has fixed width

Both Edge and Internet Explorer 11 seem to scale SVG images rather differently than regular raster images.

Take a look at the following example:



.container {
display: flex;
flex-flow: row nowrap;
}

.box {
flex: 0 1 auto;
background: red;
}

.fill {
flex: 1 0 auto;
background: green;
}

.box img {
display: block;
width: auto;
height: 150px;
background: blue;
}

<div class="container">
<div class="box">
<img src="http://s33.postimg.org/hbl2jy69b/logo_light.png" alt="" />
</div>
<div class="fill">fill</div>
</div>
<div class="container">
<div class="box">
<img src="http://imgh.us/logo-light_1.svg" alt="" />
</div>
<div class="fill">fill</div>
</div>





Both images are identical, the first is a PNG, the other is an SVG. Both images reside in a
.box
which is set to
flex-shrink
but not
flex-grow
. Next to the box is a
.fill
which is set to
flex-grow
, but not
flex-shrink
.

So, the idea is really simple. We set each image's height to some fixed value, the width gets calculated automatically keeping the aspect ratio of the image, which respectfully sets the width of the
.box
container.
.fill
occupies the rest of the available space.

The example works just fine both in Chrome and Firefox, and two identical images are being displayed:

enter image description here

In Edge however, the image is cropped:

enter image description here

Where in IE it's even weirder:

enter image description here

You can view the source of the SVG here: http://imgh.us/logo-light_1.svg

I've also tried a couple of different values for the
preserveAspectRatio
attribute of the SVG all with different results, but still not the one I'm actually looking for.

Am I missing something? Is this just a matter of a proper
preserveAspectRatio
attribute or is it a bug?

Answer

As you've noted, a fixed width on the image container gets this to work on IE11.

This worked for me:

.box {
    flex: 0 1 461px;   /* changed flex-basis from auto */
    background: red;
}

If that's not an option, and you simply want PNG and SVG to match, then a positive z-index value will shift the blue background to the surface.

.box {
    flex: 0 1 auto;
    background: red;
    z-index: 1;        /* new */
}

Note that z-index does not need to be positioned when applied to flex items (reference).


Another possible solution would be placing the image in a flex container, then defining the width (as opposed to the height) of the image:

.box {
  flex: 0 1 auto;
  background: red;
  display: flex;      /* new */
}

.box img {
  /* display: block; */
  /* width: auto; */
  /* height: 150px; */
  background: blue;
  width: 332px;     /* new; value can be anything, PNG and SVG will match */
}
Comments