Css use svg icon

How to work with SVG icons

There are many ways to use SVG icons in HTML and CSS, and I haven’t tried them all. This is how we do it in our small front-end team at Kaliop. It works well for our needs, which include:

  • Content and communication websites, often based on big CMSes, rather than full-JS web apps.
  • Icons which are often simple, single-color icons (each potentially used in several different colors depending on context and user interactions). Two-color icons and gradient fills are possible too, but require a bit more work.
  • IE11 support.

This article is available in French and in Chinese. Many thanks to the translators!

Preparing your icons

When you get a SVG icon from a designer or from a design tool (Illustrator, Sketch, Figma, etc.), it’s tempting to just throw it into your project. Yet I find that reworking it a little bit in your favorite tool to make sure it’s just right can save you some headaches and improve the result.

Work with a new document or artboard

Create a new document or new artboard in your favorite tool, and copy-paste your icon in the center. It’s a great way to make sure your icon is clean and doesn’t have a ton of hidden paths lying around.

Square is easier

Your icon doesn’t have to be square, but square icons are easier to work with (unless your icon or graphic is really wide or really tall).

Exact dimensions only matter if you want to micromanage pixel fitting (to get the sharpest possible results on low dpi screens). For example if all your icons can fit on a 15 by 15 pixel grid, and are mostly used with those exact dimensions, go ahead and work with 15×15 artboards or documents. When I’m not sure, I like setting stuff on a 20×20 artboard.

Breezy on the sides

Leave a little bit of space near the edges, especially for round shapes. Browsers use anti-aliasing when rendering SVG shapes, but sometimes the extra pixels from the anti-aliasing are rendered outside of the viewBox and they’re cut off.

Screenshot of an round icon in Illustrator, touching the limits of the artboard

As a rule of thumb, in a 16px or 20px icon, leave 0.5px or 1px of empty space on each side. Also, remember to export the whole artboard, not the selected paths at the center, or you will lose that white space in the export.

Export to SVG

  • In Illustrator I just use “Save As” and pick “SVG” for the format. (It might be better to use “Export as…” and pick SVG for an optimized result.)
  • In Sketch you can select an artboard, click “Make Exportable” on the bottom right, and pick “SVG” for the format.
  • In Inkscape you can “Save As” and pick “Optimized SVG”.

Learn some SVG

You definitely should learn some SVG basics, and be able to read and understand the structure of simple SVG files. Ideally you should know about these:

  • Grouping elements: , , .
  • Visual elements: , , , .
  • Styling attributes: fill , stroke , stroke-width .
Читайте также:  Формат времени и даты java

I tend to look them up in DevDocs (which simply offers a nicer view of the MDN SVG docs) when I want to know more. You don’t have to do that right now, and you can start your SVG adventure by copy-pasting code, but in time it’s helpful to learn enough to understand the code you’re copy-pasting.

When you export SVG from a design tool, it will often have a little bit or a lot of unnecessary markup, metadata and such. It can also have excessively precise path data (in the d attribute). Try using a tool such as SVGOMG and compare the before and after code to see what gets removed or simplified.

Remove color data

For single-color icons, make sure that:

  1. In your source file, the paths are black ( #000000 ).
  2. In the exported code, there are no fill attributes.

If we have hardcoded fills in the SVG source, we won’t be able to change those colors from our CSS code. So it’s generally best to remove them, at least for single-color icons.

Illustrator doesn’t output fill attributes for path that are fully black ( #000000 ). Sketch does, so you may have to open the exported SVG code and manually remove the fill=»#000000″ attributes.

Making a SVG sprite

This part has a lot of code, but it’s actually not complex at all. We want to create a SVG document containing elements. Each must have an id attribute, a viewBox attribute, and will contain the icon’s elements (or other graphical elements).

I’m calling this SVG document a sprite (in reference to sprites in computer games and CSS), but it may also be called a sprite sheet, or a symbol store.

Here’s a sprite with just one icon:

Adding an icon to our sprite

Say that Illustrator gave us this code for the icon show above:

We can simplify it quite a bit (manually or using SVGOMG), only keeping the viewBox attribute and essential data:

Now we can copy-paste it in our sprite. We need to transform the element into a element and insert it manually into our sprite:

You can do this manually for all your icons, but there are tools that automate the process. We use gulp-svg-symbols (here’s our gulp config, if you’re curious), but there are several graphical and command-line tools that export SVG symbol sprites, including Icomoon.

Pro tip: Keep a folder with your source icons

If you make your sprite manually, I recommend keeping a folder with individual SVG icons:

assets/ icons/ cross.svg play.svg search.svg . public/ sprite/ icons.svg

Then if you need to rebuild the icons.svg or change an individual icon, you have the right sources to work with. Be careful to not let your sprite and your source folder get out of sync.

Of course if you use a build process (with Gulp or Webpack or something else), you can feed it your source folder and let it build the sprite directly.

Important: not everything is an icon

Just because something is SVG, it doesn’t mean it should go inside your SVG sprite. For instance:

  • Illustrations that you don’t need to style: keep as a single SVG file, and include it in your page with .
  • Illustrations that you want to animate: consider inlining the full SVG code in your HTML page, so you can select and style specific groups or paths or shapes, animate some parts, etc.
Читайте также:  Read values from MySQL

As a rule of thumb, if it’s a big illustration that you need to show at 100px by 100px or much bigger, or if it contains dozens of elements, it might not be an “icon”. It would probably bloat your sprite’s size, too.

Adding icons to your pages

The bad news is that in order to use our SVG icons, we have to change our HTML code. No CSS backgrounds, no ::before pseudo-elements. The least verbose HTML we can use is:

Screenshot of unstyled SVG icons

I recommend putting this in the of your pages:

Another approach is to always use width and height attributes on your SVG elements. It works, but if you need to resize this icon in CSS it might be a bit harder.

Preloading external sprites

In the “Adding icons to your pages” section we said that icons from an external sprite can show up a bit late, partly because of the browser’s pre-load scanner (or look-ahead pre-parser or whatever) not picking up that means there is an important file to load early.

What can we do about this?

  • Standard and future solution: add in the of the page (details on preload, support coming to a Chrome near you and hopefully in more browsers in the future).
  • Old school solution: add at the start of the .

I haven’t actually tested those solutions, generally the “inline + external” compromise gives good enough performance that we don’t have to rely on preloading. But it’s worth investigating.

Selecting individual shapes or paths

We’ve looked at ways to customize fills, strokes etc. for all paths from a , and 2 or more colors from different paths. But what if we could select specific paths (using classes maybe) directly in the instance of the ? Is it possible?

Right now the answer is: yes and no.

  1. If you use external sprites, you can’t select individual paths (or other elements) inside a used .
  2. If you inline your sprite, you can select and style elements inside the sprite, but those styles will apply to all instances of the symbols.

So even with an inlined sprite, you could do this:

#my-symbol .style1 < /* Styles for one group of paths */ >#my-symbol .style2 < /* Styles for another */ >
.MyComponent-button .icon .style1 < /* For 1 group of paths for this icon in this context */ >.MyComponent-button .icon .style2 < /* For another group */ >

In the future, there might be a standard way that allows selecting through a Shadow DOM, but that’s not sure at all (there used to be the /deep/ combinator, but it was removed).

More than two colors with CSS Custom Properties

So we can easily change colors of our SVG icons from CSS, for single-color icons (easy) and two-color icons (takes some preparation). Is there a way we could have multicolor icons with more than two customizable colors?

We might be able to do that with CSS Custom Properties (aka CSS Variables). This requires a lot of preparation on the SVG side:

For this demo I stole an icon from the excellent Iconic, which offers responsive, multicolor SVG icons (powered by CSS and some JS, as I understand). I tried to mimick their own multicolor example for this icon, I hope they don’t mind.

Читайте также:  No java runtime engine

One symbol using 6 different CSS custom properties.
See in Firefox, Chrome, or Safari 9.1+

It works fairly well in supported browsers. There’s only one icon: the first instance doesn’t declare the expected variables, so it falls back to currentColor; the next two instances each declare a set of variable values.

How are percentage stroke-width computed?

What does the percentage correspond to in stroke-width:N% ? Is it the width, the height of the icon? Turns out it’s relative to the diagonal, but with a funky formula (spec) (diagonal length divided by the square root of 2, which is close to 1.4).

What does it mean? Well for square icons the result of that formula is the side of the square. So 1% means “one percent of the width or one percent of the height”. Nice and simple.

For wider or taller icons, though, the result can change a bit:

In the second icon (aspect ratio of 2:1, shown with the same height and twice as large), the stroke-width:5% gives us a stroke that is roughly: 7.91% of the height and 3.95% of the width.

All things considered, I still recommend using percentage values for stroke-width . If you stick to square or sharish icon, you can use percent values with the understanding that they mean, roughly, “percentage of the width of the icon”.

Using gradient fills

We can’t use CSS linear-gradient(…) because this sadly cannot apply to the SVG fill property. If we want gradient fills, we will need to use SVG gradients.

Источник

How do I use SVG icons in HTML?

I have an svg file with 3 icons. When I import it via the tag, I get the 3 icons one below each other. I want to use the icons in a row, one next to the other. How can I use them separately? The .svg file:

3 Answers 3

Use the SVG file as a sprite.

Create an icon-sized element, hiding the overflow:

Position the SVG within the element so the icon shows through:

.icon > img < position: relative; >.darkStar > img < top: 0; >.lightStar > img

Demo (using inline SVG instead of a linked , which defeats the purpose, but is easier to demo here):

.icon < display: inline-block; width: 16.3px; height: 13.45px; overflow: hidden; >.icon > svg < position: relative; >.darkStar > svg < top: 0; >.lightStar > svg

Why can’t you add the svg as background-image to the .icon class in css ? Wouldn’t it be easier that way?

You can use fragment identifiers to display only part of the SVG file in any particular img element.

The advantage of this approach is that the «individual sprites» in your SVG file are defined in your SVG file, so when using it elsewhere you don’t need to know anything of the internal structure, you can just ask for what you want by name:

The most cross-platform-compatible solution is add some SVG view s which define which part of the image to show for which ID fragment. The view syntax is similar to the global viewBox attribute of the root SVG element*:

Here’s a good blog post (with a live example) which explains the technique in great detail.

*note that I haven’t calculated that viewBox value for your SVG, you’ll have to figure it out yourself.

Источник

Оцените статью