Redundant <path> element inside an svg file - svg

Thw following two SVG markups render identically:
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path style={inputAdornmentIcon} d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
<path d="M0 0h24v24H0z" fill="none"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path style={inputAdornmentIcon} d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
</svg>
Any idea what the second path element (<path d="M0 0h24v24H0z" fill="none"/>) in the first version actually does?

The extra path in your code is a a rectangle that covers all the svg canvas. As I've commented Google's icons are always using an extra rectangle like this for a background, but the rectangle is coming first. It's always a good idea to remove redundant elements and to simplify the markup.

Related

SVG getting distorted in IE

I am trying to embed an svg into a web page. It works fine in Chrome and Firefox but gets completely distorted in IE. Please use the below svg block of code as reference:
<svg width="33" height="33" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<path d="M21 17.625h-3.375c-.619 0-1.125.506-1.125 1.125v3.375c0 .619.506 1.125 1.125 1.125H21c.619 0 1.125-.506 1.125-1.125V18.75c0-.619-.506-1.125-1.125-1.125zm0-11.25V7.5h-9V6.375c0-.619-.506-1.125-1.125-1.125S9.75 5.756 9.75 6.375V7.5H8.625a2.24 2.24 0 00-2.239 2.25L6.375 25.5a2.25 2.25 0 002.25 2.25h15.75a2.257 2.257 0 002.25-2.25V9.75a2.257 2.257 0 00-2.25-2.25H23.25V6.375c0-.619-.506-1.125-1.125-1.125S21 5.756 21 6.375zM23.25 25.5H9.75a1.128 1.128 0 01-1.125-1.125v-11.25h15.75v11.25c0 .619-.506 1.125-1.125 1.125z" id="a"/>
</defs>
<g fill="none" fill-rule="evenodd">
<path fill="#FFF" d="M-134-821h1400V297H-134z"/>
<path fill="#FFF" d="M-134-821h1400V204H-134z"/>
<path fill="#FFF" d="M-134-821h1400V204H-134z"/>
<circle fill="#269F96" cx="16.5" cy="16.5" r="16.5"/>
<use fill="#FFF" fill-rule="nonzero" xlink:href="#a"/>
</g>
</svg>
So some browsers have a hard time with the <use>, <mask> and <def> tags.
To fix this you can sometimes "flatten" your image in the graphics editor. Remove any folders containing layers, etc etc.
You can also fix this manually. It is not hard and doing it once helps you learn SVG syntax:
Start by looking at the id referenced in the href attribute <use ... xlink:href="#a">. As you can see it is a
Now we look for the tag with id="a" In this case it is the path inside the <def> tag. This is kind of expected as the def means "define for later use".
Remove the <def> tags but keep that <path id="a" ...> and all its guts.
Move the all the attributes (except the xlink:href="#a") in the <use> tag (fill and fill-rule ) to the path#id="a" element.
Remove the <use> tag.
place all <path> tags inside the one <g> tag
In this case the other fill tags are pointless (artifacts maybe from the editor). They are just white squares so you can ditch those.
I put the circle first since this renders in order top renders on bottom. So visually the bottom layer should be a circle top layer is some drawing in white.
End result should be something like this:
No def or use tags.
All shapes inside a root g tag
Removed pointless shapes.
.
<svg width="33" height="33" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g fill="none" fill-rule="evenodd">
<circle fill="#269F96" cx="16.5" cy="16.5" r="16.5"/>
<path fill="#FFF" fill-rule="nonzero" d="M21 17.625h-3.375c-.619 0-1.125.506-1.125 1.125v3.375c0 .619.506 1.125 1.125 1.125H21c.619 0 1.125-.506 1.125-1.125V18.75c0-.619-.506-1.125-1.125-1.125zm0-11.25V7.5h-9V6.375c0-.619-.506-1.125-1.125-1.125S9.75 5.756 9.75 6.375V7.5H8.625a2.24 2.24 0 00-2.239 2.25L6.375 25.5a2.25 2.25 0 002.25 2.25h15.75a2.257 2.257 0 002.25-2.25V9.75a2.257 2.257 0 00-2.25-2.25H23.25V6.375c0-.619-.506-1.125-1.125-1.125S21 5.756 21 6.375zM23.25 25.5H9.75a1.128 1.128 0 01-1.125-1.125v-11.25h15.75v11.25c0 .619-.506 1.125-1.125 1.125z"/>
</g>
</svg>
I don't have enough reputation points to answer #cloned question in the comments. One annoying thing I have found out about IE11 is that not all versions of IE11 will break the same. The versions among Win7, Win8, Win8.1, and Win10 actually intemperate code differently.

SVG path not filling it's interior

I have a svg image which has four paths which draw the perimeters of cuboid figures with curved corners.
I want to fill the interior of these figures. However, the fill="grey" property I am using on the path does not work.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 40" x="0px" y="0px" fill="grey">
<path fill="grey" d="M5,14h6a3,3,0,0,0,3-3V5a3,3,0,0,0-3-3H5A3,3,0,0,0,2,5v6A3,3,0,0,0,5,14ZM4,5A1,1,0,0,1,5,4h6a1,1,0,0,1,1,1v6a1,1,0,0,1-1,1H5a1,1,0,0,1-1-1Z"/>
<path d="M21,14h6a3,3,0,0,0,3-3V5a3,3,0,0,0-3-3H21a3,3,0,0,0-3,3v6A3,3,0,0,0,21,14ZM20,5a1,1,0,0,1,1-1h6a1,1,0,0,1,1,1v6a1,1,0,0,1-1,1H21a1,1,0,0,1-1-1Z"/>
<path d="M2,27a3,3,0,0,0,3,3h6a3,3,0,0,0,3-3V21a3,3,0,0,0-3-3H5a3,3,0,0,0-3,3Zm2-6a1,1,0,0,1,1-1h6a1,1,0,0,1,1,1v6a1,1,0,0,1-1,1H5a1,1,0,0,1-1-1Z"/>
<path d="M18,27a3,3,0,0,0,3,3h6a3,3,0,0,0,3-3V21a3,3,0,0,0-3-3H21a3,3,0,0,0-3,3Zm2-6a1,1,0,0,1,1-1h6a1,1,0,0,1,1,1v6a1,1,0,0,1-1,1H21a1,1,0,0,1-1-1Z"/>
</svg>
Any thoughts on what I need to do to fill in these cuboids?
Thanks
Your paths are filed grey. The problem is that there is a "hole" in in every path. I've removed the "hole
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 40" fill="grey">
<path d="M5,14h6a3,3,0,0,0,3-3V5a3,3,0,0,0-3-3H5A3,3,0,0,0,2,5v6A3,3,0,0,0,5,14Z"/>
<path d="M21,14h6a3,3,0,0,0,3-3V5a3,3,0,0,0-3-3H21a3,3,0,0,0-3,3v6A3,3,0,0,0,21,14Z"/>
<path d="M2,27a3,3,0,0,0,3,3h6a3,3,0,0,0,3-3V21a3,3,0,0,0-3-3H5a3,3,0,0,0-3,3Z"/>
<path d="M18,27a3,3,0,0,0,3,3h6a3,3,0,0,0,3-3V21a3,3,0,0,0-3-3H21a3,3,0,0,0-3,3Z"/>
</svg>

Where can I find (or make) Material Design Icon set for dense layouts (20dp, desktop)

Google Material Design guidance says:
On desktop, when the mouse and keyboard are the primary input methods, measurements may be scaled down to 20dp.
Moreover, I see that new Gmail uses 20dp-sized icons(screenshot was taken on non-high DPI display):
At the same time, I cannot find MD icons of this size anywhere. Google MD icons only offers 18dp, 24dp and bigger. Same thing in the repository. But I need exactly the size of 20dp.
I tried to use icomoon.io to change grid to 20px and tried to use icon font with the size of 20px. Both methods produce blurry icons, of course.
Where can I find them?Or, how can I up/downscale existing MD icons?
UPDATE:
This is the original icon from Gmail (20px):
https://www.gstatic.com/images/icons/material/system/1x/archive_black_20dp.png
And this is SVG, with the 24px and the desired 20px size.
On my non-high DPI screen this 20px SVG is blurry.
<svg width='24' height='24' viewBox='0 0 24 24'><title>account balance</title>
<g id="g">
<path d='M0 0h24v24H0z' fill='none'></path>
<path d='M20.54 5.23l-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 6.02 3 6.5V19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.48-.17-.93-.46-1.27zM12 17.5L6.5 12H10v-2h4v2h3.5L12 17.5zM5.12 5l.81-1h12l.94 1H5.12z'></path>
</g>
</svg>
<svg width='20' height='20' viewBox='0 0 24 24'><title>account balance</title>
<use xlink:href="#g" />
</svg>
You can use the SVG attribute - shape-rendering =" crispEdges " to disable browser anti-aliasing.
https://developer.mozilla.org/ru/docs/Web/SVG/Attribute/shape-rendering
crispEdges
Indicates that the user agent shall attempt to emphasize the contrast
between clean edges of artwork over rendering speed and geometric
precision. To achieve crisp edges, the user agent might turn off
anti-aliasing for all lines and curves or possibly just for straight
lines which are close to vertical or horizontal. Also, the user agent
might adjust line positions and line widths to align edges with device
pixels.
<svg width='24' height='24' viewBox='0 0 24 24'><title>account balance</title>
<g id="g" shape-rendering="crispEdges">
<path d='M0 0h24v24H0z' fill='none'></path>
<path d='M20.54 5.23l-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 6.02 3 6.5V19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.48-.17-.93-.46-1.27zM12 17.5L6.5 12H10v-2h4v2h3.5L12 17.5zM5.12 5l.81-1h12l.94 1H5.12z'></path>
</g>
</svg>
<svg width='20' height='20' viewBox='0 0 24 24'><title>account balance</title>
<use xlink:href="#g" />
</svg>
An .svg element can take whatever size you want.
svg{border:1px solid;}
<svg width='15' height='15' viewBox='0 0 24 24'><title>account balance</title>
<use xlink:href="#g" />
</svg>
<svg width='24' height='24' viewBox='0 0 24 24'><title>account balance</title>
<g id="g">
<path d='M0 0h24v24h-24z' fill='none'></path>
<path d='M4 10v7h3v-7h-3zm6 0v7h3v-7h-3zm-8 12h19v-3h-19v3zm14-12v7h3v-7h-3zm-4.5-9l-9.5 5v2h19v-2l-9.5-5z'></path>
</g>
</svg>
<svg width='48' height='48' viewBox='0 0 24 24'><title>account balance</title>
<use xlink:href="#g" />
</svg>
<svg width='60' height='60' viewBox='0 0 24 24'><title>account balance</title>
<use xlink:href="#g" />
</svg>
UPDATE
This is an answer for the OP updated question:
I've made some changes in your code and now you have a 20/20 px svg:
Your icon has a lot of white space around the image. I've removed that space.
<svg width='20' height='20' viewBox='3 3 18 18'><title>account balance</title>
<g id="g">
<path d='M0 0h24v24H0z' fill='none'></path>
<path id="B" d='M20.54 5.23l-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 6.02 3 6.5V19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.48-.17-.93-.46-1.27zM12 17.5L6.5 12H10v-2h4v2h3.5L12 17.5zM5.12 5l.81-1h12l.94 1H5.12z'></path>
</g>
</svg>

SVG `use` is rendering blank image

I am trying to use SVGs as CSS background images, and have everything working except for importing external files with use.
Here is what I have:
CSS and HTML:
.shape1 {
background: url("shapes/shape1.svg") no-repeat;
}
<div class="shape1"></div>
Then the shapes/shape1.svg file:
<svg viewBox="0 0 100 200" xmlns="http://www.w3.org/2000/svg">
<path d="
M 10 10
l 0 180
" fill="none" stroke="#000" stroke-width="1px"/>
<use href="parts/part1.svg#build"/>
</svg>
It references the parts/part1.svg file, which contains this:
<svg viewBox="0 0 100 200" xmlns="http://www.w3.org/2000/svg">
<defs>
<path id="build" d="
M 90 10
l 0 180
" fill="none" stroke="#000" stroke-width="1px"/>
</defs>
</svg>
However, when I render everything, it only displays one line, not two.
I've tried a few things. I've tried removing the defs and just loading directly, like this:
<svg viewBox="0 0 100 200" xmlns="http://www.w3.org/2000/svg">
<path d="
M 10 10
l 0 180
" fill="none" stroke="#000" stroke-width="1px"/>
<use href="parts/part1.svg"/>
</svg>
<svg viewBox="0 0 100 200" xmlns="http://www.w3.org/2000/svg">
<path d="
M 90 10
l 0 180
" fill="none" stroke="#000" stroke-width="1px"/>
</svg>
I've also tried messing with the file paths. My directory structure is this:
index.html
shapes/
shapes/shape1.svg
parts/
parts/part1.svg
I've tried ../parts/part1.svg, etc.. Also, I am running this directly from the filesystem, so the path is: file:///Users/me/Desktop/test/index.html. I am getting no errors in the web console. Any help would be appreciated!
I am on Chrome and only care about this working on Chrome for now.
When SVG is used as an image the SVG file must be self-contained for privacy reasons.
So shape1.svg cannot access anything outside itself. You'd have to embed part1.svg into shape1.svg.
Alternatively don't use SVG as a background image, embed it via an object or iframe tag or have it inline.

clip-path not working in SVG sprite

(live example at http://codepen.io/RwwL/pen/xbNLJp)
I'm including SVGs in an app using the <symbol> element (see https://css-tricks.com/svg-symbol-good-choice-icons/ for full details as to why), and certain icons — ones that include clip-path — are not rendering when I include their icons in pages with the <use> element.
<svg style="display: none">
<symbol id="icon-pin" viewBox="0 0 24 24" enable-background="new 0 0 24 24">
<path fill="none" stroke="#2F3137" stroke-width="2" stroke-miterlimit="10" d="M12 2C8.3 2 5.3 5 5.3 8.7c0 1.2.3 2.3.9 3.3l5.4 9.9c.1.1.2.2.4.2.1 0 .3-.1.4-.2l5.4-9.9c.5-.9.9-2.1.9-3.3C18.7 5 15.7 2 12 2zm0 0" />
<clipPath id="pin-clip">
<path d="M12 11.2c-1.4 0-2.5-1.1-2.5-2.5s1.1-2.5 2.5-2.5 2.5 1.1 2.5 2.5-1.1 2.5-2.5 2.5zm0 0" />
</clipPath>
<path clip-path="url(#pin-clip)" fill="#2F3137" d="M4.5 1.2h15v15h-15z" />
</symbol>
</svg>
</div>
<h2>Normal inline SVG</h2>
<svg id="inlinePin" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24" enable-background="new 0 0 24 24">
<path fill="none" stroke="#2F3137" stroke-width="2" stroke-miterlimit="10" d="M12 2C8.3 2 5.3 5 5.3 8.7c0 1.2.3 2.3.9 3.3l5.4 9.9c.1.1.2.2.4.2.1 0 .3-.1.4-.2l5.4-9.9c.5-.9.9-2.1.9-3.3C18.7 5 15.7 2 12 2zm0 0" />
<clipPath id="inline-pin-clip">
<path d="M12 11.2c-1.4 0-2.5-1.1-2.5-2.5s1.1-2.5 2.5-2.5 2.5 1.1 2.5 2.5-1.1 2.5-2.5 2.5zm0 0" />
</clipPath>
<path clip-path="url(#inline-pin-clip)" fill="#2F3137" d="M4.5 1.2h15v15h-15z" />
</svg>
<h2>Inline SVG using sprite</h2>
<svg>
<use xlink:href="#icon-pin">
</svg>
Here's how it's rendering:
It's broken in the same way across Chrome/Firefox/Safari, so it seems to most likely just be something I'm not understanding about the way other elements need to be referenced in SVG, especially when a symbol is being pulled in via a use. IE11 is also not rendering correctly, but in a slightly different way (no dot in the middle of the pin, but no solid square box like the others).
The problem is caused by the very first line
<svg style="display: none">
Removing display: none will render your svg referencing the inline sprite just fine.
This does at first seem a bit odd since the spec tells us
The ‘display’ property does not apply to the ‘symbol’ element; thus,
‘symbol’ elements are not directly rendered even if the ‘display’
property is set to a value other than none, and ‘symbol’ elements are
available for referencing even when the ‘display’ property on the
‘symbol’ element or any of its ancestors is set to none.
But reading further down the spec it becomes apparent why setting display: none causes this unexpected rendering:
The ‘display’ property affects direct rendering into offscreen
canvases also [...] Setting display: none on a child of a
‘clipPath’ element will prevent the given child element from
contributing to the clipping path.
Thus, setting display: none globally on the svg inhibits rendering of these offscreen canvases leaving you with the incomplete clip path, although it can still be referenced. Removing the display-attribute from the root svg and setting it directly to the clipPath will demonstrate the same behaviour.
To hide your sprite svg you could go for something like
<svg width="0" height="0">
Update:
IE and Firefox seem to be even a bit more stringent on rendering the offscreen canvases when putting a clipPath inside a symbol. Since symbols itself are never rendered, the contained clipPath will keep missing the offscreen rendering and can therefore not meaningfully be applied to any element. You should put the clipPath right outside the symbol which works well in IE, FF and Chrome.
<svg>
<clipPath id="pin-clip">
<path d="M12 11.2c-1.4 0-2.5-1.1-2.5-2.5s1.1-2.5 2.5-2.5 2.5 1.1 2.5 2.5-1.1 2.5-2.5 2.5zm0 0" />
</clipPath>
<symbol id="icon-pin" viewBox="0 0 24 24" enable-background="new 0 0 24 24">
<path fill="none" stroke="#2F3137" stroke-width="2" stroke-miterlimit="10" d="M12 2C8.3 2 5.3 5 5.3 8.7c0 1.2.3 2.3.9 3.3l5.4 9.9c.1.1.2.2.4.2.1 0 .3-.1.4-.2l5.4-9.9c.5-.9.9-2.1.9-3.3C18.7 5 15.7 2 12 2zm0 0" />
<path clip-path="url(#pin-clip)" fill="#2F3137" d="M4.5 1.2h15v15h-15z" />
</symbol>
</svg>

Resources