📜 ⬆️ ⬇️

Vector replacement to sprites - we implant SVG in CSS

Not so long ago, the company in which I work finally finally abandoned support for IE8 and, as a result, I came to grips with the issue of switching from raster icons to vector ones. The main advantages of SVG are scaling, low weight and the ability to styling via CSS.

At first, I tried to use the sprites technique, simply using a vector instead of a raster, but two problems arose:


Then I remembered the integration of images in CSS by encoding base64 and using data-uri. And with SVG everything is much simpler. Since the SVG image is an XML file, even base64 is not required for it, just specify the mime type as data: image / svg + xml and paste the contents of the SVG file in one line.

Take, for example, the recycle bin icon:
')
image

Its code looks like this:

<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" version="1.1" viewBox="0 0 1850 1635" xmlns:xlink="http://www.w3.org/1999/xlink"> <g id="icon__cart"> <path fill="#101010" d="M1254 1163l-1203 0c-26,0 -51,-25 -51,-51l0 -131c0,-23 22,-51 51,-51l1075 0c22,0 36,-13 44,-30l96 -192c4,-9 1,-12 -8,-12l-1207 0c-22,0 -51,-25 -51,-51l0 -131c0,-23 23,-51 51,-51l1298 0c27,0 46,-13 56,-33l200 -401c9,-18 20,-29 41,-29l182 0c19,0 29,7 18,29l-554 1111c-5,10 -19,23 -38,23z"/> <circle fill="#101010" cx="207" cy="1453" r="181"/> <circle fill="#101010" cx="1062" cy="1453" r="181"/> </g> </svg> 

Accordingly, using it as a background in data-uri will look like this:

 .element_whis_svg_background { background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" version="1.1" viewBox="0 0 1850 1635" xmlns:xlink="http://www.w3.org/1999/xlink">...</svg>'); } 

We try. In Chrome and Opera, everything is fine, but in IE9-10-11, Safari, and, oddly enough, Firefox - the background image is not displayed, they do not understand this recording format. We search for what the problem is and find out that for IE and others, for the contents of the SVG file, we have to perform URI encoding of the string according to the RFC 3986 standard. We encode, we get the following construction:

 %3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201850%201635%22%3E%3Cg%20fill%3D%22%23101010%22%3E%3Cpath%20d%3D%22M1254%201163H51c-26%200-51-25-51-51V981c0-23%2022-51%2051-51h1075c22%200%2036-13%2044-30l96-192c4-9%201-12-8-12H51c-22%200-51-25-51-51V514c0-23%2023-51%2051-51h1298c27%200%2046-13%2056-33l200-401c9-18%2020-29%2041-29h182c19%200%2029%207%2018%2029l-554%201111c-5%2010-19%2023-38%2023z%22%2F%3E%3Ccircle%20cx%3D%22207%22%20cy%3D%221453%22%20r%3D%22181%22%2F%3E%3Ccircle%20cx%3D%221062%22%20cy%3D%221453%22%20r%3D%22181%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E 

Substitute it in the background, check:

 .element_whis_svg_background { background: url('data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2 ... svg%3E'); } 

Hooray, everything works! Nuance - the encoding in this case does not need to be specified. If you specify - it will stop working in IE.

Well, and finally, in order to customize the appearance of the icon, we use any preprocessor (I use LESS, but this is not essential) and design our icon class as an admixture (mixin). In order to be able to change the fill color, we find the attribute fill in the coded string, there will be something of the type:

  fill%3D%22%23101010%22 

What is between% 23 and% 22 is the desired color code, in whose place it is necessary to substitute a variable. As a result, we get the following:

 .icon__cart(@width, @height, @fill) { content: ''; display: block; width: @width; height: @height; background-size: contain; background-repeat: no-repeat; background: url('data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201850%201635%22%3E%3Cg%20fill%3D%22%23@{fill}%22%3E%3Cpath%20d%3D%22M1254%201163H51c-26%200-51-25-51-51V981c0-23%2022-51%2051-51h1075c22%200%2036-13%2044-30l96-192c4-9%201-12-8-12H51c-22%200-51-25-51-51V514c0-23%2023-51%2051-51h1298c27%200%2046-13%2056-33l200-401c9-18%2020-29%2041-29h182c19%200%2029%207%2018%2029l-554%201111c-5%2010-19%2023-38%2023z%22%2F%3E%3Ccircle%20cx%3D%22207%22%20cy%3D%221453%22%20r%3D%22181%22%2F%3E%3Ccircle%20cx%3D%221062%22%20cy%3D%221453%22%20r%3D%22181%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E'); } 

This impurity is used as follows (sample is arbitrary):

 .block-whis-icon._cart { ...; &::before { .icon__cart(30px, 20px, '1d9fbb'); ...; } } 

That's all. LESS- (SASS, Stylus, etc.) a file with such impurities perfectly replaces the sprite.

For optimizing and coding SVG, I used GULP, gulp-svgo and gulp-data-uri-stream plugins. Yes, this method makes it possible to change only the size of the icon, the color of the fill and stroke, but for the most part this is quite enough.

Source: https://habr.com/ru/post/257781/


All Articles