With all the possible ways of declaring styles, it frequently occurs that multiple values for a given style property could apply to a single element. This is where the cascade comes in: the rules that govern the waterfall of different style declarations, one replacing another until a final value is determined.
For the most part, the CSS cascade works the same in SVG as it does in CSS-styled HTML. However, presentation attributes add an extra twist.
The order of precedence of CSS rules is determined by four factors:
1. The source of the style declaration: browser defaults, web page author values, or user settings.
2. The importance of the rule (either !important or not).
3. The specificity of the CSS selector.
4. The state of animations or transitions; animations override other rules of the same source, importance, and specificity. Transi‐
tions override animations.
5. The order in which the declarations are encountered by the CSS parser; when all else is equal, later declarations replace previous ones.
Regular style declaration sources are ranked in the following order, from the least to most important:
1. The defaults from the CSS property definitions. For the root ele‐
ment, this is the initial value. For example, SVG fill is by default black. For all other elements, it is either initial or inherit, depending on whether the property is normally inher‐
ited.
2. Web browser (or other user agent) default styles for a particular element or pseudoclass, or defaults declared in the specifica‐
tions. There are very few such styles for SVG: one example is that overflow is hidden on some SVG elements.
3. User preferences set in the web browser. For example, many browsers allow users to specify a default font.
4. Styles defined by the web page, in the markup, in <style>
blocks, or from external stylesheets.
For !important rules, the ranking of sources is reversed: important user preferences override all author styles, including important ones. These are usually related to accessibility issues, such as setting a minimum font size or requiring high-contrast color combinations.
Important browser styles are even stronger, and usually relate to fundamental features of the language, such as the fact that linearGradient elements do not display, regardless of the display value an author might set.
Because SVG text is often artistic, browsers may or may not apply user’s accessibility preferences to modify the author’s styles.
When multiple style rules declared by the same source could apply to a given element, they are ranked according to the specificity of the CSS selector used. There are three components to selector spe‐
cificity, in order from least to most important:
CSS in SVG | 81
1. Element tag names and pseudo-element selectors.
2. Classes, pseudo-classes, and attribute-based selectors.
3. ID values.
A given selector may have many components, so the total number of components of each category is counted. If two selectors are tied for the number of id references (possibly none), then the number of class and class-like components is counted. If still tied, the number of element components is used. A universal selector, *, has zero spe‐
cificity when comparing stylesheet rules, but still trumps over pre‐
sentation attributes, inherited values, and browser defaults.
Presentation attributes are treated as if they had selectors with a specificity slightly less than zero.
The style attribute acts like the most specific selector of all.
After all styles from all sources have been cascaded, if the final value for an element is still inherit or initial, the corresponding value is substituted in.
The cascading and specificity rules can be used to create a stylesheet that completely overrules presentation attributes in the code, for example to create a separate set of styles for black-and-white print‐
ing. Example 3-1 presents such a stylesheet for the stoplight with gradients code from Example 1-5 in Chapter 1. The only modifica‐
tion to the SVG code (which had used presentation attributes) is a class name added to the <g> element that contains the separate lights
—and a link to include the print stylesheet. The result is shown in Figure 3-1.
Example 3-1. Stylesheet for Monochrome Printing of an SVG
* { fill: inherit;
stroke: inherit;
stroke-width: inherit;
}
g.lights { fill: lightgray;
stroke: dimgray;
stroke-width: 1;
}
rect { fill: none;
stroke: black;
stroke-width: 2;
}
The universal selector (*) is used to reset the styles declared on all elements using presentation attributes.
The inherit keyword is used, instead of setting a value directly on every element, so that style inheritance will work normally.
All the lights are given the same appearance, by setting the styles once on the <g> element (which has been given a class name to aid CSS styling).
The <rect> is styled separately. Note that, because we reset the stroke and stroke-width presentation attributes for all ele‐
ments, the styles have to be set in the CSS even when, like the black stroke, they have not been changed from the original.
CSS in SVG | 83
84 | Chapter 3: A Sense of Style
If there are multiple valid stylesheet rules with the same specificity, the final value is used. To determine which value comes last, differ‐
ent stylesheets and blocks are concatenated together in the order in which they are included in the document. This allows you to use an external stylesheet for many documents and then modify it for a particular document using a <style> block. It also allows you to specify fallback styles for new features that may not be universally supported.