Html.Attributes.style does not support setting custom properties. For e.g. the following won't work:
style "--alert-text-color" "#123456"attribute "style" "--alert-text-color: #123456"re: Passing variables to CSS, Setting the gutter
However, it doesn't work well when other styles need to be set. For e.g. the following doesn't work:
H.div
[ style "background-color" "black"
, attribute "style" "--alert-text-color: #123456"
]re: It doesn't stack
The use of attribute "style" overwrites the previous styles value set by style. Order is important
when using this solution to ensure you don't overwrite previously set styles. So the following works:
H.div
[ attribute "style" "--alert-text-color: #123456"
, style "background-color" "black"
]I personally don't see it as a problem since the only time I'd want to be using the HTML style attribute
in my Elm code is when I want to use custom properties. For other uses of the HTML style attribute I think
CSS classes in an external stylesheet are better suited.
If you really need to set both then the following snippet provides a workaround:
styles : List (String, String) -> H.Attribute msg
styles =
HA.attribute "style"
<< String.join "; "
<< List.map (\(name, value) -> name ++ ": " ++ value)Now you'd be able to set custom properties along with other properties in any order you'd like:
styles
[ ( "border-color", "green" )
, ( "--circle-x", String.fromInt position.x ++ "px" )
, ( "--circle-y", String.fromInt position.y ++ "px" )
, ( "border-width", "3px" )
, ( "--circle-diameter", String.fromInt diameter ++ "px" )
, ( "background-color", "pink" )
]If you only need to set a bunch of custom properties then we can make it so that you don't have to type all those "--" at the beginning.
customProperties : List (String, String) -> H.Attribute msg
customProperties =
HA.attribute "style"
<< String.join "; "
<< List.map (\(name, value) -> "--" ++ name ++ ": " ++ value)For e.g.
customProperties
[ ( "circle-x", String.fromInt position.x ++ "px" )
, ( "circle-y", String.fromInt position.y ++ "px" )
, ( "circle-diameter", String.fromInt diameter ++ "px" )
]There is a hacky solution I figured out after I stumbled upon the use of an HTML <style> element in
elm-css.
H.div []
[ H.node "style" []
[ H.text ":root { --theme-background-color: #3241AF; }" ]
]
For e.g. I used this approach in my elm-2048 clone to control the tile movement duration from Elm.
The problem with this solution is that it uses an HTML <style> element in the <body> element. According
to the HTML Standard the
<style> element should only be used
In a
noscriptelement that is a child of aheadelement.
However, browsers may not really care according to Jukka. 😕
Elm doesn't provide support for CSS custom properties out the box. However, there are a few acceptable workarounds that I've mentioned that you can use for now. I'd be interested to learn about other scenarios where these workarounds won't work.
Examples of scenarios I haven't tried:
- CSS frameworks that can be configured with CSS custom properties
- Web components that can be configured with CSS custom properties
- Support for CSS custom properties
- Bug: CSS Custom Properties can't be set
- CSS Custom Properties
- Html.Attributes.style
- Html.Attributes.attribute
- A Complete Guide to Custom Properties
- The style element
- Developer-friendly alternative to
Html.Attribute, which can handle conditional attributes, CSS custom properties, and more