Setting Svg Element Width/Height Attributes Using CSS in Firefox

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



Leave a reply



Submit