Home > database >  Responsive <img> for svg has overflow
Responsive <img> for svg has overflow

Time:10-03

I am trying to have an <img src="*.svg"> tag to display (any) svg file, however with what I have so far there is some overflow of the svg's viewbox when it fills the width:

image of the overflow

If I did not need absolute positioning, it works without any overlfow if you remove display: inline-block and use max-width and max-height, but since I need the image to fill its container, I have to use inline-block.

Thanks in advance for any help .

    #inner-map {
        display: inline-block;
        position: relative;
    }

    #map-svg {
        border-style: solid;
    }

    #map-svg img {
        width: 100%;
        height: 80vh;
        display: block;
    }

    #pog-outer {
        position: absolute;
    }

    #pog-inner {
        position: absolute;
        left:-9px;
        top:-9px;
    }
  <div id="inner-map">
      <div id="pog-outer" style="top:58.794%;left:28.915%">
        <div id="pog-inner">
          <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="18" height="18">
            <defs>
              <radialGradient id="Shiny" cx="0.5" cy="0.5" r="0.5" fx="0.25" fy="0.25">
                <stop offset="0%" stop-color="#FFFFFF" />
                <stop offset="50%" stop-color="#DD3333" />
                <stop offset="75%" stop-color="#990000" />
                <stop offset="100%" stop-color="#000000" />
              </radialGradient>
            </defs>
            <circle r="6" cx="9" cy="9" fill="url(#Shiny)" />
          </svg>
        </div>
      </div>
      <div id="map-svg">
        <img src="https://upload.wikimedia.org/wikipedia/commons/d/d5/North_America_laea_location_map.svg">
      </div>
    </div>

CodePudding user response:

Per the question's comments you want the image to fill the whole container and then if the aspect ratio of the image and its container differ, some edges of the image would overflow and are no longer be visible.

So to get that we'd want the image to have have preserveAspectRatio="xMidYMid slice" on its root element but unfortunately it doesn't. It doesn't have that attribute at all and the default if you have a viewBox is preserveAspectRatio="xMidYMid meet"

We'll need to override that value by using an SVG fragment identifier.

To make the example below more obvious I've also changed the width to width: 70vh; so it always overflows. You probably don't want to do that.

    #inner-map {
        display: inline-block;
        position: relative;
    }

    #map-svg {
        border-style: solid;
    }

    #map-svg img {
        width: 70vh;
        height: 80vh;
        display: block;
    }

    #pog-outer {
        position: absolute;
    }

    #pog-inner {
        position: absolute;
        left:-9px;
        top:-9px;
    }
  <div id="inner-map">
      <div id="pog-outer" style="top:58.794%;left:28.915%">
        <div id="pog-inner">
          <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="18" height="18">
            <defs>
              <radialGradient id="Shiny" cx="0.5" cy="0.5" r="0.5" fx="0.25" fy="0.25">
                <stop offset="0%" stop-color="#FFFFFF" />
                <stop offset="50%" stop-color="#DD3333" />
                <stop offset="75%" stop-color="#990000" />
                <stop offset="100%" stop-color="#000000" />
              </radialGradient>
            </defs>
            <circle r="6" cx="9" cy="9" fill="url(#Shiny)" />
          </svg>
        </div>
      </div>
      <div id="map-svg">
        <img src="https://upload.wikimedia.org/wikipedia/commons/d/d5/North_America_laea_location_map.svg#svgView(preserveAspectRatio(xMidYMid slice))">
      </div>
    </div>

CodePudding user response:

You can replace the height: 80vh; with height: 80% in the element and this way it's going to always hide the non-blue svg part and without making any overflow.

    #inner-map {
        display: inline-block;
        position: relative;
    }

    #map-svg {
        border-style: solid;
    }

    #map-svg img {
        width: 100%;
        height: 80%;
        display: block;
    }

    #pog-outer {
        position: absolute;
    }

    #pog-inner {
        position: absolute;
        left:-9px;
        top:-9px;
    }
  <div id="inner-map">
      <div id="pog-outer" style="top:58.794%;left:28.915%">
        <div id="pog-inner">
          <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="18" height="18">
            <defs>
              <radialGradient id="Shiny" cx="0.5" cy="0.5" r="0.5" fx="0.25" fy="0.25">
                <stop offset="0%" stop-color="#FFFFFF" />
                <stop offset="50%" stop-color="#DD3333" />
                <stop offset="75%" stop-color="#990000" />
                <stop offset="100%" stop-color="#000000" />
              </radialGradient>
            </defs>
            <circle r="6" cx="9" cy="9" fill="url(#Shiny)" />
          </svg>
        </div>
      </div>
      <div id="map-svg">
        <img src="https://upload.wikimedia.org/wikipedia/commons/d/d5/North_America_laea_location_map.svg">
      </div>
    </div>

  • Related