View
237
Download
1
Category
Preview:
DESCRIPTION
Scalable Vector Graphics, or SVGs, are the new "big thing" in web design today, and for a good reason. With the proliferation of retina screens and high resolution displays, we need to adopt techniques that allow us to serve graphics that look good on all screens in all circumstances, and because SVGs offer resolution-independent, fully scalable and crystal clear graphics, it is safe to say that they are the future graphics format of the web. In this talk we're going to see how SVGs can be styled in CSS, and how they can be animated using CSS animations and transitions. We're also going to cover "responsifying" SVGs using CSS media queries, and how we can control the size and looks of SVGs allowing them to adapt to different screen sizes. We'll cover a short workflow from a vector graphics editor to a responsive animated graphic on screen.
Citation preview
Styling & Animating Scalable Vector
Graphics with CSS
CSSConf - May 27th 2014, Florida @SaraSoueidan / sarasoueidan.com
Hello,I’m Sara.
Scalable Vector Graphics (SVG) is an XML-based vector image format for two-dimensional graphics with support for interactivity and animation.
Why SVGs?
➔ SVGs are accessible
➔ Scalable & Resolution Independent
➔ Very Good Browser Support
➔ Smaller sizes (can be gzipped)
➔ Built-in Graphics Effects (Blend Modes, Filters, etc.)
➔ Interactive and Styleable (CSS and Javascript)
➔ SVGs Have Tools
Creating SVGs
Adobe Illustrator Inkscape (Free) Sketch (Mac OS X only)
Optimize Exported Code (Standalone Tools)
http://goo.gl/0XvzHs
SVG Editor by Peter Collingridge (Online)
Optimize Exported Code (Standalone Tools)
SVG O (NodeJS-Based + GUI)
Peter’s SVG Editor
Clean Up & Give Classes
bird.svg
Replace generic class names with semantic ones that describe your illustration.
Styling SVGs with
CSS
SVG Presentation Attributes
<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> star.svg
Shared with CSS SVG-onlyfont
font-family
font-size
font-size-adjust
font-stretch
font-style
font-variant
font-weight
direction
letter-spacing
text-decoration
unincode-bidi
word-spacing
visibility
text-rendering
writing-mode
clip-path
mask opacity
filter
pointer-events
image-rendering
clip
color
cursor
display
overflow
clip-ruleflood-colorflood-opacitystop-opacitykerningtext-anchorcolor-profile color-rendering
fill fill-opacityfill-rulemarkermarker-end marker-mid marker-start
strokestroke-width
stroke-opacitystroke-dasharraystroke-dashoffsetstroke-linecapstroke-linejoinstroke-miterlimitalignment-baselinebaseline-shiftshape-renderingglyph-orientation-horizontalglyph-orientation-verticalcolor-interpolationcolor-interpolation-filtersdominant-baselinelighting-colorstop-colorenable-background
http://goo.gl/LVkevr
Inline Styles (style=” ”)
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style=”width: 300px; height: 300px;” viewBox="0 0 300 300">
<polygon
style = ”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>star.svg
Embedded Styles (<style>) Inside svg
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="300px" height="300px" viewBox="0 0 300 300">
<style type=”text/css”><![CDATA[
selector {/* styles */}]]>
</style><g id=”..”> … </g>
</svg> filename.svg
Embedded Styles (<style>) Outside svg
<!DOCTYPE html><!-- HTML5 document --><html> <head> ... </head> <body><style type=”text/css”>
/* style rules */</style><!-- xmlns is optional in an HTML5 document --><svg version="1.1" viewBox="0 0 300 300">
<!-- SVG content --></svg></body> </html>
filename.html
External Style Sheets
<?xml version="1.0" standalone="no"?><?xml-stylesheet
type="text/css" href="style.css"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
width=".." height=".." viewBox="..">
<!-- SVG content -->
</svg> filename.svg
Style Rules (Selectors) Type Selectors:g {/* style a group */}circle, rect { fill: #009966; }
Class and ID Selectors:.arrow-head { /* styles */ }#bird { /* styles */ }
Dynamic Pseudo-Class Selectors:.icon:hover, .icon:active, .icon:focus { /* styles */ }
Pseudo-Class Selectors::first-child, :last-child, :nth-*-child(), :visited, :link and :lang, :last-of-type, :first-of-type, :not(), :nth-*-type(), :only-child, :only-of-type, ...
Children Selectors:g > circle {/* styles */}
Notes: Pseudo-elements/Generated Content don’t work.
Style Cascades
http://goo.gl/QHFp6w
Presentation attributes count as low level “author stylesheets” and are overridden by any other style definition (external stylesheets, document stylesheets and inline styles).
<circle cx="100" cy="100" r="75" fill="blue" style="fill:deepPink;" />
Example: Simple Hover Effect (Iconic)
Changing the stroke color and stroke width. Fading background in on hover.
http://goo.gl/Fofspo
Embedding
SVGs
http://goo.gl/oiYssv
1 <img src=”image.svg” alt=”Site Logo” />
2<object type="image/svg+xml" data="image.svg">
<img src=”fallback.jpg”><!-- fallback -->
</object>
3 <embed type="image/svg+xml" src="image.svg" />
4<iframe src="image.svg">
<!-- fallback here -->
</iframe>
5 <svg> … </svg> <!-- XHTML/HTML5 Document -- >
6 #el { background-image: url(image.svg); }
SVG Embed Technique Links, External Styles, Interactivity, CSS Animations
<img src=”img.svg” alt=”” /> Nope*
<object type="image/svg+xml" data="image.svg"></object> Yep
<embed type="image/svg+xml" src="image.svg" /> Yep
<iframe src="image.svg"></iframe> Yep
Inline <svg> … </svg> Yep
background-image: url(image.svg); Nope*
* CSS animations won’t be played, but SVG (SMIL) animations will be preserved..
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="350px" height="400px” viewBox="0 0 350 400" >
<style type="text/css"><![CDATA[
.fish {transform-origin: 50%;animation: shake .4s linear infinite;
}@keyframes shake {
to {-webkit-transform: rotate(-10deg);}}
]]></style> <g id="bear" …> <!-- ... --></g></svg>
bear-css.svg
Example: CSS Animation
Example(Embedded)
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="350px" height="400px” viewBox="0 0 350 400" > <g id="bear" …>
<!-- … --><g class=”fish”>
<!-- ... --><animateTransform attributeName="transform"
type="rotate" begin="0s" dur=".4s" from="0 380 530" to="-10 380 530" repeatCount="indefinite" fill="freeze" />
</g></g></svg>
bear-smil.svg
Example: SVG (SMIL) Animation
Example (Embedded)
Responsifying
SVGs
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width=”300px height=”300px” > <style type="text/css">
.eye{fill:#8B6A62;}
.face{fill:#F6E6E5;}
.head{fill:#F7A591;}/* ... */
</style> <path class="body" d=”...”> <!-- ... --></svg>
owl.svg
Example
1. Remove Width & Height, Add viewBox
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 300 300"> <style type="text/css">
/* ... */ </style> <path class="body" d=”...”> <!-- ... --></svg>
owl.svg
2. Preserve Aspect Ratio
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 300 300" preserveAspectRatio="xMinYMin meet"> <style type="text/css">
/* ... */ </style> <path class="body" d=”...”> <!-- ... --></svg>
owl.svg
Note: Without viewBox, preserveAspectRatio has no effect.
http://goo.gl/b50HY8
3. Embed & Wrap in a container<!DOCTYPE html><!-- HTML5 document --><html> <head> ... </head>
<body><div class=”my-svg-container”>
<object type="image/svg+xml" data="owl.svg" class=”my-svg”>
<!-- fallback here --> </object>
</div></body></html>
responsive-owl.html
SVG can be embedded as <object>, <img> or inline as an <svg>. The technique will work for all three embeds.
4. Padding Hack on Container
.my-svg-container {height: 0;position: relative; /* create positioning context for svg
*/width: width-value; padding-top: (SVG height / SVG width) * width-value;
}
responsive-owl.css
For owl.svg: padding-top = 300 / 300 * 100 = 1 * 100 = 100%;If width of container = 60%: padding-top = 300 / 300 * 60 = 1 * 60 = 60%;If owl.svg has width 250px, height 400px: padding-top = 400/250 * 100 = 1.6 * 100 = 160%;
4. Position SVG Inside Container
/* pull the svg to the top of the container */.my-svg {
position: absolute;top: 0;
left: 0;width: 100%; /* only required for <img /> */
}
responsive-owl.css
6. Resize!
Animating SVGs with CSS
Transforming
SVGs
Initial transform-origin on HTML & SVG
Box Model? transform-origin (default value)
HTML elements (div, etc.) Yes 50% 50%*
SVG elements (circle, rect, etc.) No 0 0**
*50% 50% = center of the HTML element itself** 0 0 is the top left corner of the SVG canvas, not the element itself
CSS Transforms on HTML & SVG<!DOCTYPE html>...<div style=”width: 100px; height: 100px; background-color: orange”> </div><svg style=”width: 150px; height: 150px; background-color: #eee”>
<rect width="100" height="100" x="25" y="25" fill="orange" /></svg>
Setting transform-origin on SVG Elements
1. Using Percentage Values: The value is set relative to the
element’s bounding box, which includes the stroke used to
draw its border.
2. Using absolute length values: The origin is set relative to the
SVG canvas.
CSS Transforms on HTML vs SVG (cont’d)<!DOCTYPE html><style>
div, rect {transform-origin: 50% 50%;
}</style>
Heads up: Transform-Origin Issue In Firefox With Percentage Values
Setting transform-origin using a percentage value currently doesn’t work in Firefox. That is a bug. (It shouldn’t be a problem if you’re not rotating anything.)
Setting it in absolute length values should be fairly simple using a graphics editor.
Example: PinWheel
PinWheel by http://pixeldoree.com/vector/free-vector-pinwheels-adobe-illustrator-and-png-files/
.wheel { -webkit-transform-origin: 50% 50%;
transform-origin: 193px 164px; animation:
spin 4s cubic-bezier(.49,.05,.32,1.04)infinite alternate;}
@keyframes spin { 50% { transform: rotate(360deg); }}
Zooming out (or in) in Webkit/Blink does not maintain the transform origin at the center of the rotating element. This is a bug.
This issue does not happen in Firefox, where the transform origin is set in absolute values (relative to the SVG canvas).
Heads up: Transform-Origin Issue In Chrome With Percentage Values
→ Just use absolute values (for the time being)!
Heads up: Hardware Acceleration In Chrome
CSS 3D transforms are hardware accelerated in Chrome when applied to HTML elements. However, they are not accelerated when used on SVG elements - they have the same performance profile as SVG transform attributes. They are accelerated in Firefox.
Animating SVG Paths
Animated Line DrawingTo Animate an SVG path you need to know its exact length. Then:
#path {
stroke-dasharray: pathLength;
stroke-dashoffset: pathLength;
/* transition stroke-dashoffset */
transition: stroke-dashoffset 2s linear;
}
svg:hover #path{
stroke-dashoffset: 0;
}
Example#cable {
stroke: #FFF2B1;stroke-dasharray: 4000 4000;stroke-dashoffset: 4000;stroke-width: 4;transition: stroke-dashoffset 8s
linear;}svg:hover #cable {
stroke-dashoffset: 0;}/* turn lamp on */.inner-lamp{
fill:grey; transition: fill .5s ease-in 6s;
}svg:hover .inner-lamp {
fill: #FBFFF8;}/* ... */
The animated path is positioned on top of the black path. When SVG is hovered path is animated, and the lamp is “turned on” after path finishes animation, using a delay that is equal to the animation (transition) time of the path.
var path = document.querySelector('.drawing-path');path.getTotalLength();//set CSS properties uppath.style.strokeDasharray = length + ' ' + length;path.style.strokeDashoffset = length;//set transition uppath.style.transition = 'stroke-dashoffset 2s ease-in-out';// animatepath.style.strokeDashoffset = '0';//more: http://jakearchibald.com/2013/animated-line-drawing-svg/
Animated Line Drawing: Retrieving Path Length Using Javascript
#RecommendedReading
http://jakearchibald.com/2013/animated-line-drawing-svg/
Animated Paths (Morphing Paths)
The idea is to create a SVG with one path and to morph that path into another one.
You’ll need: the first path, the second path, and possibly intermediate paths (depending on your animation).
There is no way in CSS to animate one SVG path into another.
http://goo.gl/93gFYh
“ By using animated SVGs instead of GIFs we were able to reduce our page size from 1.6 mb to 389 kb, and reduce our page load time from 8.75 s to 412 ms. That’s a huge difference.”
Animated SVGs As GIFs Replacement
http://oak.is/thinking/animated-svgs/
Don’t forget to..
http://caniuse.com/#search=svg
Recommended