Changing style globally instead of recreating the whole view

(Disclaimer: I’ve never built UIs nor worked on frontend apps and I’m trying to fill these holes because backend is fun and all but it’s a bit more interesting when people can use your programs.)

I wanted to do some elm training by creating a page to display 1D cellular automata.

My code can be found here and the result can be found here

Line 28 (no link because new users can only put 2 links), the field is prev_arrays and on line 339 (bis), I render all the previous arrays. Why? Because if I change the colours or resize my window I need the previous lines to be consistent with the chosen colour or the new size.

Previously, this field was called rendered_arrays and I would store the created html so I wouldn’t have to render all the previous arrays.

I tried giving my squares the alive or dead class and handling the background-color for both classes from a CSS external file but I can’t change this file from elm so it was not possible to change the colours dynamically. Same thing with resizing the window, if I just changed the square_size value, the lines generated after the resizing would be drawn with the changed value but not the ones generated before.

I’m not really happy with my current solution.

If anyone here has the patience and the will to look at my code and tell me what can be improved and how, I’d be really glad.

You can set css custom properties using elm with a style node, and then use them in your alive and dead classes in an external css file.

See this Ellie for a basic example: https://ellie-app.com/q4dQWydj8Qka1

This will probably not perform that well however, since you are rendering so many dom nodes. If you care about performance check out HTML canvas.

Thanks for the answer! I’ll take a look immediately :slight_smile:

@mattiasdrp For another example of using CSS custom properties you can check out line 186 of my Random Quote Machine, which changes this custom property from Elm.

I implemented a helper function called globalCustomProperties to set CSS custom properties on :root.

globalCustomProperties : List ( String, String ) -> H.Html msg
globalCustomProperties =
    List.map (\( name, value ) -> "--" ++ name ++ ": " ++ value ++ ";")
        >> String.join " "
        >> (\s -> H.node "style" [] [ H.text <| ":root { " ++ s ++ " }" ])

Using that function, @panda’s example becomes

div []
  [ globalCustomProperties [ ( "background-hue", String.fromInt model.hue ) ]
  , ...
  ]

Learn more here: Change CSS Properties from Elm with CSS Custom Properties.

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