Setting SVG element width/height attributes using CSS in Firefox
Not all SVG element attributes can be styled with CSS. Only the ones designated as "properties" can be. See the list below from the SVG specification.
https://www.w3.org/TR/SVG/propidx.html
The (in development) SVG 2 specification will allow all attributes to be styled with CSS. And some browsers are starting to support that. But for now you won't be able to do it.
Update: Not all attributes will be styleable in SVG2. The list of styleable presentation attributes is here.
Why does a rect require width and height attribute in Firefox?
- In SVG 1.1 height and width are attributes i.e. you can't set the height and width via CSS.
- In SVG 2 it is proposed width and height should be CSS properties.
Back in 2016 only Chrome had implemented this part of the unfinished SVG 2 specification, since then Firefox has also implemented it so the testcase works as expected.
Styles not applied to SVG element in firefox and IE
The issue appears to be caused by capitalizing the svg
selector in CSS. Take the following code snippet for example, where using SVG
does not work, but svg
does.
Example:
.wrap-a > SVG { background: blue;}.wrap-b > svg { background: green;}
<a class="wrap-a"> <svg width="226" height="226"><circle cx="110" cy="107" r="80" stroke="black" stroke-width="5" fill="red" /></svg></a><a class="wrap-b"> <svg width="226" height="226"><circle cx="110" cy="107" r="80" stroke="black" stroke-width="5" fill="red" /></svg></a>
svg/ element does not respect 100% height/width in Firefox
You need to give html
a height of 100% as well:
body, html {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
jsfiddle
Svg - Firefox calculating wrong width when setting stroke-width
In path commands commas can only be placed between numbers if the markup is to be valid. The comma preceding the Z is invalid in your example and Firefox correctly rejects this, terminating the path at this point. Chrome incorrectly continues to parse the path.
How to set width and height attributes dynamically on SVG image with Javascript?
Your call to $(svgDoc)
won't wrap the correct <svg>
element.
To get it, you would need to do $("svg", svgDoc)
so it uses the correct document context and search for the correct <svg>
element.
const svg_file = new Blob([`<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.1.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 502.2" style="enable-background:new 0 0 512 502.2;" xml:space="preserve">
<style type="text/css">
.st0{fill:#7C7A7D;}
</style>
<path class="st0" d="M25.1,178.7L0.5,40.9C-2.8,22,9.8,3.9,28.7,0.5l0,0c18.9-3.4,37,9.2,40.4,28.2l24.5,137.8
c3.4,18.9-9.2,37-28.2,40.4l0,0C46.5,210.2,28.5,197.6,25.1,178.7z"/>
<path class="st0" d="M55.2,137.9l138.9-17.3c19.1-2.4,36.5,11.2,38.8,30.2l0,0c2.4,19.1-11.2,36.5-30.2,38.8L63.8,206.9
c-19.1,2.4-36.5-11.2-38.8-30.2l0,0C22.6,157.7,36.2,140.3,55.2,137.9z"/>
<path class="st0" d="M506.6,304.6c0-0.2,0.1-0.5,0.1-0.7c6-27.2,7.5-55.7,3.8-84.7c-2.1-16.3-5.8-32.1-10.8-47.2c0,0,0,0,0-0.1
c-0.5-1.5-1-3-1.6-4.6c-0.3-0.8-0.5-1.5-0.8-2.3c-0.3-0.8-0.6-1.5-0.9-2.3c-0.6-1.5-1.1-3-1.7-4.5c0,0,0,0,0-0.1
c-5.9-14.8-13.3-29.2-22.2-43C456.5,90.7,437,69.9,414.9,53c-0.2-0.1-0.4-0.3-0.6-0.4c-0.8-0.6-1.6-1.2-2.3-1.8
C361.4,12.7,296.6-6.6,229.5,2C176.8,8.7,128,32,89.7,67.8c-1.7,1.6-3.2,3.3-4.4,5.1c-25.2,24.8-44.8,54.7-57.7,87.7
c-7.7,19.8,4.3,41.8,25,46.3l0,0c16.7,3.6,33.3-5.6,39.6-21.5C124.1,104.2,211.9,55,299.7,73.8c62.4,13.4,110.8,58.1,132,114.2
c0.1,0.3,0.2,0.6,0.4,1c0.1,0.3,0.2,0.6,0.3,1c20,56.5,12,121.9-27.1,172.4c-61,78.9-176.2,93.7-255.1,32.7
c-30.5-23.6-52.5-56-63.2-92.5c-4.8-16.2-20.7-26.4-37.5-24.2h0c-21.2,2.7-34.9,23.7-28.8,44.2c10.3,34.5,27.8,65.7,50.6,92
c1.2,2,2.5,3.8,4.1,5.6c81,89.3,218.5,109.8,322.7,42.4c56.8-36.8,93.8-93.3,107.9-155C506.1,306.5,506.3,305.5,506.6,304.6z"/>
</svg>`], {type: "image/svg+xml"});
const svgSize = { width: 512, height: 502 };
const reader = new FileReader();
reader.readAsDataURL( svg_file) ;
reader.onload = evt => {
const dataUrl = reader.result;
let svgDoc = dataURLToSVGDoc(dataUrl);
let unit = 'px';
$("svg", svgDoc).attr('width', svgSize.width + unit);
$("svg", svgDoc).attr('height', svgSize.height + unit);
let newDataURL = svgDocToDataURL(svgDoc);
const img = new Image();
img.src = newDataURL;
img.onload = e=>console.log('loaded', img.width);
function dataURLToSVGDoc(dataURI) {
// Set default result.
let svgDoc = null;
// Set RegEx vars.
let svgURIRegEx = /data:image\/svg\+xml;(base64|charset=utf8),(.*)/;
// Read data URI.
let uriMatch = svgURIRegEx.exec(dataURI);
if (uriMatch) {
// Set default SVG string.
let svgStr = '';
// Base64? Convert Base64 -> SVG.
if (uriMatch[1] === 'base64') {
svgStr = atob(uriMatch[2]);
// Not Base64, ensure no URL-encoded characters.
} else {
svgStr = decodeURI(uriMatch[2]);
}
// Convert SVG string -> SVG doc.
let parser = new DOMParser();
svgDoc = parser.parseFromString(svgStr, 'image/svg+xml');
}
// Return result.
return svgDoc;
}
function svgDocToDataURL(svgDoc, base64) {
// Set SVG prefix.
const svgPrefix = "data:image/svg+xml;";
// Serialize SVG doc.
var svgData = new XMLSerializer().serializeToString(svgDoc);
// Base64? Return Base64-encoding for data URL.
if (base64) {
var base64Data = btoa(svgData);
return svgPrefix + "base64," + base64Data;
// Nope, not Base64. Return URL-encoding for data URL.
} else {
var urlData = encodeURIComponent(svgData);
return svgPrefix + "charset=utf8," + urlData;
}
}
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Width and height do not work in SVG use element
width, and height have no effect on use elements, unless the element referenced has a viewbox
Get width/height of SVG element
Use the getBBox
function:
The
SVGGraphicsElement.getBBox()
method allows us to determine the coordinates of the smallest rectangle in which the object fits. [...]
http://jsfiddle.net/Xkv3X/1/
var bBox = svg1.getBBox();
console.log('XxY', bBox.x + 'x' + bBox.y);
console.log('size', bBox.width + 'x' + bBox.height);
Related Topics
Sunburst Effect with CSS3 Gradient
Overflow:Hidden on Body Is Broken in iOS6
How to Stop Mobile Safari from Setting Fixed Positions to Absolute on Input Focus
Variable Sized Column with Ellipsis in a Table
Reset Angle of Text in Skewed Div Using CSS
CSS Element Child VS Child with Text Node
Bootstrap 3 Column Wraps in Portrait View Only
How to Compile an Existing Project Because Compass Can't Find It
CSS Animated Circles - Stop Center Content from Rotating
Css3 Transition ( Vendor Prefixes) Crashes Safari Immediately
Safari Page-Break-Inside:Avoid Not Working
How to Get Multiple Borders with Rounded Corners? CSS
Css3 Image Crossfade (No JavaScript)
Help with Div - Make Div Fit the Remaining Width
CSS Rgba Transparency Bug in Chrome
How to Target CSS Class Names That Start with Digit
How to Create Multiple Rows Using Semantic Markup in Bootstrap 3