An in-depth article on styling content in an SVG element
Graphics in SVG format are especially often used for creating icons and one of the most common techniques for this is SVG sprites using SVG use to instantiate icons in the right place document.
Instantiating icons or any other SVG content in an element
But before we get started, let's take a quick look at the basic structure and grouping of elements in SVG, gradually moving on to
A quick tour of SVG structure, grouping, and element referencing in SVG
SVG includes 4 basic elements for defining, structuring, and referencing SVG content in a document. These elements allow for reusability of images, while keeping the code readable and maintainable. Due to the nature of SVG, some of these elements have functionality similar to the corresponding commands in image editors.
The 4 main grouping and binding elements in SVG are
Element
Grouping elements is useful when you want to apply a style to all elements in a group, and also when you want to animate all elements in a group while maintaining the relationship between them.
Element
Element
Element
Element
To use an element, you need to pass a link to that element, the identifier is the xlink: href attribute and position it by specifying the x and y attributes. You can apply styles to an element
But what is the content
Before answering these questions, and given that we were just a quick glimpse at the structure and grouping of SVGs, it's worth mentioning a couple of articles that will allow you to learn more about these elements, as well as the viewBox attribute on an element.
- Structuring, Grouping, and References in SVG - The g, use, defs, and symbol elements
- Understanding the SVG Coordinate System (Part 1): Viewport, viewBox and PreserveAspectRatio
SVG and shadow DOM
When you reference an element with
An icon is displayed on the screen, the content of which is defined inside
But the element
The answer is in shadow DOM(for some reason I always associate him with Batman, I don't know why).
What is Shadow DOM?
The shadow DOM is identical to the regular DOM, except that instead of being part of the main document tree, shadow DOM nodes refer to a portion of the document that is parallel to the main document, but not accessible to its scripts and styles. This gives authors the ability to create modular components by encapsulating scripts and styles. If you've ever used the video element or range input in HTML5 and don't understand where the video player controls or slider came from, then the answer is the same - shadow DOM.
In the case of the SVG element
So the content is
In other words, the content is there, but it is invisible. Same as regular DOM content, but not accessible by high-level tools like CSS and JavaScript selectors, copied into a document chunk bound to
Now, if you are a designer, you might be thinking, "OK, I get it, but is there a way to inspect this subdocument and see its contents." The answer is yes, you can view the contents of the shadow DOM using the development tools in Chrome (in Firefox at this moment this function is not available). But first, you need to activate the shadow DOM inspector in the General tab of the settings panel. This is described in detail.
After you have enabled shadow DOM inspection in the developer tools, you can see cloned elements in the toolbox, just like regular DOM elements. The following image shows an example of an element
Using tools Chrome developer, you can inspect the contents of the use element inside the shadow DOM (“# shadow-root”, the line is grayed out). This screenshot inspects the Codrops logo from the example we'll look at in the next section.
Looking at the inspected code, you can see that the shadow DOM is very similar to the regular DOM, except for how it is handled by the CSS and JavaScript of the main document. There are also other differences between them, which we will not cover in this article due to their volume, so if you want to know more, I recommend you the following articles:
- Shadow DOM 101 (translated by Frontender.info)
- Introduction to Shadow DOM (Video)
Given my limited experience with the shadow DOM, I see it as a regular DOM that needs to be handled differently in terms of CSS and JavaScript access to its elements. This is what matters to us when working with SVG: How to Affect Content
As said, the content of the shadow DOM is not available to CSS, unlike regular DOM. So how do we style it? We cannot use a descendant path like this:
Use path # line (stroke: # 009966;)
Because we don't have access to the shadow DOM using regular CSS selectors.
Perhaps, as I do, you expect presentation attributes to have the highest specificity of any style rule. After all, usually external styles are rewritten by internal declarations, and they, in turn, are rewritten by inline attribute styles - they have the maximum specificity, and, accordingly, priority over other styles. While this expectation makes sense, the actual mechanism is different.
In fact, presentation attributes are considered low-level “authoring style sheets” and are overwritten by the rest of the style declarations: outer, inner, and inline styles. Their only strength is their priority over legacy styles. And that's all.
Now that we've figured it out, let's go back to our element
We know that we cannot set styles inside
But we also know that as with the element
So, first let's try to change the fill color of the element inside
However, this begs a couple of questions:
- The fill color will be inherited all descendants element
, even those that you don't want to style (but if inside you have only one item, then this problem will not be). - If you exported SVG from a graphics editor, or for some other reason cannot modify the SVG code, then you will end up working with SVG that already has presentation attributes applied (unless you explicitly override this when exporting to SVG format) and the values of these attributes will take precedence over those inherited from
.
And even if you can edit the SVG code and can get rid of them, I highly recommend not to do so by following reasons:
- Removing attributes for the sake of setting certain properties later will reset the values of these properties to their default values, which, as a rule, are black fill and stroke (as applied to colors).
- By resetting the values, you force yourself to style the entire set of properties.
- The presentation attributes that are initially set are a great fallback in case you run into problems with the outer styles. If the CSS doesn't load, your icons will still look great.
So, we have these attributes, but at the same time we want to design different instances of icons in different ways.
This is done by forcing presentation attributes to inherit the styles specified by
Let's start with simple examples and gradually move on to complex ones.
Rewriting presentation attribute values with CSS
Presentation attributes are overridden by any style declaration. We can use this in order for the presentation attribute to get the value inherited from the styles.
This is simply due to the key CSS word inherits. Take a look at next example- an ice cream icon drawn with one outline, the color of which we want to change in different instances. Icon created by Erin Agnoli of the Noun Project.
The content of our ice cream icon (path) is defined inside the element
We display multiple instances of the icon using
We set the width and height of the icons using CSS. I am using the same dimensions as the viewBox, but they don't have to be identical. However, to avoid excess white space inside the SVG, make sure you maintain aspect ratio.
Icon (width: 100px; height: 125px;)
With this code, we got the following output:
Notice that thanks to the added black borders around our SVGs, you can see the borders of each one, including the first one, in which the content is not rendered. Remember: the SVG document in which you defined the symbol will be displayed on the page, but no content... To prevent this, use the display: none property on the first SVG. If you don't hide SVG with icon definitions, it will be displayed on the screen even if you don't set dimensions for it - it will take the default 300 by 150 pixels (this is the default value for non-replaceable elements in CSS) and you will get an empty block you don't need on the screen ...
Now let's try to change the fill color for each instance of the icon:
Use.ic-1 (fill: skyblue;) use.ic-2 (fill: # FDC646;)
The fill color of the icons still does not change, as the inherited color is overwritten with the fill = "# 000" attribute in the path element. To prevent this from happening, we need to force path to inherit the color:
Svg path (fill: inherit;)
Voila! Colors, given to elements
Now this technique works after we have forced the content
Content decoration using the CSS all property
Some time ago, when working on an icon activated with
If you run into a similar task, you probably decide that it will take too long if you do everything in CSS:
Path # myPath (fill: inherit; stroke: inherit; stroke-width: inherit; transform: inherit; / * ... * /)
After examining this snippet, you will notice a pattern, which means that it would make sense to combine all the specified properties into one and set it inherit value.
Fortunately, it will help us CSS property all. My CSS reference mentions using the all property for SVG styling, but it's worth brushing up on our knowledge.
Using the all property we can do this:
Path # myPath (all: inherit;)
This works fine in all browsers that support all, however the following should be considered important point: This declaration tells the element to inherit literally all the properties of its parent, including those you don't want to set on the element. Therefore, if you do not want all CSS properties to be styled, this will not work for you - this is a last resort and it is only partially suitable when you have an unstyled element and full control above its properties in CSS. If you use this declaration and do not define values for all CSS properties, they will cascade until they find a value to inherit, in most cases these are browser default styles.
Note that this only applies to attributes that can be set using CSS, not attributes that can be set in SVG only. If the attribute can be set using CSS it will inherit the styles, otherwise it won't.
Ability to activate inheritance of presentation attributes of all styles
Using the CSS variable currentColor to style content
Using the CSS variable currentColor in conjunction with the technique described above allows you to define two colors for an element, rather than one. Fabrice Weinberg wrote about this a year ago.
The idea is to simultaneously apply to
Let's say we want to style this minimalistic Codrops logo using 2 colors - one for the front blob and one for the back.
First, let's start with the code for this image: we have a symbol containing a description of the icon and three instances
If we set the fill color on the element
So instead of defining a fill color and cascading it the usual way, we will use the variable currentColor so that the smaller foreground blob has a different color and we will set this value with color properties.
First, we need to insert currentColor where we want to apply this color - this will be the place in the markup where the icon is defined, that is, inside
Then we need to remove the presentational fill attribute from the second blob and let it inherit the fill color from the element.
If we were to use the inherit keyword to force presentation attributes to inherit values from
Now using the fill and color properties in
Codrops-1 (fill: # 4BC0A5; color: # A4DFD1;). Codrops-2 (fill: # 0099CC; color: # 7FCBE5;). Codrops-3 (fill: # 5F5EC0; color: #AEAFDD;)
Every element
So what happened is the current color value leaked into the element's content styles
Here's a demo with the code used:
This two-tone technique is great for two-tone logos. In his article, Fabrice created three different versions of the Sass logo by changing the color of the text relative to the background.
The currentColor keyword is the only available CSS variable at the moment. However, if we had more variables, we could use them to fill in more more values in content
The future: content styling using CSS variables
The robot's code contains all its constituent colors:
Now, we won't be using CSS variables as fill attribute values for each outline. Instead, we'll use them as fill colors using the CSS fill property, keeping all fill attributes in place. These attributes will be used as a fallback for browsers that don't support CSS variables - the image will look as it was if CSS variables don't work.
With added variables code will be as follows:
Since inline style tags overwrite presentation attributes, browsers that support CSS variables will use those variables to set the fill color. And browsers that don't support them will use the fill attribute.
Then we need to set values for the variables in CSS. But first, instantiate the image with
After that, we will set the values of the variables for use so that they can cascade to its content. The colors you choose will create color scheme picture. Since our robot uses three primary colors, we will name them primary, secondary and tertiary.
# robot-1 (--primary-color: # 0099CC; --secondary-color: # FFDF34; --tertiary-color: # 333;)
You can still use the fill and color properties with these variables, but you can do without them altogether. So, with the colors set in our variables, the robot looks like this:
You can use as many copies of the image as you like and for each of them specify a set of different colors by creating various topics... This is partially useful when you want to style your logo. different ways depending on the context and in other similar cases.
As mentioned, browsers that do not support CSS Variables use the given presentation attributes as a fallback, while browsers that do not support CSS Variables use them to fill the fill property and rewrite the attributes. But what happens if the browser supports CSS variables, but you forgot to set these variables in your styles, or you set an incorrect value?
For our hipster robot, we set three variables and only a few of its fragments do not depend on them - after all, it was originally developed for possible theming. Therefore, if you run this code in a browser with support for CSS variables and remove all declarations with these variables, you will get the following result:
If variable values are not set or are not correct, the browser will use its default color, which is usually black for fill and stroke in SVG.
You can work around this by setting a different color as a fallback for supporting browsers. The syntax for CSS variables allows you to do this: instead of passing the var () function the name of the variable as an argument, you pass two arguments separated by commas - the variable name and fallback, in this case it will be the value for the presentation attribute.
So, now the code of our robot looks like this:
And it's all. If a variable is not set to a value, the browser will always have a fallback color in stock. Wonderful.
Using this technique, you can display this robot anywhere on the page with
You can experiment with the demo, create as many copies of the robot as you like, and color it in any colors - just remember to use a browser with support for CSS variables:
If you view this demo in a browser with support for CSS variables, then, among others, you will see a blue and yellow version of the robot, as we specified in the CSS variables. Otherwise, you will see three identical robots with a fallback color.
Summing up
It was a great article.
Using the power of the CSS cascade to style the content
Personally, I really like the combination of CSS and SVG variables. I love their joint functionality, especially in terms of creating a fallback mechanism.
We may also get other ways to style the content.
Working with reusable SVG content is one of the tricky topics of SVG, it has to do with the behavior and location of the cloned code. This raises a lot of related questions that can become the topic of separate articles.
Scalable Vector Graphics (SVG) support is excellent across all modern browsers The image format appears in amazing contexts on many different web pages. But even though it has been the standard for nearly two decades, SVG remains a somewhat new format for some designers and developers, leaving them confused as to how it should be used on a site. Here are some reasons why you should use SVG:
Tiny file size
Well-designed, typical SVGs are much smaller than the equivalent PNGs, which means pages that use them load faster for users.
Scalability
Since SVG is built from mathematical formulas, not fixed pixels bitmap graphics SVG images can be scaled up and down without loss of quality, making them ideal for modern responsive sites.
Interacts with the DOM
SVG is sometimes referred to as "drawing with markup": every element in the SVG image interacts with the DOM, which means that CSS and JavaScript can manipulate parts of the SVG document. Unlike bitmap graphics, each individual shape in SVG can have its own identifier or class.
Easy to modify and adapt
The quality of SVG components means that well-formed SVG documents can be easily modified in any text editor without the need for specialized programs required for bitmaps. And since SVG interacts with the DOM, its elements can be modified using CSS. SVG format is great for displaying:
-
illustrations and drawings
logos
SVG tools
While you can create an SVG document using any text editor, vector illustration programs such as Adobe Illustrator or Inkscape are usually the best choice(although it should be noted that other applications including 3D programs such as Blender and server applications, can export SVG).
Whatever you use, you should be aware that creating SVGs from applications still leaves a lot to be desired at times: the resulting document is often recoded and sometimes poorly formatted. The svg file can be made smaller, more compact by processing it with an optimizer such as SVGOMG. Sometimes passing the wrong svg document through the W3C validator can help you pinpoint problems.
SVG integration
There are three main ways SVG can be used directly on a web page:
Since SVG is based on XML, it can be directly integrated into the code on your page. SVG code reduces latency and overall load time for your page.
Like bitmaps, the SVG file can be referenced by tag or via CSS as a background image. This is often The best way unless SVGs need the individual attention of CSS and JavaScript.
Inserted as
Адаптивный SVG
Как я уже упоминал, отдельные компоненты SVG могут быть помечены идентификатором или классом, что означает, что им можно манипулировать в рамках медиа-запросов. Это означает, что вы можете использовать различные функции SVG-иллюстраций при разных размерах экранов, создавая возможности для адаптивных логотипов или иллюстрации, которые показывают большую или маленькую детализацию, когда окно просмотра сжимается и расширяется..., что полностью подходит для отзывчивого дизайна, который заключается в том, чтобы показать посетителям сайта соответствующий контент на соответствующем уровне детализации, на том устройстве с которого они просматривают в данный момент сайт.
Вот несколько примеров адаптивных логотипов:
Интерактивные SVG
SVG идеально подходят для отображения реальных форм, это означает, что они отлично подходят для интерактивных карт:
Узоры
Есть два особенно недооцененных аспекта SVG:
Подготовка SVG для использования в вебе это очень простой процесс, не сложнее экспорта JPEG или PNG . Используйте любой привычный для вас графический редактор (Illustrator, Sketch, Inkscape [бесплатен], и тому подобное [или даже Photoshop, если вы используете слои с формами]) с тем размером изображения, который вы планируете использовать. Обычно я работаю в Иллюстраторе, поэтому я объясню некоторые способы подготовки файлов в этой программе, но вообще они применимы и для любой другой программы. Вам, возможно, стоит перевести текст в кривые, поскольку шрифт, скорее всего, будет неправильно отображаться, если, конечно, вы не планируете стилизовать их с помощью веб-шрифта, используемого на странице (что возможно!). Не стоит также превращать все объекты в единые формы, особенно если у вас есть обводка, которой необходимо будет управлять на странице, тем более преобразование объектов зачастую не уменьшает размер файла. Любые имена, присвоенные группам или слоям, будут добавлены к SVG как ID элемента. Это довольно удобно для стилизации, но немного увеличит общий размер файла.
Перед тем как сделать экспорт, необходимо проверить, все ли изображения находятся в целочисленной пиксельной сетке (то есть, например не 23.3px × 86.8px ). В противном случае скорее всего изображению не будет хватать чёткости и часть изображения обрежется. В Иллюстраторе это можно сделать следующим образом: Object > Artboards > Fit to Artwork Bounds . Затем жмём save as и выбираем SVG , и оставляем настройки по умолчанию. Здесь можно сделать небольшую оптимизацию, но на самом деле не стоит, так как далее мы будем применять разные улучшающие приёмы, поэтому сейчас мы не будем тратить впустую время на эти настройки.
Приёмы для уменьшения размеров файла.
(Смотрите по оптимизации)
Чтобы добиться наименьшего размера SVG , логично будет удалить из него всё лишнее. Наиболее известная и полезная программа (по крайней мере я так думаю) для обработки SVG это SVGO . Она удаляет весь не нужный код. Но! Будьте внимательны используя эту программу, если планируете управлять SVG при помощи CSS / JS , так как она может слишком сильно почистить код, что затруднит дальнейшие изменения. Удобство SVGO ещё и в том, что её можно включить в процесс автоматической сборки проекта, но можно также использовать GUI если хочется.
Разбираясь подробнее с правильным удалением всего ненужного, мы можем сделать ещё кое-что в графическом редакторе. Сперва нужно убедиться, что используется настолько мало контуров/форм, насколько это возможно, так же как и точек на этих контурах. Можно объединять и упрощать всё, что поддаётся упрощению, и удалить все ненужные точки. В Иллюстраторе есть плагин VectorScribe с инструментом Smart Remove Brush Tool , который поможет удалить точки и при этом оставить общую форму той же.
Предварительная оптимизация
Smart Remove Brush Tool удалил точки
Дальше будем увеличивать изображение. В Иллюстраторе удобно включить просмотр с пиксельной сеткой View > Pixel Preview и проверить, как располагаются контуры. Чтобы разместить контуры по сетке, потребуется немного времени, но эти усилия окупятся и позволят добиться более чёткого рендеринга (лучше обратить на это внимание заранее).
Точки вне сетки
Выравнивание по сетке
Если есть два и более объекта для выравнивания, то стоит удалить все ненужные перекрытия. Иногда даже если контуры тщательно выровнены, может быть видна тонкая белая линия. Чтобы предотвратить такое, можно немного наложить объекты друг на друга в местах перекрытия. Важно: в SVG z-index имеет определённый порядок, который зависит от объекта, находящегося снизу, поэтому стоит поместить верхний объект в нижнюю часть файла в коде.
И, наконец, последнее, но немаловажное, то, о чём обычно забывают - это активировать gzip сжатие SVG на вашем сайте в.htaccess файле.
AddType image/svg+xml svg svgz
В качестве примера того, насколько эффективна эта техника, я воспользуюсь оригинальным логотипом Breaking Borders и оптимизирую его таким образом: увеличиваю размер до того, каким он должен быть; приведу в порядок контуры; удалю максимально возможное количество точек; передвину точки на целочисленные пиксели; сдвину все области перекрытий и отправлю это всё в SVGO .
Оригинал: 1,413b
После оптимизации: 409b
В итоге размер файла стал меньше на ~71% (и на ~83% при сжатии)
Подготовил: Евгений Рыжков Дата публикации: 27.08.2010
Последнее обновление: 17.11.2010
Задача
Отобразить SVG-изображение на HTML-странице.
Существует несколько способов это сделать, но не все из них кроссбраузерны.
SVG через iframe
Наличие фрейма для многих уже ставит крест на данном способе. Нынче есть более совершенные способы решения данной задачи. К тому же в таком виде не получится реализовать прозрачные изображения (фрейм имеет фон), а так же нет доступа из внешних скриптов к элементам рисунка.
SVG через object
We have: valid clean code, alternative text, where you can provide the user with instructions on what to do if he does not see the picture (for example, send to the website normal browser or give a link to a plugin, the installation of which will help him). This embedding supports transparency in the SVG image (though in IE there is a problem: transparent areas will be filled with white). Cons: there is no way to influence images by external scripts (from HTML), only those that are in the SVG file itself.
The method is good for background images or any static pictures.
SVG via embed
This method supposedly allows scripts in HTML to interact with the contents of the SVG file (I have not been able to achieve this yet). For IE has wmode attribute (
This method is very popular now.
SVG in HTML code
- you should pay attention to the used namespace: xmlns: svg = "http://www.w3.org/2000/svg">;
- the document must be exactly in xhtml format (locally - this is a file with the .xhtml extension)
- cross-browser compatibility with this method is bad. IE's response is particularly bad;
- html code becomes unrealistically messy.
It is best not to use this method now.
The note
IE including version 8 does not support SVG. At that Microsoft time actively promoted its format - VML. Therefore, you will have to tinker with this browser in order to see the SVG image there too (more on this in the following articles).
Bright future
Apparently, in the near future, the SVG format will thoroughly enter the life of web developers. In confirmation of this, you can already find descriptions now interesting ways embedding SVG. Browser developers say new versions of their creations will support some or all of the following ways to integrate SVG.
SVG is a vector graphics format. Literally its name means scalable Vector graphics"(Scalable Vector Graphics). Quite simply, this is what you work with in Adobe Illustrator. SVG can be easily used on the web, but there are a lot of things to understand first.
Why do you need SVG at all?
- Small file sizes, excellent compression;
- Scaling to any size, without loss of quality (perhaps, at very small sizes);
- Looks good on retina;
- Ample opportunities provided by filters and interactivity.
Create an SVG image to work with next.
Create a freehand drawing in Adobe Illustrator. For example, a kiwi bird on an oval.
Note that the image is cropped to fit the edges of the image. Canvas is just as important in SVG as it is in PNG or JPG.
Adobe Illustrator can save to SVG.
When saving, another dialog box with settings will appear. To be honest, I don't know much about them. There is a whole tutorial on SVG Profiles. I'm fine with SVG 1.1.
It's worth noting here that you have the option to click OK and save the file, or click the “SVG Code ...” button, which will open a TextEdit window (on Mac at least) with the SVG code.
Both options can come in handy.
In Illustrator Workspace was 612px ✕ 502px.
These are the dimensions that the image on the page will have, if you do not specify them specifically. Its dimensions can be changed by setting width attributes or height for img, just like PNG or JPG. Here's an example:
Browser support
One option is checking support via Modernizr and replacing the src for the image:
if (! Modernizr.svg) ($ (". logo img") .attr ("src", "images / logo.png");)David Bushell has provided a very simple alternative if you don't mind JavaScript in your markup:
"this.onerror = null; this.src =" image.png "">
For this way of inserting SVG, you can use the following degradation techniques:
<svg> ... svg> <div class = "fallback">div>Using Modernizr again:
.logo-fallback (display: none; / * Make sure the size matches the size of the SVG * /) .no-svg .logo-fallback (background-image: url (logo.png);)Adding SVG to a Page Using a Tag
If for some reason you don't like the option of inserting SVG directly into the document (it still has a couple of drawbacks, for example, caching is almost impossible), you can include the SVG file using
<object type = "image / svg + xml" data = "kiwi.svg" class = "logo"> Kiwi Logo object>In case this is not supported, we implement the degradation using the class that Modernizr adds:
.no-svg .logo (width: 200px; height: 164px; background-image: url (kiwi.png);)This approach has no caching issues and is supported by browsers. it is better, than others. But if you use external file with styles or