Should Elm not support custom css properties in style? I think so

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 :slight_smile: 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?

5 Likes

I don’t have any opinions on whether Elm should switch to using setProperty or not.
However, I can offer you another workaround that seems a bit nicer to your current workaround.
Here’s an ellie that shows how it works.

2 Likes

Thanks @zinggi we are doing something similar, but your version is nicer :smile:

1 Like

I recently learned that you can use custom properties for animation effects too:

David K. :musical_keyboard: (@DavidKPiano) Tweeted:
:atom_symbol:️ Did you know that you can use CSS variables in @reactjs? Add them to the style={{…}} attribute for dynamic, customizable effects such as staggered animations: https://t.co/OdKLlEpOQD https://twitter.com/DavidKPiano/status/984430690870677504?s=17

It is such a cool and simple way to do things like staggered animations!

It would be great if we could use this. elm-html being close in behavior to HTML seems like a good idea to avoid cognitive dissonance when working with it.

It is great that there is a workaround too, thanks for sharing it.

3 Likes

I tried to make it happen: https://github.com/elm-lang/virtual-dom/pull/44

Evan wasn’t convinced that it makes things nicer, even though that (IMO) is the wrong line of thinking - it’s part of the CSS spec and should be supported on that merit alone.

And of course, it makes things much nicer, as evidenced by the response to the tweet and other discussions:


3 Likes

Thanks for the context!

@davidkpiano mentioned in the pull request theming CSS. If you are working with plain CSS (and not with elm-css) having elm variables doesn’t help, which seems to be a comment why custom properties don’t seem useful.

Custom properties are the way to make CSS stylesheets interactive in a performant way. Having them allows you to (among other things):

  • Theme CSS from Elm (--spacing: 1.5em or --main-color: red)
  • Vary CSS animations and transitions (duration, delay, and any other properties) from Elm
    • With this, we can define in CSS a generic animation like fade-in, and then from Elm I could control the duration or delay for each DOM we apply it to without having to duplicate the animation in CSS

Here is an article about how custom properties can be used to manipulate all kinds of aspects of CSS.

If anyone has thoughts on what exactly is needed to show the usefulness of them, please comment!

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.