Hi! I’m Sara!
Presentation Attributes will override inherited styles specified on a parent element.
Problematic when: re-using components with <use> (e.g. SVG sprites)
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="300px" height="300px" viewBox="0 0 300 300"> <polygon fill = "#FF931E" stroke = "#ED1C24" stroke-width = "5" points = "279.1,160.8 195.2,193.3 174.4,280.8 117.6,211.1 27.9,218.3 76.7,142.7 42.1,59.6 129.1,82.7 197.4,24.1 202.3,114 "/> </svg>
Styles lower in the diagram override those above them
<style> circle {fill: orange;} </style> <svg version="1.1" viewBox="0 0 400 400"> <g fill="yellow"> <circle cx="100" cy="100" r="100" fill="blue" /> <!-- ... --> </g> </svg>
<style> use {fill: orange;} </style> <svg version="1.1" viewBox="0 0 400 400"> <symbol id="myCirc" viewBox="0 0 32 32">
<circle cx="100" cy="100" r="100" fill="blue"/>
</symbol>
<use xlink:href="#myCirc"...></use>
</svg>
This is common in reusable SVG icons in icon sprites.
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" style="display: none;"> <symbol id="icon-twitter" viewBox="0 0 35 35"> <!-- Twitter icon markup --> </symbol> <symbol id="icon-github" viewBox="0 0 35 35"> <!-- Github icon markup --> </symbol> <!-- more icons here... --> </svg>
<svg class="icon-twitter"> <use xlink:href="#icon-twitter"></use> </svg>
<svg class="icon-twitter"> <use xlink:href="icons.svg#icon-twitter"></use> </svg>
Does not currently work in any version of IE.
circle { fill: inherit; stroke: inherit; }
Force the browser into inheriting the styles by taking advantage of the cascade
P.S. Make sure you set this rule _before_ any new style declarations in the CSS.
svg * { all: inherit; }
Extreme Measure
Note that this will:
1. reset all the SVG attributes that can be set in CSS except transforms for now (which is good considering the use case, cz u would want to change styles but not transformations + the latter are chained into a matrix!)
2. reset _all_ of those properties — so if u don't specify an alternate value, it will default to browser defaults.
3. This is great for overriding and "bare-boning" SVG elements to allow you to control them completely from the CSS (use case: an SVG whose innards you can't control)
Extra Tip: Styling Contents Of <use>
Further Styling Control w/ CSS Variables
<svg class="bird">
<use xlink:href="#bulbul"></use>
</svg>
use {
color: gray;
fill: currentColor; /* this will be the base fill color inherited by all elements inside <use> */
/* define variables here */
--secondaryColor: yellow;
--tertiaryColor: black;
}
Continued
HTML
CSS
Further Styling Control w/ CSS Variables
<symbol id="bulbul" viewBox="0 0 300 200">
<path id="body" d="…" />
<path id="tail" fill="var(--tertiaryColor)" d="…" />
<path id="head" fill="var(--tertiaryColor)" d="…" />
<path id="vent" fill="var(--secondaryColor)" d="…" />
</symbol>
SVG
Further Styling Control w/ CSS Variables
Links (<a>) inside an SVG embedded as an <object> will open inside the boundaries of that <object>, not in the main page.
(—predictably so, considering that <object> is similar in functionality to <iframe>.)
<img src="logo.svg" alt="Company Logo" />
.el {background: url(mySVG.svg);}
<object type="image/svg+xml" data="mySVG.svg">
<!--fallback-->
</object>
<embed type="image/svg+xml" src="mySVG.svg" />
<iframe src="mySVG.svg">
<!--fallback-->
</iframe>
<svg><!--SVG content--></svg>
Learn more about it: http://sarasoueidan.com/blog/svg-picture/
<picture> <source type="image/svg+xml" srcset="path/to/image.svg"> <img src="path/to/fallback.png" alt="..."> </picture>
Better fallback and art direction options.
<a role="link" tabindex="0" xlink:href="..." xlink:title="..." xlink:target="_parent" ...> Visit Page </a>
Specify the target of the link using the xlink:target attribute
Remember to...
Setting `fill: none` on path area will disable pointer events on that area.
pointer-events: visiblePainted;
The given element can be the target element for pointer events when the ‘visibility’ property is set to visible and when the pointer is over a "painted" area. The pointer is over a painted area if it is over the interior (i.e., fill) of the element and the ‘fill’ property has an actual value other than none or it is over the perimeter (i.e., stroke) of the element and the ‘stroke’property is set to a value other than none.
Set the fill to "transparent" instead of "none"
<path ... fill="transparent" ...></path>
OR
Change the value of the `pointer-events` property on the element.
For a list of values, refer to the specification.
Certain CSS and JS characters — e.g "<" — will cause an XML error when used inside an SVG file.
<path style="fill: maroon; stroke:..." ></path>
Inline styles using a style attribute:
Styles embedded using a <style> tag inside the <svg>:
External styles:
<style> rect { stroke-width: 1em; } </style>
<?xml-stylesheet type="text/css" href="style.css"?>
Script block:
External script reference:
<script> //JS here </script>
<script xlink:href="file_name.js"></script>
Conflicting characters will not be an issue if the JS is external.
The Solution
Wrap your CSS and/or JS in a CDATA block:
<style>
//<![CDATA[
CSS here
//]]>
</style>
<script>
//<![CDATA[
JS here
//]]>
</script>
OR
Manually convert your conflicting characters to their data formats.
< > &
Placing internal CSS style sheets within CDATA blocks is sometimes necessary since CSS style sheets can include characters, such as ">", which conflict with XML parsers. Even if a given style sheet does not use characters that conflict with XML parsing, it is highly recommended that internal style sheets be placed inside CDATA blocks.
Cropping the SVG using the viewBox attribute can yield unwanted visible overflow.
LIVE DEMO'ING
Change the aspect ratio of the <svg> (the viewport) to match that of the new viewBox.
OR
Clip the overflow out using clip-path
<svg ... clip-path="url(#clipper") viewBox="vx vy width height">
<defs>
<clipPath id="clipper">
<rect x="vx" y="vy" width="100%" height="100%"></rect>
</clipPath>
</defs>
<!-- other svg content & styles -->
</svg>
This trick can also be used to visualise and troubleshoot viewBox problems.
You might want to reposition and/or scale the viewBox after clipping/cropping it. Do that using the preserveAspectRatio attribute.
Read
Everything you need to know about the SVG viewport, viewBox and preserveAspectRatio:
http://sarasoueidan.com/blog/svg-coordinate-systems
(Includes an interactive demo.)
CSSOM methods produce unexpected values when retrieving an SVG element's bounding box properties.
CSSOM's `getClientRects()` and `getBoundingClientRect()` method(s) can be used to get the top, right, bottom and left offset coordinates of an element and the width and height of the element's bounding rectangle.
...can yield unexpected results.
getBoundingClientRect()
expected result
Solution
Use getBBox() instead of the CSSOM Methods
var svgElement = document.getElementById('el'); bbox = svgElement.getBBox(); console.log( bbox.x ) ; console.log( bbox.y ) ; console.log( bbox.width ) ; console.log( bbox.height ) ;
Important Note
[getBBox()] returns the tight bounding box in current user space (i.e., after application of the ‘transform’ attribute, if any) on the geometry of all contained graphics elements, exclusive of stroking, clipping, masking and filter effects).
SVG lacks the concept of relative positioning.
You cannot position an element relative to another element — SVG elements are not governed by a box model.
A Workaround
The inner <svg> gets its properties from the nest’s bounding box properties, and the bird goes INSIDE the <svg> and is positioned relative to it.
Root <svg>
Extra Tip
Use an element's bounding box properties (bbox.x, bbox.y, bbox.width, bbox.height) to define the viewBox area when cropping an SVG to that element.
viewBox="x y width height"
viewBox="bbox.x bbox.y bbox.width bbox.height"
...instead of using an error-prone graphics editor.
Thank You!