Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mutal reaction between inlineStyles and convertStyleToAttrs #932

Closed
fatalmind opened this issue Mar 27, 2018 · 3 comments
Closed

Mutal reaction between inlineStyles and convertStyleToAttrs #932

fatalmind opened this issue Mar 27, 2018 · 3 comments

Comments

@fatalmind
Copy link

The appearance of the following SVG is broken (in some browsers) by the inlineStyles plugin in conjuction with the convertStylesToAttrs plugin (both enabled by default).

<svg id="test" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
    <style>
        .c1.c2 {fill: #FFF;}
        .c2    {fill: #000;}
    </style>
    <rect width="100" height="100" class="c2"/>
    <rect width="100" height="100" class="c1 c2"/>
</svg>

First, the inlineStyles plugin does it's work, which is fine:

    <style>
        .c2{fill: #000}
    </style>
    <rect width="100" height="100" class="c2"/>
    <rect width="100" height="100" class="c2" style="fill:#FFF"/>

Even though the '.c2' rule still applies to the second rect, the style attribute takes precedence over the style element.

However, then the convertStyleToAttrs comes and turns the style attribute into a fill attribute (or the like).

    <style>
        .c2{fill: #000}
    </style>
    <rect width="100" height="100" class="c2"/>
    <rect width="100" height="100" class="c2" fill="#FFF"/>

The problem is that the fill attribute has a very low precedence (as opposed to style, which has the highest possible precedence).

This is at least what I understand from the spec: https://www.w3.org/TR/CSS2/cascade.html#preshint

It seems that not all browsers honour this — e.g. Firefox applies the fill="#FFF" although the '.c2' selector still matches — the problem is thus not visible. Other browsers (Chrome and Safari at least) apply the rule of the '.c2' selector so that the optimized image is visually different from the original.

If my understanding is right, the solution is to disable the convertStylesToAttrs plugin per default because it turns high precedence style attributes into low precedence fill (and the like) attributes. Although I've hit this issue because inlineStyles moves rules to the style attribute, the problem should also strike in case the original SVG has style attributes.

A more advanced solution would require convertStylesToAttrs to check whether the element matches any CSS selector that defines the same property and, if so, refrains from transforming the style attribute to the respective SVG attribute.

@strarsis
Copy link
Contributor

strarsis commented May 18, 2019

@fatalmind: I always assumed that there is a precedence in this order (least specific to most specific): <style>; style="..."; style="... !important" attribute, hence the attribute value should always apply after everything else.

Disabling the onlyMatchedOnce option may be helpful because this would inline all styles that match.
There can be still an issue with non-inlineable styles though.

@TrySound
Copy link
Member

convertStyleToAttrs will be disabled by default in the next release
#1365

@TrySound
Copy link
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants