SVGs can be messy to develop with, often times being exported from a graphics application and being pasted into a document. However, they become much more delightful to work with when you have a readable file and clean markup.
Optimizing SVG for the web
When an SVG is exported from an application, it usually comes with code that’s unnecessary for rendering it on the web. For example, in Sketch, they add code to allow for easier re-importing into Sketch. If you use Sketch and you’re just exporting for use on the web, you can run this command in your terminal:
defaults write com.bohemiancoding.sketch3 exportCompactSVG -bool yes
This will change the way Sketch exports the files, making them more compact and web-ready. You’ll need to log out of your Mac user account or restart your computer for this change to take effect.
It’s also a good idea to run generated SVGs through an optimizer in order to quickly strip it down to only what’s necessary to render it on the page. This becomes more important when embedding SVGs in your application because those extra lines of code and comments show up in the markup.
I’ve found SVGO to be a great addition to my SVG workflow. SVGO is a Nodejs-based tool for optimizing SVG files. A simple command removes or converts the insignificant information in SVGs, reducing the file size without affecting rendering. It has a plugin-based architecture, so you can enable or disable different optimizations to best fit your needs. It works great out of the box, but if you want to learn more about the individual optimizations, check out their github.
To get started, install SVGO:
npm install -g svgo
In my workflow, I’m usually adding SVGs as I go, and optimizing them after I
export them from Sketch or Adobe Illustrator. To optimize a single SVG, it’s
simply svgo
followed by the relative path to the file and where to output it.
svgo --pretty ~/Desktop/ralph.svg app/assets/images/svg/ralph.min.svg
The --pretty
option isn’t required, it just “pretty prints” the SVG to make
diffing easier.
Embedding Inline SVG in Rails applications
Having your SVG inline, rather than referencing it via an <img>
tag, is a
great way to keep control over your document. Inlining means no additional HTTP
requests to load the graphic and the ability to use CSS and JavaScript to
manipulate individual parts of an SVG.
Rather than creating a partial that contains the SVG and including that, we can
use a helper method. This lets us reference it cleanly, similar to an <img>
tag, but with the benefits of having the code available in the markup.
I’ve been experimenting with a helper similar to what James
Martin wrote here on
coderwall. You can put the following code in
app/helpers/application_helper.rb
:
def embedded_svg(filename, options = {})
assets = Rails.application.assets
file = assets.find_asset(filename).source.force_encoding("UTF-8")
doc = Nokogiri::HTML::DocumentFragment.parse file
svg = doc.at_css "svg"
if options[:class].present?
svg["class"] = options[:class]
end
raw doc
end
This uses Sprockets to locate the file and reference it simply in your markup.
All you need to do is call the helper method with the path to the SVG relative
to app/assets/images
directory:
= embedded_svg "svg/ralph.svg"
The helper also allows for CSS classes to be added for easier manipulation:
= embedded_svg "images/svg/ralph.svg", class: "ralph-logo"
These small changes in my workflow have helped me spend less time optimizing by hand and organizing my SVGs. What tips or tools do you use to improve your SVG workflow?