elm-community / typed-svg

Typed SVG library written for Elm

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Non-standard use of rgba(.., .., .., ..)

rupertlssmith opened this issue · comments

Setting the style on an element like this:

[ fillOpacity <| Opacity 1.0
]

Results in SVG like this:

fill="rgba(255, 255, 255, 1)"

Which renders correctly in browsers as "rgba(..)" is valid in CSS. However, the SVG 1.0 standard does not allow rgba, and this should be specified as

fill="#FFFFFF"

The alpha part should be set independently using the 'fill-opacity' parameter.

This problem is only seen if the rendered SVG is exported and loaded into an SVG tool that does not support CSS, such as Inkscape.

This also afffects the 'stroke' attribute which has a separate 'stroke-opacity' attribute for the alpha channel. Corrected in the commit above.

It is a little hard to know what to do alpha values from colors in general. If one is set, should adding a 'stroke', 'fill' automatically set the opacity?

Also the 'color' attribute does not have a corresponding 'opacity' attribute. In browsers setting a color with alpha will work just fine, but in SVG 1.1 it should really only set the color. It would seem correct if adhering to 1.1 to discard the alpha value from an Elm Color in that case.

It would seem more friendly to make a better API that lets Elm Color values be used with alpha, and to automatically set the correct opacity somehow.

I decided to leave 'color' alone for now, until a better design can be thought of.

Fixed in 2.0.1

Ahhh. Okay, now I see.

Anyway, as I mentioned, this is a breaking change. Our entire app blew up, as suddenly everything no longer has proper transparency.

To be backward compatible, you could write some logic to check if you are being passed an RGBA from Elm. If so, add the opacity as an additional field fill-opacity and set it to the opacity.

Not sure what to do now... maybe I'll make a pull request to fix this...

As discussed in issue #19, the patch has been removed as it was a breaking change.

Options for fixing this are:

  1. "Write some logic to check if you are being passed an RGBA from Elm, if so, add the opacity as an additional field fill-opacity"

Each SVG attribute in typed-svg maps onto one VirtualDom.Property, so creating 2 attributes from 1 probably doesn't work. Unless there is some kind of List Property -> Property that lets you wrap a list as just one property, like Cmd.batch does for Cmds.

This would still be possible but it means not mapping Attribute 1:1 onto VirtualDom.Property but introducing an intermediate layer. This would cost a little in terms of performance.

  1. Could add a separate attribute that does maintain SVG 1.1 compatability for fill and stroke, like this:

default:

fill : Fill -> Attribute

when you want to ensure compatability:

fillCompat : Fill -> Attribute

  1. Could do it dynamically depending on whether there is an alpha value < 1:

This will output 'rgba(123, 232, 45, 0.9)':

fill Color.rgba (123, 232, 45, 0.9)

These would output '#7be82d':

fill Color.rgba (123, 232, 45, 1.0)
fill Color.rgb (123, 232, 45)

This would be documented in the comments warning users that non-compliant SVG may be output when setting the alpha channel and directing them to the fill-opacity attribute as an alternative.

===

Other suggestions welcome or say which of the above you think works best.

  1. Add more options to the Fill type (and introduce a similar Stroke type):
type Fill
    = Fill Color
    | FillNone

Changes to:

type Fill
    = Fill Color
    | FillNoAlpha Color
    | FillNone

other suitable names might be FillCompat, or FillColorOnly?

Should also look at what is going to happen to the Color module in Elm 0.19, it changes in some way for that I believe.

Personally, I'd probably go with option #3, as it seems like most use-cases for this library would be geared for SVG browser compatibility, e.g. SVG fill rgba works on IE 11, Chrome, FF, Safari, Edge, which is pretty much everything.

But maybe I'm wrong!

I'm good with option 3 too.