Scaling Up (and Down) SVG
Using Scalable Vector Graphics on Responsive Web Pages
Responsive SVG
- Chris Coyier covered:
- What is SVG?
- Why is SVG good for RWD?
- This talk: how to use SVG in responsive sites
- How to make your SVG look good at any size
- First: SVG scaling basics
- Then: Advanced scaling effects
- I won't cover using JavaScript to re-scale graphics
- Slows down your page
- Can't be used in SVG images
- I will talk about
- Core SVG scaling options
- Using CSS media queries
Images vs. Documents
- Graphics and text respond to screen size differently
- Images: constant aspect ratio
- shrink width = shrink height
- expand width = expand height
- Text: constant area (approximately)
- shrink width = expand height
- Text wraps onto new lines
- SVG scales like an image
Scaling SVG Basics: the viewBox
- Most RWD:
- Browser has a certain size
- You adjust to fit
- SVG
viewBox
:
- You declare what size your graphic is designed for
- The browser scales to fit
- DEMO
- No
viewBox
= no scaling:
- Works like CSS absolute positioning
- Percentages scale, nothing else
- WT# is a
viewBox
?
- Attribute on the
<svg>
- Four numbers: x, y, width, height
- x,y: top-left corner coordinates
- width,height: # of px to fit in available space
- Can I haz
viewBox
?
- Some graphics programs will create automatically (Inkscape won't)
- Use px for your dimensions
<svg viewBox="0,0 w,h" >
- For x,y: use 0,0 (if you're using graphics program)
- For w,h: use the width & height in px
- LIVE DEMO: Getting a
viewBox
in Inkscape
SVG Images
- SVG Image = SVG used as an image file
- HTML
<img>
or CSS background-image
- Most layout/scaling issues work the same with HTML
<object>
- LIVE DEMO: Using your Inkscape SVG in a web page
- Size the image with CSS, browser handles the scaling
- LIVE DEMO: No viewBox = no scaling in IE
- LIVE DEMO: No height, width, viewBox = no scaling anywhere
- LIVE DEMO: No height, width = arbitrary default sizes
- What if you don't know the aspect ratio?
- If aspect ratio doesn't match, browser centers and fits
- If you only specify height or width, other dimension auto-scales
- The center/fit behavior is controlled by
preserveAspectRatio
attribute
- E.g.:
preserveAspectRatio="xMinYMax slice"
- E.g.:
preserveAspectRatio="none"
- Find out more
- Make image responsive!
- Percentages or viewport units
- Media queries
Inline SVG
- Inline SVG = SVG markup inside your HTML file
- Same document, same stylesheets
<svg>
element is both canvas and content
- If creating your SVG in a graphics program:
- Give it a viewBox
- Optimize it
- PHP / other server-side includes
- AJAX for browser caching
- Good old copy & paste
- Same Demo, edit it!
- Set both height and width with CSS
- & make responsive!
- no viewBox = no scaling, in any browser
- height & width attributes are defaults only
- LIVE DEMO: playing around with CodePen
- If you set height or width
- Some browsers adjust according to viewBox
- Others don't (IE, Safari, older Chrome, really old Firefox)
- Use the
padding-bottom
hack to scale height according to width
- Find out more
Icons & Symbols
- SVG
<symbol>
element = reusable graphic
- Draw a symbol with a
<use>
element
- The use element can be in a different SVG in the same document
- Specs: the use element could be in a different document
- Real world: no IE support, styles buggy in other browsers
- Use AJAX to get your symbols into your main document
- If they are used on many pages
- Or, directly include in HTML markup
- Symbols must be within an
<svg>
element
- Insert symbols in first SVG (the won't draw directly)
- Put symbols in their own SVG, then hide with CSS
- Don't use
display: none
(older Firefox bugs)
- The
<symbol>
has a viewBox
, so your SVG doesn't need one
- Inline markup is short & sweet
<svg class="icon"><use xlink:href="#icon" /></svg>
- The symbol will stretch to fit the SVG
- DEMO
- Change icon size using CSS height and width on the svg.icon
- Must set both height and width, in all browsers
- Use classes if icons have different aspect ratios
- Tip: Use
em
units for easy scaling with font-size
- End of SVG Scaling Basics:
Media Queries and SVG
- Slimming Down when you're Scaling Up
- The viewBox scales everything equally
- All units
- Font size
- Stroke (lines/outline) width
- Result: overbearing text, thick lines
- Media queries can cancel out the effect
- Make
font-size
or stroke-width
smaller as SVG gets larger
- Text and strokes will still scale up, but not as much
- Consider accessibility: Don't make things too small
- SAME DEMO, new options
- What is the media for SVG?
- Image or object: the SVG region only
- Inline: the entire page/frame
- Always: the area for the entire document
Selective Scaling
- Instead of media query breakpoints, just don't scale some parts
- No viewBox = no scaling
- Nested SVG elements (with viewBox) contain the parts you want to scale
- But no viewBox = no auto-scaling aspect ratio for images
- Percentages scale position but not size
- Can't do complex shapes with percentages
- Weird for dimensions not linked to width/height
- No aspect ratio control
- Requires math
- Best for map/chart annotations
Shrink & Simplify
- Media queries remove / replace parts of graphic as you scale down
- Large, medium, & small logos in one image file
- Not an image sprite!
- Works as an HTML image or as CSS background image
- Streamline shapes, simplify effects, remove text
- Media queries inside the SVG file
- In a
<style>
block
- Main page CSS only controls the image width/height
- View source
- Media queries cannot change aspect ratio
- viewBox is not a CSS property
- This may change in SVG 2
- Other layout control is limited to CSS transforms
- This will change in SVG 2
- To significantly change design, show/hide separate versions
- More examples & explanation:
Complex Scaling Patterns
- Inline SVG & no viewBox = CSS control of aspect ratio
- Nested SVGs and percentages for scaling
- Details dropped / swapped with media queries
- Complexity is up to you
SVG & Text Wrapping
- SVG text is absolutely positioned
- Not text-in-a-box
- Does not wrap to a new line if it runs out of room
- This will change in SVG 2
- Need to explicitly position multi-line text
- Practical solution: Two versions of text, and swap
- For lots of text: use HTML
- Absolutely positioned divs over top of SVG
- SVG
<foreignObject>
element: no IE support yet, buggy in other browsers
Summary: Basics
- For most SVG,
viewBox
is all you need
- For SVG-as-image (or object):
- Use
viewBox
+ width
+ height
attributes on the root <svg>
element
- Use preserveAspectRatio to control alignment when image size doesn't match
- Browser will auto scale height to match width or vice versa
- For large inline SVG:
- Use
viewBox
on the <svg>
element
- Use CSS for height and width
- Use a padding-bottom hack if necessary to get height to scale with width
- For inline SVG icons:
- Use
<symbol>
element with viewBox
attribute
- Inline markup:
<svg class="icon"><use xlink:href="#icon" /></svg>
- Use CSS classes/em units to set height and width
- More examples & explanation:
Summary: Advanced
- Use media queries:
- To make text and strokes smaller (relatively) as SVG gets larger
- To remove extra details or swap in simplified versions
- With breakpoints based on the document size
- Use nested SVGs:
- To create complex scaling effects
- If you want to get fancy
- With no
viewBox
on outer SVG
- With percentages for position & sizing of nested SVG
- With percentages for position of non-scaling content
- Use SVG 2:
- To make this all easier!
- …eventually.