elm-css

Thomas Brisbout

Freelance JS developer

 @tbrisbout

Elm Paris Meetup / 2016-09-20

Why ?

Main issues

  • Specifity War
  • Module Organization
  • Scoping
  • Maintenance

Tentatives

  • Preprocessors
  • Module Organization (CSS modules)
  • Scoping: BEM ...

CSS in Elm ?

Two possibilities

  • Inline Styles
  • External Stylesheet in Custom HTML

Inline Styles

Inline Style Old Way

import Html exposing (div)
import Css exposing (..)

viewStyles =
    styles
        [ ("height", "100%")
        , ("margin", "0")
        , ("text-align", "center")
        , ("font-family", "Montserrat, Arial")
        , ("background-color", "#ffggff")
        ]

view =
    div [ viewStyles ] []

Inline Style Old Way 2

import Html exposing (div)
import Css exposing (..)

(=>) = (,)

viewStyles =
    styles
        [ "height" => "100%"
        , "margin" => "0"
        , "text-align" => "center"
        , "font-family" => "Montserrat, Arial"
        , "background-color" => "#ffggff"
        ]

view =
    div [ viewStyles ] []

Inline Style New Way

import Html exposing (div)
import Css exposing (..)

viewStyles =
    styles
        [ height (pc 100)
        , margin (px 0)
        , textAlign center
        , fontFamilies [ "Montserrat", "Arial" ]
        , backgroundColor (hex "#ffggff")
        ]

view =
    div [ viewStyles ] []

what ?

CSS Preprocessor in Elm

Implementation of most CSS properties as functions and values as types

Inline Style New Way

import Html exposing (style)
import Css exposing (..)

styles : List Css.Mixin -> Html.Attribute Msg
styles =
    Css.asPairs >> style

CSS Property functions

things to know

  • A few missing properties
    • list-style-type
    • box-shadow
  • A few differences
    • margin, margin2, margin4...
    • fontFamilies
  • Colors, Fonts, ..., are typed

External Styles

Load Stylesheet in Reactor

loadStylesheet : String -> Html Msg
loadStylesheet url =
    let
        tag =
            "link"

        attrs =
            [ attribute "rel" "stylesheet"
            , attribute "property" "stylesheet"
            , attribute "href" url
            ]

        children =
            []
    in
        node tag attrs children


fontAwesome : Html Msg
fontAwesome =
    loadStylesheet "https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css"


bootstrap : Html Msg
bootstrap =
    loadStylesheet "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"


externalStylesheets : List (Html Msg)
externalStylesheets =
    [ fontAwesome, bootstrap ]

External Style Example

css =
    (stylesheet << namespace homepageNamespace.name)
        [ header
            [ backgroundColor (rgb 90 90 90)
            , boxSizing borderBox
            , padding (px -80)
            ]
        , nav
            [ display inlineBlock
            , paddingBottom (px 12)
            ]
        , (.) NavLink
            , color (rgb 255 255 255)
            ]
        , (#) ReactiveLogo
            [ display inlineBlock
            , marginLeft (px 150)
            , verticalAlign middle
            ]
        ]

Port Module

port module Stylesheets exposing (..)

import Css.File exposing (..)
import MyCss
import Html exposing (div)
import Html.App as Html

port files : CssFileStructure -> Cmd msg

cssFiles : CssFileStructure
cssFiles =
    toFileStructure 
      [ ( "styles.css", compile MyCss.css ) ]

main =
    Html.program
        { init = ( (), files cssFiles )
        , view = \_ -> (div [] [])
        , update = \_ _ -> ( (), Cmd.none )
        , subscriptions = \_ -> Sub.none
        }

Organisation

SharedStyles.elm

module SharedStyles exposing (..)

import Html.CssHelpers exposing (withNamespace)


type CssClasses
  = NavLink


type CssIds
  = ReactiveLogo
  | BuyTickets


homepageNamespace =
  withNamespace "homepage"

ColorScheme Module

module ColorScheme exposing (..)

headerBg : Color
headerBg =
    hex "#3ca0b8"

headerColor : Color
headerColor =
    hex "#ffffff"

talkTitle : Color
talkTitle =
    hex "#e33e57"

eventTitle : Color
eventTitle =
    hex "#7fd13b"

Conclusion

Interesting Approach

Prod Ready ?

References

Questions ?

elm-css

By Thomas BRISBOUT

elm-css

  • 1,401