SVG oversized on load until CSS kicks in

lazy load images example
lazyload
preventing content reflow from lazy-loaded images
lazy loading with blurred image effect
image loading placeholder
lazy load css
lazy load w3school
lazy load background images

I have a SVG inside a fixed-size div (width: 350px; height: 400px;) and everything is fine once the page loads, but during the loading, the SVG is oversized and mangled up until CSS kicks in:

Here is the code, HTML first:

<div class="dashboard-tasks-completed">
  <figure>
    <svg width="100%" height="100%" viewBox="0 0 42 42" class="donut">
      <circle class="donut-hole" cx="21" cy="21" r="15.91549430918954" fill="#fff"></circle>
      <circle class="donut-ring" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#19222a" stroke-width="5"></circle>
      <circle id="active" class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#206996" stroke-width="5" stroke-dasharray="66.66666666666666 33.33333333333333" stroke-dashoffset="25"></circle>
      <circle id="completed" class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#B8E1FA" stroke-width="5" stroke-dasharray="33.33333333333333 66.66666666666666" stroke-dashoffset="58.33333333333334"></circle>
      <g class="chart-text">
        <text x="50%" y="50%" class="chart-number">3</text>
        <text x="50%" y="50%" class="chart-label"> Tasks </text>
      </g>
    </svg>
    <figcaption class="figure-key">
      <ul class="figure-key-list" aria-hidden="true" role="presentation">
        <li>
          <span class="shape-circle shape-blue"></span>2 Active (66.67%)
        </li>
        <li>
          <span class="shape-circle shape-lightblue"></span>1 Completed (33.33%)
        </li>
      </ul>
    </figcaption>
  </figure>
</div>

CSS:

.dashboard-tasks-completed {
    width: 350px;
    height: 400px;
}

.chart-text {
    font: 16px/1.4em "Montserrat", Arial, sans-serif;
    fill: #000;
    transform: translateY(0.25em);
}

.chart-number {
    font-size: 0.6em;
    line-height: 1;
    text-anchor: middle;
    transform: translateY(-0.25em);
}

.chart-label {
    font-size: 0.2em;
    font-weight: bold;
    text-transform: uppercase;
    text-anchor: middle;
    transform: translateY(0.7em);
}

.figure-key-list {
    list-style: none;
}

.figure-key-list li {
    margin: 0 0 8px;
    font-size: 14px;
}

.shape-circle {
    display: inline-block;
    vertical-align: middle;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    margin-right: 10px;
}

.shape-blue { background-color: #206996; }

.shape-lightblue { background-color: #B8E1FA }

I have created a minimal example, unfortunately it is not reproducible in neither JSFiddle or Codepen, but here is the demo in any case.

How can I overcome the issue?

SVG Oversized on Load, Put the SVG IMG element inside a div and then size the div and the img appropriately <div id="logo"> <img id="logo_img"  SVG oversized on load until CSS kicks in. 0. Page blink when using tailwindcss. 0. Whole CSS appearing, disappearing, and then re-appearing again on page load. Related.

One option is to hide the div (or other elements within) initially and then reveal it after the page finishes loading.

For example, modify your div thusly:

<div id="showme" class="dashboard-tasks-completed" style="display:none;">

And then add the following javascript:

window.onload = function () {
     document.getElementById("showme").style.display = "block";
};

The inline CSS display:none; lets the browser know not to display it, even before external CSS is loaded. Once everything is loaded, your onload event will fire, and the javascript above will display the previously-hidden elements.

SVG Oversized on Load, SVG oversized on load until CSS kicks in, As others have said, you are letting the SVG fill the page until the CSS loads and it becomes the correct size. In Firefox, SVG used as a css background-img is bitmapped at its original designed dimensions, before it is scaled up or down. This results in very blurry images when upscaling a small SVG. Some suggest to simple use a gigantic SVG so you never upscale, only downscale.

The viewBox attribute defines the position and dimension, in user space, of an SVG viewport.

The value of the viewBox attribute is a list of four numbers min-x, min-y, width and height, separated by whitespace and/or a comma, which specify a rectangle in user space which is mapped to the bounds of the viewport established for the associated SVG element (not the browser viewport).

Taken from MDN.


The viewbox property defines the region of an svg element which should be zoomed in on to fit inside it's container. However, the element will keep it's aspect ratio and not stretch to fit inside the container.


So in your case, this means that the svg element will fill all it's parents space while maintaining it's aspect ratio, until css arrives and tells it to size it self inside a 350px by 400px space.

Preventing Content Reflow From Lazy-Loaded Images, It prevents the browser from loading images until those images are in (or nearly in) After exploring the inline PNG option, I wondered if SVG might be a smaller   When used in an <image> tag SVG must be contained in a single file for privacy reasons. This bugzilla bug has more details on exactly why this is so. Unfortunately you can’t use a different tag such as an <iframe> because that won’t work as a link so you’ll have to embed the CSS in a <style> tag within the file itself.

An SVG Primer for Today's Browsers, The above draws the string "some text" in large red letters and positions the string Colors may be specified in much the same way that they are in HTML/CSS: we may see exactly where the 25% mask (and the other values) actually kick in. of "onload," since in the above code, ASV+IE fires the alert before the ellipse is   All SVG shapes are essentially built from numbers, which means all of them are fair game for randomizing. Imagine a shape with a random-looking jagged bottom like this: That’s probably normally a (straight lines), but it’s just about as easy to draw as a , which will make it transitionable (in Chrome).

Cross Domain SVG Web, The iPhone before version 2.1 does not natively support either Flash or SVG If you are loading an SVG file using the OBJECT tag and have an onload="" Note the svg\:rect trick to have Internet Explorer see namespaced SVG CSS rules. In SVG 2, this list will include x, y, width, height, cx, cy and a few other presentation attributes that were not possible to set via CSS in SVG 1.1. The new list of attributes can be found in the SVG 2 specification. Another way to set the styles of an SVG element is to use CSS properties.

276431 - external SVG not loaded from img tag, I would recommend this is not fixed until that stuff can be thoroughly looked at. Btw, I consider this a low-priority bug compared to the SVG CSS one (Bug 231179). if we could have the onload event and/or XSLT transformations (or even xbl), Just kicked off a TryServer build with these patches applied -- builds should  The viewport is like a window you look through to see an SVG’s content. The viewBox is similar to the viewport, but you can also use it to “pan” and “zoom” like a telescope. Control the viewport via width and height parameters on the svg element. Control the viewBox by adding the attribute viewBox to the svg element.

Comments
  • Dooes your CSS get loaded before any content or after? AKA is it in your <head> or at the end of your <body>?
  • @somethinghere CSS is in my <head>.
  • Investigate these steps: Delayed CSS - particularly the part about importing scripts at the bottom of the page (if possible)
  • @EGC: I don't have jQuery loading on that page, nor any other JS. The only CSS file is the file I pasted here. Those suggestions don't work for me.
  • This is called Flash Of Unstyled SVG. Read the article by Sara Soueidan
  • Yeah, I've seen workarounds like this before. If I don't find something more systematic, I'll have to use this workaround. Thanks.
  • You could also set all the css in-line on the individual elements, or embed your css in a script tag instead of an external file. Or you could pre-load your svg in a variable with js and append it to the DOM after page load.
  • You might actually get away with just setting the width and height on the div.
  • I have already set the width and height on the div. I have also tried to set exact size of the SVG, however while the oversizing issue would go away, it still remains mangled up.
  • Yeah, unfortunately until the browser gets instructions on how to size everything, that's going to be the case. This is why it isn't a workaround but actually a common method to allow assets on a page to load before displaying elements.