There's More Than One Way to Style It


Table of Contents

SVG Styling Approaches
Trade-offs
Objective Features of the Styling Approaches
The Redundancy Argument
Subjective Comparison of Styling Approaches
Reducing Bandwidth or File Size
Higher-level Semantic Meaning
Styling a Group of Elements
Scripting Styles
Styling Suggestions
Case: Hand Authoring Images
Case: Target does not support CSS
Case: Generating SVG Using Code
Case: Using XSLT to Change SVG
Case: Providing Default Styling
Case: Applying a Large Number of Style Variations
Case: Styling All Text the Same
Case: Default Style on All Elements of a Type
Case: Multiple Elements with the Same Style
Case: Reducing File Size
Case: Change Styling Through Scripting
Case: Animate Styling Through SMIL
Case: Skinning an Image
Case: Applying Consistent Styles to Multiple Images
Case: Non-Overrideable Style
Summary: Expressiveness and Context
A. Acknowledgements

The SVG specification has always supported applying styling information to graphical objects through both presentation attributes and CSS. CSS can be applied either through CSS selectors or directly through the style attribute on particular graphical elements.

The authors of the SVG specification explicitly chose to support both approaches. In fact, Section 6 "Styling" of the SVG 1.1 specification specifies particular use cases for the each styling approach. It also contains two or three sections describing the relative advantages and disadvantages of the two.

Despite the careful consideration that went into the decision, there are people who have argued that the different approaches are too complicated or redundant.

Styling graphical elements turns out to be a surprisingly complex problem. Any given element has several different features that may need to be styled independently of the others. Describing the styling for any reasonable image multiplies that complexity by the number of elements in the image.

When attempting to solve any set of complex problems, we normally learn that there is no one, true solution that solves every problem. Whether you refer to it as a silver bullet or a golden hammer, the single perfect solution always seems to be an illusion. One reason is that no problem stands alone. It is surrounded by other forces or requirements that prevent this instance of the problem from being exactly like another instance of the same problem.

In many fields, there are a number of different standard solutions that can be applied to the problems of the field. Each of these solutions has advantages and limitations. At some point in time, each solution was better than the others in some specific instance of the problem. Sometimes the differences are profound, and sometimes they are subtle. When solving a problem, you have to weigh the advantages and limitations of the different solutions and make trade-offs based on your specific instance of the problem.

When creating images or applications with SVG, we have access to a rich set of tools. When drawing a four-sided shape, you can choose between a path, a polygon, or a rect element. Each approach solves some problems better than others. When styling that shape, you can choose between presentation attributes and CSS. This design gives flexibility in styling similar to our flexibility in structure.

In different circumstances, each of these choices for shape or styling may be the best solution to a particular instance of the problem you are solving.

According to the SVG 1.1 specification all of the presentation capabilities of CSS are supported by presentation attributes. Likewise, there is nothing that you can do with presentation attributes that is not equivalently supported by CSS.

Neither approach has more presentation functionality than the other. This was an intentional design decision. Because of this decision, each of the following examples renders to the exact same image. For simplicity, we will use a solid green rectangle with a 2 pixel-wide blue border.


In the first example, we use presentation attributes to style the rectangle. Anybody with XML experience should have no problem understanding how to modify the styling in this case. This is one of the benefits of presentation attributes.


The second example uses the style attribute. This approach is easily understandable to anyone who has worked with CSS. Like the presentation attribute approach, the style attribute affects only this element.


The third example shows the use of CSS selectors. Like the style attribute, this approach should be familiar to most people doing modern web development. This approach separates the styling information from the structure of the objects. Although this example does not show it, the styling could be stored in an external stylesheet. Because the rect selector is used, this style would have affected every rectangle in the document. But since there is only one rect, the net effect is the same as the other examples.


Although each approach has its benefits, they all render to exactly the same displayed image. If you are familiar with any one of these approaches, reading the others is not difficult.

None of these approaches has any overwhelming objective advantage when it comes to styling individual elements. So, from a purely objective point of view they can all be considered equivalent, at least for static documents. Even though, in certain situations, each may have a minor advantage over the others.

One of the more frequent arguments in the styling discussion is that multiple styling approaches is redundant. The specification requires that both styling approaches should be capable of performing the same styling. In other words, neither approach should be able to style elements in ways the other can not. This argument goes further to suggest that since all SVG viewers and interpreters are required to support presentation attributes, CSS support should be dropped.

A counter to the redundancy argument is that the different approaches provide some expressiveness for the author, above and beyond the simple mechanics of styling. This is the same reason we have the special-purpose object elements. A rect element conveys much more information than a series of L commands in a path.

The redundancy argument normally comes from people that want SVG to be a minimal language. The idea is that there should be only one way to do anything with the language. Many people suggest that a good language should always be minimal. Others believe that a richer, more expressive language is a good thing.

This redundant information can convey context to the author or anyone else reading the source. It could also provide more information for something similar to a screen reader-type program. This could help with increasing the accessibility of the image for the visually impaired.

Since the minimal vs. expressive language argument has been going on with respect to programming languages for over 30 years, this paper has very little chance of resolving the argument in this case.

We have established that there are no objective reasons to choose either the CSS or presentation attributes approach over each other. However, there are many trade-offs of a more subjective nature that can help steer the decision on how to style a given image.

The obvious subjective method for deciding on a given styling approach is to pick the one you are most familiar with or that you like better. While it is an easy choice, this decision can lead to a tactic of applying the same hammer regardless of the problem to solve.

A better strategy is to become familiar with the strengths and weaknesses of each approach. Then you can make an appropriate trade-off for each situation. Better understanding leads to more flexibility of design. An obvious way to increase understanding is to explore some of these strengths and weaknesses.

One of the claimed benefits of CSS is decrease in file size. The decrease in file size only occurs because of two effects:

  1. Sharing the same styles across multiple files.

  2. Sharing the same styles on multiple elements.

If you are not working with multiple images that would share styles in some way, you cannot take advantage of the first effect. For example, a single, standalone image obviously cannot share styling, because there is nothing to share with.

If, on the other hand, you have a dozen related images requiring similar styling, an external stylesheet containing the shared styles could be an excellent way to reduce overall file size by reducing redundant styling. If the viewer implements caching (like most browsers), it would not need to download the external stylesheet more than once. Depending on the styling and the number of files, this can result in a significant bandwidth savings.

Likewise, if none of the elements in your image has related styles, CSS cannot reduce file size by reducing repeated style references. On the other hand, if your image has a series of elements that make up similar objects, CSS can be an effective way to make certain that all lines are 2 pixels wide and black, while all rects are just filled and not stroked.

To show the kind of difference CSS can make in file size, we need an example. This is a relatively straight-forward bar graph.


The following example is the source for the image using CSS for styling.


To compare, the following example is the exact same image styled using presentation attributes.

                    <svg viewBox="0 0 500 400" xmlns="http://www.w3.org/2000/svg">
                        <path d="M50,365h400m-200,0v-330" fill="none" id="axes"
                            stroke="#000" stroke-linejoin="miter" stroke-width="1px"/>
                        <text x="250" y="22" text-anchor="middle"
                            font-family="Helvetica,Arial,sans-serif" font-size="18px"
                            color="#000">Relative Measure of Satisfaction</text>
                        <text x="60" y="385" text-anchor="middle"
                            font-family="Helvetica,Arial,sans-serif" font-size="15px"
                            color="#000">Very Dissatisfied</text>
                        <text x="250" y="385" text-anchor="middle"
                            font-family="Helvetica,Arial,sans-serif" font-size="15px"
                            color="#000">Neutral</text>
                        <text x="440" y="385" text-anchor="middle"
                            font-family="Helvetica,Arial,sans-serif" font-size="15px"
                            color="#000">Very Satisfied</text>
                        <rect fill="#0f0" height="30" stroke="#000" stroke-width="1px" width="180"
                            x="250" y="45"/>
                        <text x="20" y="65" font-family="Helvetica,Arial,sans-serif" font-size="15px"
                            color="#000">Group A</text>
                        <rect fill="#0f0" height="30" stroke="#000" stroke-width="1px" width="100"
                            x="250" y="85"/>
                        <text x="20" y="105" font-family="Helvetica,Arial,sans-serif" font-size="15px"
                            color="#000">Group B</text>
                        <rect fill="#0f0" height="30" stroke="#000" stroke-width="1px" width="40"
                            x="250" y="125"/>
                        <text x="20" y="145" font-family="Helvetica,Arial,sans-serif" font-size="15px"
                            color="#000">Group C</text>
                        <rect fill="#0f0" height="30" stroke="#000" stroke-width="1px" width="25"
                            x="250" y="165"/>
                        <text x="20" y="185" font-family="Helvetica,Arial,sans-serif" font-size="15px"
                            color="#000">Group D</text>
                        <rect fill="#f00" height="30" stroke="#000" stroke-width="1px" width="20"
                            x="230" y="205"/>
                        <text x="20" y="225" font-family="Helvetica,Arial,sans-serif" font-size="15px"
                            color="#000">Group E</text>
                        <rect fill="#f00" height="30" stroke="#000" stroke-width="1px" width="50"
                            x="200" y="245"/>
                        <text x="20" y="265" font-family="Helvetica,Arial,sans-serif" font-size="15px"
                            color="#000">Group F</text>
                        <rect fill="#f00" height="30" stroke="#000" stroke-width="1px" width="90"
                            x="160" y="285"/>
                        <text x="20" y="305" font-family="Helvetica,Arial,sans-serif" font-size="15px"
                            color="#000">Group G</text>
                        <rect fill="#f00" height="30" stroke="#000" stroke-width="1px" width="170"
                            x="80" y="325"/>
                        <text x="20" y="345" font-family="Helvetica,Arial,sans-serif" font-size="15px"
                            color="#000">Group H</text>
                    </svg>

Example 5. Bar graph using presentation attributes for styling.


The CSS version weighs in at 1623 bytes, the presentation attributes version is 2438. So, the CSS version is 33% smaller. If we remove the text labeling the bars, the CSS is only 16% smaller. Depending on the mix of elements, the redundancy in the styles, and the size of the image, this difference will vary. There are some reports of higher reductions in real-world applications.

Obviously, either version could be made substantially smaller through compression. However, there may be circumstances where compression is not appropriate. As usual, the best choice depends on the situation.

One of the biggest benefits of using CSS for styling is the use of the class attribute to group objects with related styles. By choosing good names, these classes can give extra semantic information to the author or maintainer of the image. For example, using a class of error conveys useful information that a color of red or an italic font does not.

The semantic benefit of using a class for styling can simplify authoring and reading the SVG source text. Good tools can provide clues and help generating classes for repeated styles.

As an example, the following is a image displaying the votes taken at a meeting. The chair icons repesent the various members. The chairs are styled to show how each member voted: yes, no, or abstain. (The chairman in the top-center has not voted.)


The following example is the source for the image using the CSS approach to styling. Careful choice of the name of the CSS class has resulted in high-level information being attached directly to the objects. The vote associated with each chair is readily available.

                    <svg viewBox="0 0 600 430" xmlns="http://www.w3.org/2000/svg"
                        xmlns:xlink="http://www.w3.org/1999/xlink">
                        <defs>
                            <g id="chair">
                                <rect height="40" rx="15" ry="15" width="40" x="-20" y="-20"/>
                                <ellipse cx="0" cy="-24" rx="16" ry="4" />
                                <rect height="30" rx="4" ry="10" width="8" x="-28" y="-15"/>
                                <rect height="30" rx="4" ry="10" width="8" x="20" y="-15"/>
                            </g>
                        </defs>
                        <style type="text/css">
                            .legend { stroke: #000; stroke-width: 1px; }
                            .legend text { stroke: none; font-size: 12px; font-family:Times,serif; }
                            .table { stroke: #000; fill: tan; stroke-width: 1px; }
                            use { stroke: #000; stroke-width: 1px; fill:none; }
                            .yes { fill: violet; }
                            .no { fill: gold; }
                            .abstain { stroke: silver; fill: none; }
                        </style>
                        <rect class="table" height="80" width="280" x="160" y="60"/>
                        <rect class="table" width="80" height="280" x="120" y="140"/>
                        <rect class="table" width="80" height="280" x="400" y="140"/>

                        <g class="legend" transform="translate(475,45)">
                            <rect style="fill:none; stroke:#888;" height="65" width="80"/>
                            <rect class="yes" height="15" width="15" x="10" y="5" />
                            <text x="30" y="17">Yes</text>
                            <rect class="no" height="15" width="15" x="10" y="25" />
                            <text x="30" y="37">No</text>
                            <rect class="abstain" height="15" width="15" x="10" y="45" />
                            <text x="30" y="57">Abstain</text>
                        </g>

                        <use xlink:href="#chair" transform="translate(300,35)"/>
                        <use xlink:href="#chair" class="yes" transform="translate(220,35)"/>
                        <use xlink:href="#chair" class="yes" transform="translate(380,35)"/>

                        <use xlink:href="#chair" class="no" transform="translate(95,170) rotate(-90)"/>
                        <use xlink:href="#chair" class="yes" transform="translate(95,245) rotate(-90)"/>
                        <use xlink:href="#chair" class="yes" transform="translate(95,320) rotate(-90)"/>
                        <use xlink:href="#chair" class="abstain" transform="translate(95,395) rotate(-90)"/>

                        <use xlink:href="#chair" class="yes" transform="translate(510,170) rotate(90)"/>
                        <use xlink:href="#chair" class="abstain" transform="translate(510,245) rotate(90)"/>
                        <use xlink:href="#chair" class="yes" transform="translate(510,320) rotate(90)"/>
                        <use xlink:href="#chair" class="no" transform="translate(510,395) rotate(90)"/>
                    </svg>

Example 6. Vote display using CSS for styling.


To compare, the following is the exact same image styled using presentation attributes for styling. Notice that the semantic information is hidden in the values of the presentation attributes. To retrieve the votes, we would need to decode the styling information back into the semantic form.

                    <svg viewBox="0 0 600 430" xmlns="http://www.w3.org/2000/svg"
                        xmlns:xlink="http://www.w3.org/1999/xlink">
                        <defs>
                            <g id="chair">
                                <rect height="40" rx="15" ry="15" width="40" x="-20" y="-20"/>
                                <ellipse cx="0" cy="-24" rx="16" ry="4" />
                                <rect height="30" rx="4" ry="10" width="8" x="-28" y="-15"/>
                                <rect height="30" rx="4" ry="10" width="8" x="20" y="-15"/>
                            </g>
                        </defs>
                        <rect stroke="#000" fill="tan" stroke-width="1px" height="80" width="280"
                            x="160" y="60"/>
                        <rect stroke="#000" fill="tan" stroke-width="1px" width="80" height="280"
                            x="120" y="140"/>
                        <rect stroke="#000" fill="tan" stroke-width="1px" width="80" height="280"
                            x="400" y="140"/>

                        <g class="legend" transform="translate(475,45)">
                            <rect fill="none" stroke="#888" height="65" width="80"/>
                            <rect stroke="#000" stroke-width="1px" fill="violet" height="15" width="15"
                                x="10" y="5" />
                            <text x="30" y="17" font-size="12px" font-family="Times,serif">Yes</text>
                            <rect stroke="#000" stroke-width="1px" fill="gold" height="15" width="15"
                                x="10" y="25" />
                            <text x="30" y="37" font-size="12px" font-family="Times,serif">No</text>
                            <rect stroke="#000" stroke-width="1px" fill="none" height="15" width="15"
                                x="10" y="45" />
                            <text x="30" y="57" font-size="12px" font-family="Times,serif">Abstain</text>
                        </g>

                        <use xlink:href="#chair" stroke="#000" stroke-width="1px" fill="none"
                            transform="translate(300,35)"/>
                        <use xlink:href="#chair" stroke="#000" stroke-width="1px" fill="violet"
                            transform="translate(220,35)"/>
                        <use xlink:href="#chair" stroke="#000" stroke-width="1px" fill="violet"
                            transform="translate(380,35)"/>

                        <use xlink:href="#chair" stroke="#000" stroke-width="1px" fill="gold"
                            transform="translate(95,170) rotate(-90)"/>
                        <use xlink:href="#chair" stroke="#000" stroke-width="1px" fill="violet"
                            transform="translate(95,245) rotate(-90)"/>
                        <use xlink:href="#chair" stroke="#000" stroke-width="1px" fill="violet"
                            transform="translate(95,320) rotate(-90)"/>
                        <use xlink:href="#chair" stroke="silver" stroke-width="1px" fill="none"
                            transform="translate(95,395) rotate(-90)"/>

                        <use xlink:href="#chair" stroke="#000" stroke-width="1px" fill="violet"
                            transform="translate(510,170) rotate(90)"/>
                        <use xlink:href="#chair" stroke="silver" stroke-width="1px" fill="none"
                            transform="translate(510,245) rotate(90)"/>
                        <use xlink:href="#chair" stroke="#000" stroke-width="1px" fill="violet"
                            transform="translate(510,320) rotate(90)"/>
                        <use xlink:href="#chair" stroke="#000" stroke-width="1px" fill="gold"
                            transform="translate(510,395) rotate(90)"/>
                    </svg>

Example 7. Vote display using presentation attributes for styling.


The key in these examples is not the fact that the CSS version is lighter (almost 300 bytes less). The important part of this example is that the semantic information is available directly from the image.

Being able to see the meaning of a particular style is useful when building or maintaining the image. Not everyone looks at the source when maintaining an image, so this may not seem important. However, the same semantic argument applies to scripting (and possibly even to SMIL animation, but I don't have as much experience there). This issue is covered in more detail in Scripting Styles.

One place where CSS-based styling can really shine is applying the same style to sets of elements. Whether the styling should be applied to all elements of a given type or just the ones marked with a given class, CSS selectors provide a powerful mechanism for selecting a subset of the elements in an image.

Presentation attributes can also apply to a number of elements through a mechanism of inheritance. In most cases, the default value for a presentation attribute is inherit. This means that the value for the presentation attribute is inherited from the enclosing element (usually a g or svg element). While this does provide a mechanism for reusing styling information, it is not as flexible as CSS selectors.

Another limitation of attribute inheritance is that an object can only inherit from an element that contains it. There is no way to inherit different attributes from different elements unless they form a strict hierarchy. While that works in many cases, not all relationships can be expressed as a hierarchy.

If the same styling should be applied to multiple elements, a set of styles can be grouped as a CSS class. This class can be applied to individual elements, giving some of the benefits of global changes but with the ability to target elements. Multiple CSS classes can be applied to one element, resulting in substantial flexibility.

The last section used CSS classes to good effect for reusing styling on the chairs. The presentation attributes version did not do a very good job of reuse. The following example shows the use of grouping and inherited presentation attributes to manage some reuse of styling.

                    <svg viewBox="0 0 600 430" xmlns="http://www.w3.org/2000/svg"
                        xmlns:xlink="http://www.w3.org/1999/xlink">
                        <defs>
                            <g id="chair">
                                <rect height="40" rx="15" ry="15" width="40" x="-20" y="-20"/>
                                <ellipse cx="0" cy="-24" rx="16" ry="4" />
                                <rect height="30" rx="4" ry="10" width="8" x="-28" y="-15"/>
                                <rect height="30" rx="4" ry="10" width="8" x="20" y="-15"/>
                            </g>
                        </defs>
                        <rect stroke="#000" fill="tan" stroke-width="1px" height="80" width="280"
                            x="160" y="60"/>
                        <rect stroke="#000" fill="tan" stroke-width="1px" width="80" height="280"
                            x="120" y="140"/>
                        <rect stroke="#000" fill="tan" stroke-width="1px" width="80" height="280"
                            x="400" y="140"/>

                        <g class="legend" transform="translate(475,45)">
                            <rect fill="none" stroke="#888" height="65" width="80"/>
                            <rect stroke="#000" stroke-width="1px" fill="violet" height="15" width="15"
                                x="10" y="5" />
                            <text x="30" y="17" font-size="12px" font-family="Times,serif">Yes</text>
                            <rect stroke="#000" stroke-width="1px" fill="gold" height="15" width="15"
                                x="10" y="25" />
                            <text x="30" y="37" font-size="12px" font-family="Times,serif">No</text>
                            <rect stroke="#000" stroke-width="1px" fill="none" height="15" width="15"
                                x="10" y="45" />
                            <text x="30" y="57" font-size="12px" font-family="Times,serif">Abstain</text>
                        </g>

                        <g stroke="#000" stroke-width="1px" fill="none">
                            <use xlink:href="#chair" transform="translate(300,35)"/>
                        </g>

                        <g id="yes" fill="violet" stroke="#000" stroke-width="1px">
                            <use xlink:href="#chair" transform="translate(220,35)"/>
                            <use xlink:href="#chair" transform="translate(380,35)"/>
                            <use xlink:href="#chair" transform="translate(95,245) rotate(-90)"/>
                            <use xlink:href="#chair" transform="translate(95,320) rotate(-90)"/>
                            <use xlink:href="#chair" transform="translate(510,170) rotate(90)"/>
                            <use xlink:href="#chair" transform="translate(510,320) rotate(90)"/>
                        </g>

                        <g id="no" stroke="#000" stroke-width="1px" fill="gold">
                            <use xlink:href="#chair" transform="translate(95,170) rotate(-90)"/>
                            <use xlink:href="#chair" transform="translate(510,395) rotate(90)"/>
                        </g>

                        <g id="abstain" stroke="silver" stroke-width="1px" fill="none">
                            <use xlink:href="#chair" transform="translate(95,395) rotate(-90)"/>
                            <use xlink:href="#chair" transform="translate(510,245) rotate(90)"/>
                        </g>
                    </svg>

Example 8. Vote display using grouping to reuse presentation attributes.


While this approach reduces the overhead of using presentation attributes close to the level of CSS, it requires changing the structure of the image. The individual chair objects are moved to put them in the right group. Unlike the original images, adjacent chair objects are no longer adjacent in the image. This may impact maintenance or attempts at scripting.

Scripting can be used to modify the styling of elements using either approach. Since each approach has its own advantages and limitations, there are trade-offs in scripting each style. Some kinds of applications work better with one approach, and some work better with the other.

The main advantage of presentation attributes where scripting is concerned has to do with flexibility. Any element can have each of its presentation attributes changed individually. Moreover, you can change each presentation attribute to any legal value, not just a set of styles defined in the stylesheet.

You can use scripting to add or remove presentation attributes relatively easily. Any presentation attribute on any existing element can also be changed easily. The DOM methods hasAttributeNS, getAttributeNS, setAttributeNS, and removeAttributeNS support querying, changing and removing any attribute.

The main disadvantage of presentation attributes is actually the same issue. In order to change multiple attributes of an element, multiple DOM calls are needed. Extensive style changes to a large number of elements can become repetitive and tiresome. Careful script design can help simplify some of the redundancy, but extra code may be needed to track which elements have (or need) which style changes.

In many applications, you do not need infinite flexibility in the styles for any given element. If there are a limited number of styles to choose from, you can define those styles in the stylesheet initially as CSS-based styles and then change the class associated with an element to restyle it.

This approach can result in a large change in the styling of an element with only one DOM call to set a class attribute. Depending on the structural layout of the SVG image, it is possible to change a large number of elements with a single change to the class of an enclosing g element. More important than the reduced number of calls is the fact that the class attributes can also be interpreted as markers to show what elements have which styles.

While it is possible to change the stylesheet associated with an SVG image using the new DOM Level 2 CSS Interface, that is not always the best approach. It is often more convenient to define a set of classes and choose among them as needed.

Assuming that we wanted code to script the voting examples above, we would need functions to convert a given chair to new styling based on a vote. The functions below all assume that the element to be changed is supplied to the function. We'll just assume that these elements are retrieved through other code.


The functions for manipulating the CSS classes are pretty obvious and simple. Interestingly, there is almost no real style information in the functions, despite the fact that they change the styling of the elements.


The presentation attribute versions of these functions contains the actual styling information. In addition, we need twice as much DOM manipulation, because we need to set the fill and stroke separately. Obviously, if we decided to change more aspects of the styling, there would be more DOM work needed.


The functions to change the groups could be made simpler by storing the elements for the groups somewhere. The real work is performed by the appendChild() call. Fortunately, the function removes the element from its previous location. Otherwise, we would have a bit more work.

As we have seen, each of the styling approaches has advantages and limitations. The only way to make informed trade-offs between the approaches is by understanding their strengths and weaknesses. One good way to get a feel for the kinds of trade-offs one might make in styling is through examples.

This section covers a few issues that are ancillary to the problem you are solving with your SVG and suggests an approach for that issue. The suggestions explore some of the limitations and advantages of the different approaches.

In many real-world applications, you may need to apply different suggestions to different parts of your problem. The optimal solution on a complex image is often a hybrid approach rather than one styling solution applied religiously throughout.

There are a number of strategies that can help reduce file size. Don't use unnecessary resolution in your coordinates and lengths. Re-use complex objects with the use tag if possible, rather than duplicate a lot of XML. The best strategy of all would be to use gzip compression to make .svgz files as allowed in the specification.

Sometimes, the above tactics are not enough or cannot be used. Then, careful use of the appropriate styling approach may be enough to make a difference.

For very simple images with only a few objects or for images where no two objects share any styling information, presentation attributes may be result in the smallest file size. For most other images, carefully designed CSS can result in a substantial size reduction.

When looking at either approach, the way to reduce file size is to reduce unnecessary redundancy. You should share the same styling on multiple elements either through grouping and presentation attribute inheritance (see Styling a Group of Elements) or through careful use of CSS selectors (see Reducing Bandwidth or File Size).

Consider the image in the example below where the form and major elements remain the same but we want to change the coloring of objects into one of several different palettes. This technique is sometimes called skinning when refering to user interfaces.

Depending on the application, the image could be skinned with a small set of specifically defined styles or with a user-chosen style. The important point is the ability to make sweeping changes all at once.

CSS classes are extremely well-suited to solving this problem. Instead of directly styling the elements, each element is assigned a class or group of classes. By changing an external stylesheet associated with the image, the entire look can change.



Using the default skin (Example 16, “Default Skin”) shown above, the resulting image looks like this.


By applying a different stylesheet (Example 17, “The Dark Stylesheet”), we can get a completely different look.



To really drive the point home, we can change the stylesheet to Example 18, “The Silver Stylesheet” and get yet another look, without changing anything in the image.



For certain applications, this can be a powerful tool.

This paper argues that none of the styling approaches is best in an objective sense because there is no styling that one approach can do that the others can not. Despite this fact, there are more factors involved than just the objective styling ability of each approach.

Some of these subjective features are obvious like file size. Most are more subtle. In some circumstances, readability and maintainability are more important than styling functionality. Unfortunately, there is no really objective measures for readability or maintainability. These features are extremely subjective.

Different styling approaches vary in their expressiveness. In some cases, presentation attributes express exactly what you want. In other cases, CSS may be more expressive. Using different styling approaches can provide a person reading the document with insight into the author's intent. This insight is not important to the program displaying the SVG, but it can be important to a person.

This expressiveness can be very important to both the programmer developing SVG applications and the artist or designer making art with SVG.

A. Acknowledgements

My wife, Debbie Campbell, provided significant editing to help turn my attempts into something readable. Any remaining errors are purely my responsibility.