Problem/Motivation

We need some guidelines for svg & svg icons for Drupal core.

The issue have come up during the work on the RSS icon #2427213: Replace feed.png with feed.svg

To sum it up we need Guidelines:

  • How should a svg icons be created stroke's / vectors
  • Which apps do we want it to support (sketch, illustrator ...)?
  • must be editable colors with css (inline) ?
  • Does it even matters & by having "guidelines" the design community will pretty much move on, as they want it to look pretty, not use time on svgo optimization etc.

Proposed resolution

Write a guideline... here is a start:

Goals of SVGs:

  1. Support high-resolution displays automatically -- because SVGs are vectors they can scale up to any pixel density without losing clarity.
  2. Replace as many static image assets in core as possible -- static image assets (jpgs and pngs) currently in Drupal core are not scalable, and do not support hi-res displays so we should attempt to replace as many of them as possible.
  3. Lay framework of best practices that contrib can adopt -- this could mean demonstrations of both inline svgs (ie inside twig templates) as well as external svg assets in core.

Best Practices

  1. Minimize file size

    Since these little icon files are assets that will be loaded (downloaded) millions of times across millions of websites, one of the most important tenants is to require the smallest file size possible for the SVGs in core. So just as "profiling" the server-side implications of changing each phptemplate into twig, so important is it also to ensure SVG files are optimized and even potentially minified. This means manual (or automatic) removal of all "crap" produced by vector design applications like Illustrator, Sketch, and Inkscape. Removal of these elements should not inhibit editability in these applications as the resulting SVG still conforms to the spec.

    There are not so many graphics in Drupal core, so it is not problematic to have high standards here. Once created, the SVG file could be unmodified for years.

    There are a number of ways to optimize SVGs including via the svgo command and/or optimized manually -- each of which might produces better results in different cases. The best method usually depends on the complexity of the SVG. For example, the points required for a rounded rectangle as a <path>end up being more code than using a <rect> with the rx and ry attributes to give the rounded corners. The strategy can be that a designer can create the SVG and someone else can optimize it with svgo or by hand.

  2. Validate against SVG 1.1

    All core assets should pass through the validator http://validator.w3.org successfully. Although, we can ignore the "DOCTYPE missing" error, it seems not necessary and to be removed in SVG 1.2 according to MDN documentation article (about namespaces)

  3. Indentation & coding standards
    • SVG is markup, and therefore should use proper indentation (2 spaces). SVGO strips whitespace by default, so this is something we should maybe discuss further if to sacrifice readability vs weight
    • Like CSS standards, use lowercase hex colors for fill and stroke.
    • Use SMACSS class structures on SVG tags, particularly when there is more than one of the same tag in an SVG. This will facilitate easy style overrides from a theme's CSS.
    • Like CSS standards, classes should be preferred to ID attributes. ID attributes should be stripped, unless they are used as Fragment Identifiers
    • Default presentation attributes (fill/stroke/etc) should be moved off from SVG tags if it reduces the weight, and placed as Internal CSS (inside a <style> tag). Note: this is a manual procedure, there are not many tools to automate this process. Try Illustrator CSS Properties: SVG Elements in the SVG save settings
    • Do not base64 encode inline SVGs -- there are serious performance implications in doing this.
  4. Inline SVG Vs external SVG

    There is no single right answer to inline versus external SVG.

    Inline SVG (i.e. SVG images embedded directly inside twig templates) is preferred over external SVG asset files added via <img> tag, or referenced in CSS backgrounds, in cases where SVG needs to be manipulated (e.g. animated or color changed) via CSS or JavaScript, whereas external SVGs referenced in CSS backgrounds cannot.

    When SVG does not need manipulation, keeping them as external assets has the benefit of SVG files being cached by the browser.

    We need to weigh the pros/cons and analyze the SVG Sprite option also (less HTTP requests, and cacheable).

    Consider also that HTTP 2.0 is minimizing the benefit of "saving HTTP requests".

  5. Fallback methodologies

    Although SVG is widely supported, there are some exceptions, like IE8. There is barely any consensus on the "best way" to support fallbacks. If using inline SVGs (as is the best practice), then by and large the best fallback method has to be the SVG <switch> structure, because it is the only foolproof fallback method that has no dependencies on javascript. The switch tag requires the first element be a group tag <g> followed by a single <foreignObject> tag containing the fallback <img> inside.

    Other fallback methods available: Use .no-svg and .svg classes in css to provide background image fallbacks. Because this fallback method requires modernizr javascript be loaded on the page, this is an inferior solution that should only be considered as a last resort.

  6. SVG Accessibility

    SVG Accessibility is only really applicable to inline SVGs. Inline SVGs can be be given text alternatives by adding a <title id="title"> tag inside the SVG and referencing this using an aria-labelledby="title" attribute on the <svg> tag itself, i.e.:

    <svg aria-labelledby="title">
      <title id="title">Alternative text goes here</title>
      <!-- Remaining SVG code follows. -->
    </svg>
    
    ARIA support is introduced officially into the SVG 2.0 specification, but it is still possible to use ARIA with SVG 1.1 content. Some examples in this article will raise a flag when you validate your HTML, but it’s a reasonable exception to make.

    -- Léonie Watson Tips for Creating Accessible SVG (Sitepoint article)

    If the image content is purely graphical, add the role="img" attribute to the <svg> tag. If the SVG is interactive, make use of <text> tags for readable text and make the interactive elements focusable by wrapping them in <a xlink:href="http://example.com"> tags.

  7. SVG Localization
    SVG can contain text. So if we use <title>and <desc> for accessible labels, these will need to be localizable.
    Can we generate SVG using Twig? How do we cache these per locale?

    The current recommendation is that text in SVGs (particularly visible text) should be avoided. As stated on a blog post from Una Kravets:

    Running the website through the web interface Google Translate Tool could possibly translate the SVG text if the character glyphs exist in the specified font, but may also break the SVG due to viewbox constraints. So even though the diagram text is highlightable, don't rely on SVG images to be the tools you need for text translation.

Tools & Resources

Remaining tasks

User interface changes

API changes

Comments

corbacho’s picture

Thanks for opening the issue. I think is needed. SVG is a dual technology, it's markup and image at the same time. So I agree it's tricky to make "guidelines" for it, because it depends on the use case.

These things cross my mind now:

* Validate against SVG 1.1 ? http://validator.w3.org

* SVG shouldn't have any "trace" of crap, it should be as clean as possible. For performance reasons (less weight, the better) and for readability and cross-compatibility.
SVG is a markup language. The same way that we wouldn't accept the crap HTML+CSS that Dreamweaver outputs (even if it's valid) why we should accept the level of crap that Illustrator/Sketch outputs ?

* SVGO takes 1 second, and automate 90% of the process. Why not use it ? The default settings are good.

* Styling with Internal CSS (instead of inline CSS), is something really cool that can save bytes and cleaner output. This normally requires manual manipulation, it's something SVGO can't do for you.
http://www.w3.org/TR/SVG/styling.html#StylingWithCSS

I know that there is nowadays very few tools to help with some steps, and it's quite manual process.
But in the other hand, there is not so many graphics in Drupal core.. I don't think it's problematic to have high standards here. Once created, the SVG file could be unmodified for years.

Designers can post their designs in drupal.org, and somebody else optimize it. Not all steps needs to be done by the designer.

jwilson3’s picture

Issue summary: View changes

Added a few things to start the guideline out. First and foremost a clear set of goals for SVG in core. And secondly what I consider to be the most important tenant: file size optimization.

Since these little icon files are assets that will be loaded (downloaded) millions of times across millions of websites, one of the most important tenants is to require the smallest file size possible for the SVGs in core. So just as "profiling" the server-side implications of changing each phptemplate into twig, so important is it also to ensure SVG files are optimized and even potentially minified.

jwilson3’s picture

Issue summary: View changes

Added some of comment #1 to guidelines.

jwilson3’s picture

Issue summary: View changes
jwilson3’s picture

Issue summary: View changes
jwilson3’s picture

Issue summary: View changes
jwilson3’s picture

Issue summary: View changes
jwilson3’s picture

Issue summary: View changes
jwilson3’s picture

Issue summary: View changes
jwilson3’s picture

Issue summary: View changes
jwilson3’s picture

Issue summary: View changes
mortendk’s picture

d a m n ! :)

jwilson3’s picture

Bringing over discussion started on #2427213, from mortendk:

can somebody please explain why/if its a crime against [something-something] to have the "sketch" crap in the graphic file ? when svg begins to use maskes then stuff gets a bit tricky "to clean" using svgo, will kill the file - If we have some restrictions on which kinda app we wanna use, or if theres meta data, then we need to write that down somewhere.

So apparently svgo has trouble optimizing certain things, such as masks created in Sketch. It's very possible there are other things svgo cannot handle well.

Additionally, if you're using a mask, then you're essentially hiding data points from view. This is useless data that adds to SVG file size bloat, so in most cases, there is an alternative way to create the path/object you want, that may even (not always) result in a smaller and less complicated SVG file. In Illustrator one would expand the paths and or instead of a mask, overlay what would have been the mask layer on top -- select both layers and use the "Crop" button inside the "Pathfinder" pane, this would result in a simple single <path> element.

So, I believe that best practices would dictate that we should stick to the utter basic SVG elements for three reasons:

  • markup that is simple to read and understand in the SVGs.
  • so that automated compression mechanisms like svgo can be leveraged.
  • better cross-compatibility between image editors.
jwilson3’s picture

Issue summary: View changes
Issue tags: +icons, +svg

Added point about accessibility.

jwilson3’s picture

Issue summary: View changes

More changes on accessibility.

jwilson3’s picture

Issue summary: View changes

A place for links to tools and resources.

mortendk’s picture

A quick thoght what do we know about optimization from popular apps, lets face it designers are a bunch of lazy f.... so lets help em out.

In sketch i found these 2 tricks for fixing exporting of svg

sketch 2.2:
in the terminal paste in:
remove svg crapdefaults write com.bohemiancoding.sketch3 exportCompactSVG -bool yes
add in svg crap defaults write com.bohemiancoding.sketch3 exportCompactSVG -bool no

jwilson3’s picture

In Illustrator:

* Always use: Object > Artboards > Fit to Artwork and ensure the artboard starts at point 0, 0.
* Object > Path > Simplify can provide VERY REAL optimizations for paths with a lot of little "dots" (vertices) near one another.

This also reminds me that we need a section in the guidelines about responsive SVGs.

corbacho’s picture

Issue summary: View changes

Great job jwilson :)
Updating issue summary with some comments and also notice this:
SVG validator demands a DOCTYPE, but it seems not necessary and to be removed in SVG 1.2 according to MDN documentation article (about namespaces)

Crell’s picture

jwilson3: Are there any standard guidelines about responsive SVGs? It's an area that is rather confusing to me, and when I last went googling for leading practices I didn't find much.

jwilson3’s picture

@Crell: I've found and read about a few guidelines for responsive SVGs, but have not tested any myself in cross browsers. Some of them depend on having a wrapper tag around the svg itself -- which frankly sucks.

The cleanest solution I know of is to set width="100%" height="100%" on the <svg> tag. By default, this will scale up the vector graphic to it's container element -- whcih can have drastic effects for a small inline SVG "icon" plopped onto the page (like a feed icon). So then if you don't want the image to scale UP larger than the SVG's own viewbox size) you can set a max-width rule on the style attribute on the svg tag, to the x-width dimension of the viewbox property. Eg:

<svg version="1.1" width="100%" height="100%" viewbox="0 0 16 16" style="max-width: 16px">

The inline style is a bad example because if you're making a small icon responsive, you'll probably want to manipulate the max-width in an external css file, where you can use media queries, etc.

FAAREIA’s picture

Hi, i have been using SVG in my latest proyects, including Drupal proyects. This is my experience:

Responsive SVG

  1. You can scale them up or down without loosing quality.
  2. If you need a 100% width and height svg, you need to specify the preserveAspectRatio attribute in you svg. Check link 01 and link 02

Inline SVG

Method #1 - Inline

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 256 160" preserveAspectRatio="xMinYMid">
  <rect fill="#74ACDF" width="256" height="160"/>
  <rect y="53" fill="#FFFFFF" width="256" height="54"/>
</svg>

Advantages

  1. You can use CSS over the SVG and it's childrens. You can manipulate every piece of it with CSS.
  2. You can use gradients. Crossbrowser.
  3. Accessibility with <title> and <desc>

Disadvantages

  1. If you need to reuse the SVG, it's better to make a file and call it.

Method #2 - IMG

<img src="img/logo.svg" alt="Company name">

Advantages

  1. Reusable SVG file
  2. You can apply CSS to whole icon
  3. Accessibility with <title> and <desc>

Disadvantages

  1. CSS is applied in whole SVG file. You can't change the color, stroke or opacity of a single children tag.

Method #3 - Inline SVG identifiers

<svg><use xlink:href="img/icons.svg#logo"/></svg>

Advantages

  1. Reusable sprite file
  2. Accessibility with <title> and <desc>
  3. Can apply CSS to whole icon

Disadvantages

  1. CSS is applied in whole icon. You can't change the color, stroke or opacity of a single children tag.
  2. You need the script svg4everybody to avoid a blocked SVG because a crossdomain issue
  3. Some browsers do not accept a call for gradients (a second ID call, symbol is first). IE10 & 11 call them, FF don't, Chrome dont remember

SVG Background

Method #1 - CSS background

Advantages

  1. Reusable single file or base64 code

Disadvantages

  1. Can't apply CSS on SVG

Method #2 - Fragment identifier:

Advantages

  1. Reusable sprite file
  2. Accessibility with <title> and <desc>

Disadvantages

  1. Can't apply CSS on icon. Didn't test it but a single background file can't be colored

Crafting the SVG

This is the method i have been using. It works crossbrowser and on mobile. It won't work on browsers which do not support svg.

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <symbol id="bandera-argentina" viewBox="0 0 256 160" preserveAspectRatio="xMinYMid">
    <title>Bandera Argentina</title>
    <rect fill="#74ACDF" width="256" height="160"/>
    <rect y="53" fill="#FFFFFF" width="256" height="54"/>
  </symbol>
  <symbol id="twitter" viewBox="0 0 256 208" preserveAspectRatio="xMinYMid">
    <title>Twitter</title>
    <path d="M256,24.6c-9.4,4.2-19.5,7-30.2,8.3c10.8-6.5,19.2-16.8,23.1-29.1c-10.1,6-21.4,10.4-33.4,12.7C206,6.4,192.3,0,177.2,0c-29,0-52.5,23.5-52.5,52.5c0,4.1,0.5,8.1,1.4,12C82.4,62.3,43.7,41.4,17.8,9.6c-4.5,7.8-7.1,16.8-7.1,26.4c0,18.2,9.3,34.3,23.4,43.7c-8.6-0.3-16.7-2.6-23.8-6.6c0,0.2,0,0.4,0,0.7c0,25.4,18.1,46.7,42.1,51.5c-4.4,1.2-9,1.8-13.8,1.8c-3.4,0-6.7-0.3-9.9-0.9c6.7,20.9,26.1,36,49.1,36.5c-18,14.1-40.6,22.5-65.2,22.5c-4.2,0-8.4-0.2-12.5-0.7C23.2,199.3,50.9,208,80.5,208c96.6,0,149.4-80,149.4-149.4c0-2.3-0.1-4.5-0.2-6.8C240.1,44.4,249,35.2,256,24.6z"/>
  </symbol>
</svg>

Explanation

  • The file contains a main wrapper with: <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">.
  • Every icon is inside a <symbol> tag
  • Every <symbol> must have it's own id and viewBox attribute.
  • You can specify the preserveAspectRatio attribute if it is not default ("xMidYMid meet").
  • You can specify the <title> and <desc> tag for better accesibility

References

corbacho’s picture

Issue summary: View changes

Replying #2426967: Feed icon should be a CSS background image not a image file. where jwilson listed a list of pros to inline SVG.

With the forth-coming HTTP 2.0 the number of HTTP requests is not anymore an issue. So "saving" HTTP requests won't be a problem anymore (as I understood).

Inlining SVG in the templates is only good for advanced manipulation (via css or JS)... but it has a main disadvantage: It can't be cached by the browser

So it has to be a decision taken case-by-case. We can't generalize in the guideline with a single advice.
FAAREIA guidelines style, with pros/cons is quite good idea to have.

rikki_iki’s picture

I've been working on this for a project and made this codepen to work out the kinks in various scaling methods, most of which has already been mentioned above but might be useful to see in action... http://codepen.io/rikki-iki/pen/rVxaNj (consistent across all supported browsers). I did find that inline SVGs in IE required both a height and width set in CSS which can cause problems when the container is smaller than the viewBox or css dimensions (see example 4).

Regarding fallbacks, I haven't tested it yet but the idea of using <picture> sounded really interesting http://sarasoueidan.com/blog/svg-picture/

jwilson3’s picture

Issue tags: +HiDPI
jwilson3’s picture

Another angle to discuss: SVG Animations -- namely "SIML" which currently has fairly poor browser support is being considered on #1974928: Update throbber icon. The thought is that for browsers that don't support the animation, a fallback to a simple color change would be sufficient. I'm certainly in favor of a solution like that, but if anyone objects to the visual regression of these older browsers losing the icon rotation, speak up.

andrewmacpherson’s picture

Issue summary: View changes

Fleshed out the aria-labelledby example, to make it clear that the value is an ID attribute, not the element name.

andrewmacpherson’s picture

Issue summary: View changes

minor edit, add list markup to Problem section.

andrewmacpherson’s picture

Issue summary: View changes

Added the links from #22 to the Resources section, using the actual titles of the articles.

andrewmacpherson’s picture

Do we want to make use of the want to target SVG's <desc> element using the aria-describedby attribute? (For details see the SVG accessibility articles linked in the issue resources section.)

i.e.

<svg aria-labelledby="title" aria-describedby="desc">
  <title id="title">Short label</title>
  <desc id="desc">longer description</desc>
  <!-- remaining SVG code follows... -->
</svg>

We are already making widespread use of aria-describedby in D8 core, notably with Form API output from \Drupal\Core\Form\FormBuilder::doBuildForm().

Tagging accessibility so we can get more views on whether this is useful for our images.

andrewmacpherson’s picture

andrewmacpherson’s picture

Issue tags: +localization

If we do use <title>and <desc> in our SVG, these will need to be localizable.

This might mean we can't have static SVG assets. However, I'm assuming Twig can be used to generate arbitrary XML, not just HTML? So perhaps we could have files like feed-icon.svg.twig.

andrewmacpherson’s picture

Issue summary: View changes

Adding localization of <title>and <desc> to main issue summary.

andrewmacpherson’s picture

From the related issue, comment #50 in #2427213: Replace feed.png with feed.svg, Lewis says

Our existing SVG's don't use these elements and I would suggested avoiding them so we don't run into these localisation issues.

mgifford’s picture

Adding <title>and <desc> would be a great accessibility enhancement.

andrewmacpherson’s picture

@mgifford Some more discussion cropped up about this in #2427213: Replace feed.png with feed.svg. The title and desc elements would need to be translatable. Having them embedded inside the SVG would mean having to generate/cache separate SVG images for each translation. This is quite different from a PNG where we would put image file and fallback text in separate src/alt attributes. The feed icon issue eventually stuck with the span.visually-hidden fallback text, to avoid this issue.

jwilson3’s picture

If the svg were embedded inside a twig template itself, then the translatable text would be a non-issue. I'm not opposed to trying this, but it also needs more discussion, for example there are people that are talking about adding a single SVG at the top of the dom (or could be after the footer) that is essentially an svg sprite of all the svg images used on the page and then referencing them using the #id svg sprite method. To do that in core would be a pretty significant undertaking, requiring some global thing keeping track of each svg, adding it to the sprite with an id, and adding in the placeholder svgs in its place. OOS for this issue, but certainly using a twig template that produces inline svg could be an idea we could entertain as a first step towards better a11y.

joelpittet’s picture

Category: Task » Plan

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

jwilson3’s picture

Issue summary: View changes

Added a note to the issue summary from https://una.im/a11y-for-the-masses/ about watching out for text in SVGs.

It suggests that you should not put raw text strings into SVG because Google Translate and other providers cannot translate the text appropriately, and also brings up the great point that if we start allowing text in the svg for things like <title> and <desc> then people will be tempted to put visible text in there as well, and transliterated visible text in SVG might completely break the svg drawing when you take viewport size restrictions into account (ie, foreign language text in more verbose languages might get cut off).

I think it will be hard to get Localization right, and still maintain Accessibility.

andypost’s picture

Version: 8.1.x-dev » 8.3.x-dev

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

yoroy’s picture

I wonder how we can best balance pragmatism (so that we can move forward and make nice changes) and standardisation (making sure we're doing the right thing).

#2775725: Update throbber icon in Seven theme is getting somewhat stalled on a decision about how to handle SVGs. Maybe people who are interested in this can have a look and chime on that specific case? Thanks!