diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /docs/code-quality/coding-style/svg_guidelines.rst | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'docs/code-quality/coding-style/svg_guidelines.rst')
-rw-r--r-- | docs/code-quality/coding-style/svg_guidelines.rst | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/docs/code-quality/coding-style/svg_guidelines.rst b/docs/code-quality/coding-style/svg_guidelines.rst new file mode 100644 index 0000000000..b0f122b76e --- /dev/null +++ b/docs/code-quality/coding-style/svg_guidelines.rst @@ -0,0 +1,347 @@ +SVG Guidelines +============== + +Pros and cons of SVG for images +------------------------------- + +When used as a document format there is usually a compelling reason that +makes SVG the only solution. When used as an `image +format <https://developer.mozilla.org/en-US/docs/Web/SVG/SVG_as_an_Image>`__, +it is sometimes less obvious whether it would be best to use SVG or a +raster image format for any given image. The vector format SVG and +raster formats like PNG both have their place. When choosing whether or +not to use SVG it is best to understand the advantages and disadvantages +of both. + +File size + Whether SVG or a raster format will produce a smaller file for a + given image depends very much on the image. For example, consider an + image of a path with a gradient fill. The size of an SVG of this + image will be the same regardless of the dimensions of the image. On + the other hand the size of a raster file of the same image will + likely vary tremendously depending on the dimensions of the image + since the larger the dimensions the more pixel data the file needs to + store. At very small dimensions (the extreme case being 1px x 1px) + the raster file will likely be much smaller than the SVG file since + it only needs to store one pixel of data. At large dimensions the + raster file may be much larger than the SVG file. +Scalability, with caveats + One of the primary advantages of SVG is that as it is scaled it does + not pixelate. However, this is not to say that it always does away + with the need to have a collection of raster images for display at + different scales. This can be particularly true for icons. While SVG + may scale well enough for flat-ish icons without a lot of detail, for + icons that try to pack in a lot of detail graphic artists generally + `want to be able to pixel + tweak <https://www.pushing-pixels.org/2011/11/04/about-those-vector-icons.html>`__. +Performance + While SVG provides a lot of flexibility in terms of scaling, + themability, etc. this flexibility depends on doing computations for + SVG images at the time they're displayed, rather than at the time the + author creates them. Consider an image that involves some complex + gradients and filters. If saved as a raster image then the work to + rasterize the gradients and filters takes place on the authors + computer before the result is stored in the raster file. This work + doesn't need to be redone when the image is displayed on someone + else's computer. On the other hand, if the image is saved as an SVG + image then all this work needs to be done each time the SVG is + displayed on someone else's computer. This isn't to say that SVG + images are always slower than raster equivalents. In fact it can be + faster to send vector information from an SVG to a user's GPU than it + is to extract raster data from an equivalent raster image. And even + when an SVG image is slower than a raster equivalent, the difference + is usually not noticeable. However, just don't fall into the trap of + thinking that SVGs are faster than equivalent raster images, or vice + versa. Once again, "it depends". + +Authoring guidelines +-------------------- + +A lot of SVG files (particularly those generated by SVG editors) ship +without being cleaned up and can contain a ton of junk that bloats the +file size and slows down rendering. In general the best way to combat +this is to first run SVG files through a linter such as +`svgo <https://github.com/svg/svgo>`__ (see the Tools section below). +However, when authoring SVGs by hand here are some best practices to +help keep them lightweight. These rules are based on some real examples +seen in Mozilla's code. + +Basics +~~~~~~ + +- Two spaces indenting +- No useless whitespaces or line breaks (see below for more details) +- Adding a license header +- Use double quotes + +Whitespace and line breaks +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Whitespace +^^^^^^^^^^ + +In addition to trailing whitespace at the end of lines, there are a few +more cases more specific to SVGs: + +- Trailing whitespaces in attribute values (usually seen in path + definitions) +- Excessive whitespace in path or polygon points definition + +Whitespace examples +^^^^^^^^^^^^^^^^^^^ + +This path: + +.. code:: svg + + <path d=" M5,5 L1,1z "> + +can be cut down to this: + +.. code:: svg + + <path d="M5,5 L1,1z"> + +Similarly, this polygon: + +.. code:: svg + + <polygon points=" 0,0 4,4 4,0 "/> + +can be cut down to this: + +.. code:: svg + + <polygon points="0,0 4,4 4,0"/> + +Line breaks +^^^^^^^^^^^ + +You should only use line breaks for logical separation or if they help +make the file readable. You should avoid line breaks between every +single element or within attribute values. It's recommended to put the +attributes on the same line as their tag names, if possible. You should +also put the shortest attributes first, so they are easier to spot. + +Unused tags and attributes +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Editor metadata +^^^^^^^^^^^^^^^ + +Vector editors (Inkscape, Adobe Illustrator, Sketch) usually add a bunch +of metadata in SVG files while saving them. Metadata can mean many +things, including: + +- The typical "Created with *editor*" comments +- Non-standard editor specific tags and attributes (``sketch:foo``, + ``illustrator:foo``, ``sopodi:foo``, …) +- The `XML + namespace <https://developer.mozilla.org/en-US/docs/Web/SVG/Namespaces_Crash_Course>`__ + definition that comes with the latter (``xmlns:sketch``, + ``xmlns:sopodi``, …) + +Other metadata +^^^^^^^^^^^^^^ + +In addition to non-standard editor metadata, standard compliant metadata +also exists. Typical examples of this are ``<title>`` and ``<desc>`` +tags. Although this kind of data is supported by the browser, it can +only be displayed when the SVG is opened in a new tab. Plus, in most of +the cases, the filename is quite descriptive So it's recommended to +remove that kind of metadata since it doesn't bring much value. + +You shouldn't include DOCTYPEs in your SVGs either; they are a source of +many issues, and the SVG WG recommends not to include them. See `SVG +Authoring +guidelines <https://jwatt.org/svg/authoring/#doctype-declaration>`__. + +Avoid the use of CDATA sections +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +`CDATA +sections <https://developer.mozilla.org/en-US/docs/Web/API/CDATASection>`__ +are used to avoid parsing some text as HTML. Most of time, CDATA isn't +needed, for example, the content in ``<style>`` tags doesn't need to be +wrapped in a CDATA section as the content inside the tag is already +correctly parsed as CSS. + +Invisible shapes +^^^^^^^^^^^^^^^^ + +There are two kinds of invisible shapes: The off-screen ones and the +uncolored ones. + +The offscreen shapes are hard to spot, even with an automated tool, and +are usually context aware. Those kinds of shapes are visible but off the +`SVG view +box <https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox>`__. +Here's `an +example <https://hg.mozilla.org/mozilla-central/diff/9fb143f3b36a/browser/themes/shared/heartbeat-star-lit.svg>`__ +of a file with offscreen shapes. + +On the other hand, the uncolored ones are easier to spot, since they +usually come with styles making them invisible. They must meet two +conditions: they must be devoid of any fill (or a transparent one) or +stroke. + +Unused attributes on root ``<svg>`` element +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The root ``<svg>`` element can also host many useless attributes. Here's +an +`example <https://hg.mozilla.org/mozilla-central/diff/2d38fecce226/browser/components/loop/content/shared/img/icons-10x10.svg>`__ +taking into account the list below: + +- ``version`` +- ``x="0"`` and ``y="0"`` +- ``enable-background`` (unsupported by Gecko and now deprecated by the + Filter Effects specification) +- ``id`` (id on root element has no effect) +- ``xmlns:xlink`` attribute when there are no ``xlink:href`` attributes + used throughout the file +- Other unused `XML + Namespace <https://developer.mozilla.org/en-US/docs/Web/SVG/Namespaces_Crash_Course>`__ + definitions +- ``xml:space`` when there is no text used in the file + +Other +^^^^^ + +- Empty tags, this may be obvious, but those are sometimes found in + SVGs +- Unreferenced ids (usually on gradient stops, but also on shapes or + paths) +- ``clip-rule`` attribute when the element *is not* a descendant of a + ``<clipPath>`` +- ``fill-rule`` attribute when the element *is* a descendant of a + ``<clipPath>`` +- Unreferenced/Unused clip paths, masks or defs + (`example <https://hg.mozilla.org/mozilla-central/diff/2d38fecce226/toolkit/themes/shared/reader/RM-Plus-24x24.svg>`__) + +Styling +~~~~~~~ + +Styling basics +^^^^^^^^^^^^^^ + +- Privilege short lowercase hex for colors +- Don't use excessive precision for numeric values (usually comes from + illustrator) +- Use descriptive IDs +- Avoid inline styles and use class names or SVG attributes + +Styling examples +'''''''''''''''' + +Here are some examples for excessive number precision: + +- 5.000000e-02 → 0.05 (as seen + `here <https://hg.mozilla.org/mozilla-central/diff/2d38fecce226/browser/themes/shared/devtools/images/tool-network.svg#l1.31>`__) +- -3.728928e-10 → 0 (as seen + `here <https://hg.mozilla.org/mozilla-central/diff/2d38fecce226/browser/themes/shared/aboutNetError_alert.svg#l1.12>`__) +- translate(0.000000, -1.000000) → translate(0, -1) (as seen + `here <https://hg.mozilla.org/mozilla-central/diff/2d38fecce226/browser/themes/shared/heartbeat-icon.svg#l1.13>`__) + +As for descriptive IDs: + +- For gradients: SVG_ID1 → gradient1 (as seen + `here <https://hg.mozilla.org/mozilla-central/diff/2d38fecce226/browser/themes/shared/aboutNetError_alert.svg#l1.12>`__) + +Use of class names +^^^^^^^^^^^^^^^^^^ + +- Avoid using a class if that class is only used once in the file +- If that class only sets a fill or a stroke, it's better to set the + fill/stroke directly on the actual shape, instead of introducing a + class just for that shape. You can also use SVG grouping to avoid + duplicating those attributes +- Avoid introducing variants of the same file (color/style variants), + and use sprites instead (with class names) + +Default style values +^^^^^^^^^^^^^^^^^^^^ + +There's usually no need to set the default style value unless you're +overriding a style. Here are some commonly seen examples: + +- ``style="display: none;"`` on ``<defs>`` elements (a ``<defs>`` + element is hidden by default) +- ``type="text/css"`` on ``<style>`` elements +- ``stroke: none`` or ``stroke-width: 0`` + +SVG grouping +~~~~~~~~~~~~ + +Style grouping +^^^^^^^^^^^^^^ + +Group similarly styled shapes under one ``<g>`` tag; this avoids having +to set the same class/styles on many shapes. + +Avoid excessive grouping +^^^^^^^^^^^^^^^^^^^^^^^^ + +Editors can sometimes do excessive grouping while exporting SVGs. This +is due to the way editors work. + +Nested groups +''''''''''''' + +Avoid multiple-level nesting of groups, these make the SVG less +readable. + +Nested transforms +''''''''''''''''' + +Some editors use ``<g>`` tags to do nested transforms, which is usually +not needed. You can avoid this by doing basic algebra, for example: + +.. code:: svg + + <g transform="translate(-62, -310)"><shape transform="translate(60, 308)"/></g> + +can be cut down to: + +.. code:: svg + + <shape transform="translate(-2,-2)"/> + +because: -62+60 = -310+308 = -2 + +Performance tips +~~~~~~~~~~~~~~~~ + +These rules are optional, but they help speeding up the SVG. + +- Avoid using a ``<use>`` tag when that ``<use>`` tag is being + referenced only once in the whole file. +- Instead of using CSS/SVG + `transforms <https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform>`__, + apply directly the transform on the path/shape definition. + +Tools +~~~~~ + +Tools can help to clean SVG files. Note, however that some of the rules +stated above can be hard to detect with automated tools since they +require too much context-awareness. To this date, there doesn't seem to +be a tool that handles all of the above. However, there are some +utilities that cover parts of this document: + +- Mostly complete command line tool: https://github.com/svg/svgo +- Alternatives to SVGO: + + - https://github.com/RazrFalcon/svgcleaner + - https://github.com/scour-project/scour + +- GUI for command line tool (use with "Prettify code" and "Remove + ``<title>``" options on): https://jakearchibald.github.io/svgomg/ +- Good alternative to SVGO/SVGOMG: + https://petercollingridge.appspot.com/svg-editor +- Fixes the excessive number precision: + https://simon.html5.org/tools/js/svg-optimizer/ +- Converts inline styles to SVG + attributes: https://www.w3.org/wiki/SvgTidy +- RaphaelJS has a couple of utilities that may be useful: + `raphael.js <https://dmitrybaranovskiy.github.io/raphael/>`__ |