The type-safe CSS styling with elm-css

Key takeaways:

  1. Elm's static typing catches errors at compile time, reducing debugging time and increasing code reliability.

  2. Each HTML element receives a single class, ensuring predictable styling and behavior.

  3. Prevents common issues such as type mismatches and helps maintain consistency in units (em, px, %).

  4. Allows seamless integration of dependencies, including custom-built functions, promoting code reuse.

  5. Changes to styles are reflected throughout the project, making refactoring more manageable.

  6. Elm's compiler provides clear error messages, aiding developers in identifying and correcting issues efficiently.

The elm-css package

Elm is a functional programming language that uses pure functions and immutable data to render web pages. Some salient features of Elm include no runtime error, a user-friendly debugger that gives easily understandable error messages, making debugging easier, and quicker rendering of HTML templates. It also makes writing CSS safer than original CSS for the following reasons:

  • Elm is statically typed, and all variable and function names are checked at compile-time. Any typos in CSS class names and properties are caught at compile-time. We don’t have to constantly refer to the browser developer tools to debug CSS-related errors.

  • Elm supports strong types, ensuring no type mismatch. Type mismatches can happen when we confuse units like em, px, percentage, etc., or wrongly style elements.

  • All dependencies, even our custom-built functions, can be imported into other files. These files may contain other styled elements.

  • The elm-css package allows deterministic resolution, which means that any HTML element receives one class. Common styles are used within an Elm function to add multiple styles to one element.

  • With elm-css, we can’t mix classes from two different style sheets, making the code isolated and maintainable.

  • Any style changes are consistent throughout our project, allowing reliable code refactoring.

Getting started with elm-css

First of all, we need to create an Elm project. Elm requires Node.js to be pre-installed. For convenience, both Node.js and Elm have been installed.

To get started with elm-css, paste the following command in the terminal to see what versions of Node.js and Elm are installed.

node --version && elm --version

Now, we'll create a separate folder and change our current working directory to that project directory using the following command:

mkdir /usercode/elm_project && cd /usercode/elm_project

Initialize the Elm project and install the elm-css package. Paste each command one after the other. Don’t forget to type y/Y against each prompt shown in all terminals that follow from this point onwards.

elm init
elm install rtfeldman/elm-css

Create a Main.elm file inside the src folder of the project. This is the entry point of any Elm application and where we’ll write our CSS. Use the following command to create the Main.elm file. The ls command verifies if Main.elm has been successfully created.

cd src/
touch Main.elm && ls

Paste the above commands in the following terminal:

Terminal 1
Terminal
Loading...

Code implementation

The following code has two errors on line 33 and 43, which are commented with --error and highlighted. See how Elm’s debugger shows a compile-time error when clicking the ‘‘Run’’ button.

The compiler will point out the error on line 43. See how Elm’s compiler suggests possible properties in place of the erroneous one entered on line 43. Change backgroundCol to backgroundColor and rerun the widget.

We get another error on line 33. In place of padding2, write padding3 and rerun the widget. As we can see, all errors were identified and removed before the CSS was even rendered on the browser. Note how user-friendly the compiler is, making the debugging process simpler. Expect Success! Compiled 1 module message, together with Main ───> index.html. The latter indicates that an index.html file has been automatically generated from our Elm code.

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
An erroneous elm-css example

Corrected code

To understand how the above code is working, we’ll understand the entire structure and syntax of the Main.elm file given in the src folder.

module Main exposing (main)
import Browser
import Css exposing (..)
import Html.Styled exposing (..)
import Html.Styled.Attributes exposing ( css, src)
update : Msg -> Model -> Model
update msg model =
model
type Msg
= ReloadPage | CreateDiv | PerformAction
type alias Model =
()
initialModel : Model
initialModel =
()
main : Program () Model Msg
main =
Browser.sandbox{ view = view >> toUnstyled, update = update, init = initialModel}
educative_banner : Html msg
educative_banner =
img
[ src "educative_logo.png"
, css
[ margin auto
, padding3 (pct 20) (pct 20) (pct 20)
, width (pct 50)
, height (pct 30)
, position relative
]
]
[]
view : Model -> Html Msg
view model =
div [css [displayFlex , justifyContent center,alignItems center, margin zero,width (pct 100), height (pct 100),overflow hidden, backgroundColor (hex "#b8d4de") ]]
[ educative_banner ]
A working elm-css example

Code explanation

  • Lines 1–5: In these lines, line 1 exposes the Main module’s main function, which means the main function can now be used outside in other modules. This method is used to export functions in Elm. Line 2 imports the browser module, which will create a sandbox environment for creating web applications in Elm. We also import the Css, Html.Styled , and Html.Styled.Attributes packages. exposing (..) means we will import the entire file with all its functionality, not a particular function or property. From Html.Styled.Attributes we import the css and src attributes.

  • Lines 7–9: These lines define an update function that takes Msg and Model as arguments and returns the same Model. The Model stores the current state of our application.

  • Lines 11–12: We define a custom type called Msg, which will receive all the messages sent from the browser to the application. The browser can send different messages: ReloadPage, CreateDiv, and PerformAction. We can make our update function perform different tasks for each message sent from the browser. The update function contains our entire business logic.

  • Lines 14–15: These line declares a type alias Model. Type aliases are like nicknames for data and save us the hassle of rewriting large records again and again in Elm. In this case, it’s an alias for the unit value ().

  • Lines 17–19: These lines define the initialModel function, which returns () as the initial value for the Model.

  • Lines 21–23: These lines define the main function of the application. The Browser.sandbox function creates our application, which interacts with Elm’s runtime system to render HTML. It specifies what our view, update, and init functions will be.

  • Lines 25– 37: These lines define the function educative_banner, which returns the styled img tag. The src "educative_logo.png" function specifies the path of the image and is the Elm equivalent of src tag in HTML. This shows one way to style HTML elements using elm-css. Note any HTML tags are just normal functions in Elm. Any CSS property can be rewritten in elm-css as property_name or property_value. For example, width : 50% in CSS can be written as width : (pct 50) using elm-css. The corresponding CSS for all properties is given below:

    • Line 30: margin : auto

    • Line 31: padding : 20% 20% 20%

    • Line 32: width : 50%

    • Line 33: height : 30%

    • Line 30: position : relative

  • Lines 39 –42: These lines define the view function, which takes Model as input and returns Html to be rendered in the browser.

Conclusion

The elm-css package significantly enhances the development experience in Elm by providing type-safe CSS styling. It leverages Elm's static typing system to catch errors at compile time, ensuring that developers can write CSS without the common pitfalls associated with traditional stylesheets. By preventing type mismatches and enforcing consistent styling across an application, elm-css promotes maintainability and reduces the likelihood of runtime errors. Furthermore, the isolated nature of styles prevents conflicts between different stylesheets, making it easier to manage large projects. As web development continues to evolve, adopting tools like elm-css can lead to more robust and reliable applications.

Frequently asked questions

Haven’t found what you were looking for? Contact Us


What are the different types of CSS styling?

CSS styling can be categorized into three types:

  • Inline CSS, where styles are applied directly within an HTML element using the style attribute.
  • Internal CSS, where styles are defined within a <style> tag in the document’s <head> section.
  • External CSS, where styles are written in a separate .css file and linked to the HTML document using the <link> tag.

Each method serves specific use cases, allowing for flexibility in how styles are applied and organized.


What is CSS style rules?

CSS style rules define the appearance and layout of HTML elements on a web page. Each rule consists of a selector that targets specific elements and a declaration block containing one or more declarations. Each declaration includes a property and a value that specify the styling to apply. CSS style rules enable efficient control over the visual presentation of web content.


Free Resources

Copyright ©2025 Educative, Inc. All rights reserved