zathras / jovial_svg

Flutter library for robust, efficient rendering of SVG static images
BSD 3-Clause "New" or "Revised" License
107 stars 20 forks source link

Stylesheets should take precedence over presentation attributes #116

Open zathras opened 1 month ago

zathras commented 1 month ago

It looks like when CSS was grafted onto the SVG spec, they set surprising precedence rules. It looks like the priority of styling attributes is:

  1. Styles set directly on an SVG node with the "style" attribute
  2. Styles set via a stylesheet
  3. Styles set directly on an SVG node with a presentation attribute

jovial_svg treats #1 and #3 as the same.

Changing this would be at least a semi-major version number change. It also would require an expansion of the DOM API, in order to differentiate between #1 and #3, above. That change would probably involve deprecation, and be non-trivial.

This could be considered a bug, but I'm calling it an enhancement, because the support for stylesheets was never 100% complete. With that said, this enhancement may be worth doing.

Here's the relevant spec, copied from https://github.com/zathras/jovial_svg/discussions/112 . An SVG asset that shows the difference can be found there, too.

From https://www.w3.org/TR/2003/REC-SVG11-20030114/styling.html :

6.4 Specifying properties using the presentation attributes ...

For user agents that support CSS, the presentation attributes must be translated to corresponding CSS style rules according to rules described in section 6.4.4 of the CSS2 specification, Precedence of non-CSS presentational hints, with the additional clarification that the presentation attributes are conceptually inserted into a new author style sheet which is the first in the author style sheet collection. The presentation attributes thus will participate in the CSS2 cascade as if they were replaced by corresponding CSS style rules placed at the start of the author style sheet with a specificity of zero. In general, this means that the presentation attributes have lower priority than other CSS style rules specified in author style sheets or style attributes.

zathras commented 1 month ago

Thinking about this a bit, I think it's fair to say that the intent of the SVG spec authors here was that everyone should use CSS or the style attribute, and that directly specifying presentation attributes was a legacy. This issue only comes up if you mix the two mechanisms. If the SVG's author specifies node attributes using the "style=" attribute on the node, as the SVG authors presumably intended, all is well.

Also, as noted in #112, there are readily available tools that clean up SVGs so as to avoid this sort of thing.

zathras commented 1 month ago

Digging a little deeper into the CSS specification, the precedence rules are crazy complicated. Consider, for example, "specificity": https://www.w3.org/TR/2008/REC-CSS2-20080411/cascade.html#specificity.

jimmyff commented 1 month ago

Cat SVG source file from #112 discussion:

cat.svg ```xml ```
zathras commented 4 weeks ago

The only use case identified so far for these very complicated precedence rules is for scripting. If you're scripting (using the DOM API), it's easy enough to null out the offending presentation attributes, so this missing feature of jovial_svg has an easy workaround in this case.

Of course, there might be cases where valid static SVG files rely on these precedence rules, and where pre-processing is not practical. But full compliance with all of SVG and CSS is an explicit non-goal of jovial_svg. I've updated the README to better spell out what areas of stylesheets are (intentionally) not implemented. With that, I'll mark this as "won't fix", but leave it open in case someone else runs into it. If there's a compelling use-case with no easy workaround to implement a little more of CSS, that could be considered in the future.