Skip to content

Instantly share code, notes, and snippets.

@shshaw
Created January 14, 2016 15:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shshaw/afbade9155052b4caebd to your computer and use it in GitHub Desktop.
Save shshaw/afbade9155052b4caebd to your computer and use it in GitHub Desktop.
A vanilla JavaScript fix (of sorts) for responsive SVGs in Safari and some other WebKit browsers.
/*
Title: Vanilla JavaScript to fix responsive SVGs in some versions of Safari.
What it does: Stops the problem I described here: http://stackoverflow.com/q/17158717/1147859 Reference URL of the issue: http://codepen.io/benfrain/full/fhyrD
It will work on all SVGs referenced inside objects as long as given the class .emb:
<object class="emb" data="img/cup.svg" type="image/svg+xml"></object>
And also any inline SVGs.
Necassary CSS (!important should be optional)
svg {
height: 100%!important;
width: 100%!important;
}
Author: Ben Frain
Date: 21.6.2013
Version 0.1
Pointers on the embedded SVGs from Erik Dahlström: http://xn--dahlstrm-t4a.net/svg/html/get-embedded-svg-document-script.html from this Stack Overflow question: http://stackoverflow.com/a/8134698/1147859
*/
// wait until all the resources are loaded
window.addEventListener("load", function(){
findSVGs();
inlineSVGs();
},false);
window.addEventListener("resize", function(){
findSVGs();
inlineSVGs();
},false) ;
// fetches the document for the given embedding_element
var getSubDocument = function(embedding_element) {
if (embedding_element.contentDocument)
{
return embedding_element.contentDocument;
}
else
{
var subdoc = null;
try {
subdoc = embedding_element.getSVGDocument();
} catch(e) {}
return subdoc;
}
};
var findSVGs = function() {
// Find all emements with a class of .emb
var elms = document.querySelectorAll(".emb");
// Make a loop for each
for (var i = 0; i < elms.length; i++) {
// Get the SVG whether content or iframe etc
subdoc = getSubDocument(elms[i]);
// Get the internal SVG document
SVGdoc = subdoc.documentElement;
// If it exists set the SVG to be width and height 100%;
if (subdoc)
SVGdoc.setAttribute("height", "100%");
SVGdoc.setAttribute("width", "100%");
}
};
var inlineSVGs = function() {
// Find all inline elements
var inlines = document.getElementsByTagName("svg");
// Make a loop for each
for (var i = 0; i < inlines.length; i++) {
// Get the computed width of the SVG as determined by UA
ComputedSVGWidthRaw = inlines[i].getBoundingClientRect().width.toFixed(0);
ComputedSVGWidth = inlines[i].getBoundingClientRect().width.toFixed(0) + 'px';
// If no height or width on SVG:
if (!inlines[i].hasAttribute("height") || !inlines[i].hasAttribute("width")) {
// If it has no width/height and ALSO DOES NOT have a viewBox:
if (!inlines[i].hasAttribute("viewBox")) {
// Then set the height to be the same as the ComputedSVGWidth
inlines[i].setAttribute("height", ComputedSVGWidth);
inlines[i].setAttribute("width", ComputedSVGWidth);
}
// If it has no width/height but DOES have a viewbox:
else {
// Split contents of the viewBox into an array
viewBox = inlines[i].getAttribute("viewBox").split(/[\s,]+/);
// With viewBox Width and Height are the last two values
viewBoxHeight = viewBox[viewBox.length-1];
viewBoxWidth = viewBox[viewBox.length-2];
HeightProportionFromViewBox = (viewBoxHeight / viewBoxWidth);
HeightfromViewBoxProportion = (ComputedSVGWidthRaw * HeightProportionFromViewBox).toFixed(0) + 'px';
// OK, let's set this Mofo:
inlines[i].setAttribute("width", ComputedSVGWidth);
inlines[i].setAttribute("height", HeightfromViewBoxProportion);
}
}
// At this point we have height and width
else {
// Get the height/width of the SVG sans units
OriginalSVGheight = parseInt(inlines[i].getAttribute("height"), 10);
OriginalSVGwidth = parseInt(inlines[i].getAttribute("width"), 10);
// Get the ratios of height and width
RatioOfHeightToWidth = (OriginalSVGheight / OriginalSVGwidth).toFixed(0);
RatioOfWidthToHeight = (OriginalSVGwidth / OriginalSVGheight);
// Define each width and height as value and add px to it - remove decimals to prevent rouding discrepancies
HeightAsProportion = (RatioOfHeightToWidth * ComputedSVGWidthRaw).toFixed(0) + 'px';
WidthAsProportion = (parseInt(HeightAsProportion, 10) * RatioOfWidthToHeight).toFixed(0) + 'px';
inlines[i].setAttribute("width", WidthAsProportion);
inlines[i].setAttribute("height", HeightAsProportion);
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment