Search code examples
htmlsvgsafaricross-browseralignment

Safari not rendering SVGs to the desired size/height (SVGS are clipped)


I have some responsive inline SVGs I made. Their sizes render as I want them to in Chrome, Firefox and Edge, but in Safari they escape their containers/are cut off. For some reason their containers doesn't stretch to accommodate them. The following screenshot demonstrates the unwanted, cut-off Safari rendering:

SVGS don't fit

There are known issues with SVG rendering in Safari, and I have tried all the fixes out there I have found to the best of my ability (here, here, here, and here), but I can't manage to make the containers fit the SVGs in Safari. It is in part because things are a little complicated with my javascript and I'm still a beginner, forgive me if my codepen is a bit messy.

This is my codepen. :http://codepen.io/ihatecoding/pen/Bzgqqa

What my jquery does: it makes SVGs as large as possible until they take up 1/3 of the screen height, at that point it won't let them get taller.

To help you focus on what matters :

  • The SVGs are all of class .areaSVG
  • The SVG parents/containers are always .ey-col-svg
  • The entire footer is #indexFooter
  • The main background image that is supposed to resize according to the height of the landing footer is #section0img

The current version that is working the best has the following format for the svg container:

.ey-col-svg {
    display: block;
    max-height: calc(30vh - 1vw - 63px);
    text-align: center;
    box-sizing: content-box;
    padding: 0;
    margin: -2vh 0 0 0;
}

This is the css for the SVGs before the javascript makes them visible and adjusts their height:

.areaSVG {
    overflow: visible;
    display: none;
    box-sizing: content-box;
    margin: 0;
    padding: 1.6vh 0 1vh 0;
}

Again, to repeat The javascript I have currently implemented adjusts the height of the SVGs (whose class is areaSVG).

This is the most relevant part of my jQuery script; it controls the size of the the SVGs. As I mentioned above, this script makes the SVGs as large as possible until they take up 1/3 of the screen height, and at that point it won't let them get taller:

  function resizeSVG() {

// the row
 var $linksRow = $('.ey-nav-bar');

// the text
   var $areaText = $('.ey-text-content');

//the entire row below "research Area"



         // the actual svg container

      var $area = $('.areaSVG');

      var scale = 0.6;

         //the wrapper containing the svg div, its height and its width
      var $eyCol = $(".ey-col-svg");
      var eyWidth = $eyCol.width();
      var eyHeight = $eyCol.height();

              //the window
      var winHeight = $(window).height();
      var winWidth = $(window).width();

      //max Height caclulated based on window
      var maxHeight = .33 * winHeight;


        // if the height of the column is less than the width, and below the max height

      if (eyHeight < eyWidth && eyHeight < maxHeight)

                  //make the height of the svg the max heihgt
        $area.height(maxHeight);

          // use the scaling factor times the width of the svg wrapper

      var imageWidth = scale * $eyCol.width();
                // get the hight of the column       

      var imageHeight = $eyCol.height();


          // will be the dimensions used to size lenth and width of the svg

      var tot;

          //apsect ratio of the screen (horizontal/vertical)

      var ratio = winWidth / winHeight;
          // if the screen is landscape or if the user has left the landing section


        tot = imageWidth > imageHeight ? imageHeight: imageWidth;

maxTextHeight = maxHeight * .07;
maxTotHeight = maxHeight * .5;

if (tot < maxTotHeight)

{        $area.css("height", tot);

}
        else
        {


  $area.css("height", maxTotHeight);
  $areaText.css("height", maxTextHeight);

        }

minLinksHeight = maxHeight * .8;

var linksHeight = $linksRow.height();


    }

(Note: the resulting SVG heights are subsequently used by another function, not seen here, to control the size of the main image).

This is my introductory formatting code for each inline svg:

    <svg class="areaSVG notFixed index" viewBox="20 0 37 75" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

Any help would be very appreciated, I really would like to see this to render properly in Safari!


Solution

  • I figured out a combinations of CSS settings that now make the SVGs Render in entirety in Safari (as well as in Chrome, Firefox, and Edge); Safari no longer clips them/cuts them off. My sizing and calculations are not perfect, but the display settings work, you will need to tweak the size according to your own needs adjusting the height of the SVG container/parent. My javascript (which controls other aspects of the page) are wonky, but the SVG settings are more or less correct. I hope this helps someone.

    Here is the codepen: http://codepen.io/ihatecoding/pen/zBgqgp

    The inline html declaration of the SVG

    I adjusted my viewBox and removed my overflow: visible setting according to the suggestions of @Paul Lebeau Note that the preserveAspectRatio is intentionally not specified because it should remain with the default setting, xMidYMid meet (unlike other Safari SVG fixes which change it to none).

    Here is the code:

     <svg class="areaSVG notFixed index" viewBox="0 0 80 80"  xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    

    The CSS

    If you are not using my javascript to resize the svgs, use the following css settings for the SVG container (.ey-col-svg) and the SVG itself (.areaSVG):

    /* the SVG parent/container */
    
    .ey-col.svg {
        display: block;
        height: auto;
        text-align: center;
        box-sizing: border-box;
        padding: 0;
    }
    
    
    /* the SVG itself */
    
    .areaSVG {
        display: inline-block;
        max-height: 15vh; 
        box-sizing: content-box;
        margin: 0;
    }
    

    Notes about my javascript

    If you are using my messy javascript, please note both the container and the SVG will both initially have the setting display: none in the CSS, and then the javascript will change both of them to have the same displays settings I have shown above [with the container (.ey-col-svg) set to display: block and the SVG (.areaSVG) set to display: inline-block].

    Also, my javascript in my codepen has changed. It now works better if I adjust the height of the container (.ey-col-svg) instead of the of SVG (.areaSVG) itself. Another option that might work better for users is changing the max-height of the container, instead of the height (as I have done).