Background:
At Humio we use custom css properties (aka css variables) to support styling and customisation of CSS components that we share across our app and sites. We have found it to be extremely useful do most (styling related calculations directly in CSS). We would like to use it a lot more than we are. We also love Elm and have one of the largest Elm code bases in the world.
Problem:
The problem is that Elm will not allow using custom properties in the style
attribute e.g. this will not work:
button [style [("--light-direction", lightDir), ("--hue", hue)]] [ ... ]
The reason for this is that style
is implemented to apply styles using javascript styles[key]
where key
is the style property you would like to set. This unfortunately does not support custom variables. If it was implemented using setProperty
instead it would work just fine, like suggested in:
elm-lang/virtual-dom/pull/95 (by @ilias)
Which has since been closed by @evancz, due to lack of motivation for making the change.
Motivation is what I am trying to provide here as well as hear what others think, since it does not
look to be changing with 0.19 either.
In @evancz recent blog post about how to deal with Native being removed in 0.19, he suggested that Custom HTML Elements (webcomponents) could be a replacement in some cases. At Humio we have found webcomponents to be very useful when integrating with larger js libs like codemirror and highcharts.
One of the suggested ways of making your webcomponents customizable is using custom css properties, which work very well with the shadow DOM (which many webcomponents use). You can read about it here. Isn’t it a shame that you cannot do something like:
Html.node "codemirror" [style ("--theme-color", model.color)] []
The sentiment that I have seen several times while reading discussions about this is “You can just do those calculations in Elm”, and set styles there. The thing is, I really don’t want to mix
my application logic and navigation etc with the styling code. It is very nice when defining complex css components to have everything in a single place and it be only CSS.
But that is just my personal preference. When it comes to Shadow DOM on the other hand, there is actually no other way to style these components since their CSS context is not the same as the containing pages.
Workaround
Until (I really hope it is “until” and not forever) Elm supports custom properties we have had to use a trick that I would like to share. It has been posted several other places and it is in no way something I can take credit for inventing You can create a “temporary class” in an inline style element and apply your custom properties there. It is not pretty and your CSP rules may restrict you from doing it.
div [] [
style [] [text ".properties--" ++ id ++ " { --theme-color: " ++ toHex color ++"; } " ]
Html.node "codemirror" [class (".properties--" ++ id)] [ ... ]
]
What do you think?