Color Coding with Elm

Tessa Kelly

NoRedInk

slides.com/tessak/color-coding-with-elm/live

tesk9/accessible-html

Accessible by law!

Generating colors with JS and CSS Custom Properties

 

at NordicJs 2018

A Colorful History

On Colors

TODO: image here

Opticks

A treatise of the reflections, refractions, inflections and colours of light

3-color printing

Additive Colors

Subtractive Colors

(Paint)

(Colored flashlights)

Modeling color

Albert Munsell

What did Munsell realize about human perception of color?

SharkD [CC BY-SA 3.0 (https://creativecommons.org/licenses/by-sa/3.0), from Wikimedia Commons

Using color systems

Web Color Modeling

RGB cube

(1,0,0)
(0,1,0)
(0,0,1)
(255,0,0)
(0,255,0)
(0,0,255)
  "#00F"
"#0F0"             
      "#F00"

Hex cube

A Hex on Hex

linear-gradient(
    #F00, #FF7F00, #FF0, #0F0, #00F, #8B00FF
)

Working with Colors

-- Is a red by another name just as red?
rgb (255, 0, 0) == hex "#F00" 


-- Does red + green = yellow?
add (hex "#F00") (rgb (0, 255, 0)) 


-- ... Does red always look red?

Color Placement

Color Wheel

RGB & HSL

HSL Color Space

By HSL_color_solid_cylinder.png: SharkDderivative work: SharkD  Talk - HSL_color_solid_cylinder.png, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=9801661

A Rainbow Gradient

Color Donut

Shades, Tints, and Tones

What we've discussed so far:

  • Historical color modeling
  • Color modeling on the web
    • RGB
    • Hex
    • HSL
  • Color perception & color delivery

Colorful Elm Packages

elm-lang/core

-- Color library API

{- arguments should be integers in [0, 255] -}
rgb : Int -> Int -> Int -> Color 

rgba : Int -> Int -> Int -> Float -> Color

{- the hue is in radians and the saturation and lightness in [0,1] -}
hsl : Float -> Float -> Float -> Color

hsla : Float -> Float -> Float -> Float -> Color

{- Produces a gray -- 0 is white, 1 is black -}
greyscale : Float -> Color 

complement : Color -> Color
-- Color library API


toRgb :
    Color
    -> { red : Int
       , green : Int
       , blue : Int
       , alpha : Float
       }

toHsl :
    Color
    -> { hue : Float
       , saturation : Float
       , lightness : Float
       , alpha : Float
       }
-- Color library API


linear :
    ( Float, Float )
    -> ( Float, Float )
    -> List ( Float, Color )
    -> Gradient


radial :
    ( Float, Float )
    -> Float
    -> ( Float, Float )
    -> Float
    -> List ( Float, Color )
    -> Gradient

avh4/elm-color

rgb255 : Int -> Int -> Int -> Color

fromRgba :
    { red : Float
    , green : Float
    , blue : Float
    , alpha : Float
    }
    -> Color

fromHsla :
    { hue : Float
    , saturation : Float
    , lightness : Float
    , alpha : Float
    }
    -> Color
{- Produced string matches: rgba(rr.rr%,gg.gg%,bb.bb%,a.aaa) -}
toCssString : Color -> String

rtfeldman/elm-css

-- Internal modeling of colors

type alias Color =
    ColorValue { red : Int, green : Int, blue : Int, alpha : Float }
-- Css library API

rgb : Int -> Int -> Int -> Color

rgba : Int -> Int -> Int -> Float -> Color

{- saturation and lightness should be between 0 and 1 -}
hsl : Float -> Float -> Float -> Color 

hsla : Float -> Float -> Float -> Float -> Color

hex : String -> Color

mdgriffith/elm-ui

-- Internal modeling of Color

type Color = Rgba Float Float Float Float
-- External elm-ui API

rgba : Float -> Float -> Float -> Float -> Color
rgb  : Float -> Float -> Float -> Color

rgba    : Float -> Float -> Float -> Float -> Color
rgba255 : Int -> Int -> Int -> Float -> Color

fromRgb    : { red : Float, green : Float, blue : Float, alpha : Float}
             -> Color

fromRgb255 : { red : Int, green : Int, blue : Int, alpha : Float } 
             -> Color
-- External elm-ui API

toRgb :
    Color
    -> { red : Float
       , green : Float
       , blue : Float
       , alpha : Float
       }
-- avh4/elm-color

div [ style "color" (Color.toCssString (Color.rgb 1 0 0)) ] 
    [ text "Hello, world!" ]
-- rtfeldman/elm-css

div [ css [ Css.color (Css.rgb 255 0 0 ) ] ] [ text "Hello, world!" ]
-- mdgriffith/elm-ui

Element.el [ Font.color (Element.rgb255 255 0 0) ] 
    (Element.text "Howdy!")

What more is there?

  • Contrast
  • Blending
  • Adjustments
  • Generation
  • Palettes

Luminance and Contrast

Luminance

luminance : (Float, Float, Float) -> Float
luminance ( r, g, b ) =
    let
        red = fromSRGB (r / 255)
        green = fromSRGB (g / 255) 
        blue = fromSRGB (b / 255) 

        fromSRGB srgb =
            if srgb <= 0.03928 then
                srgb / 12.92

            else
                ((srgb + 0.055) / 1.055) ^ 2.4
    in
    (0.2126 * red) + (0.7152 * green) + (0.0722 * blue)

Contrast

contrast : Color -> Color -> Float
contrast color1 color2 =
    let
        luminance1 = Color.luminance color1

        luminance2 = Color.luminance color2
    in
    if luminance1 > luminance2 then
        (luminance1 + 0.05) / (luminance2 + 0.05)

    else
        (luminance2 + 0.05) / (luminance1 + 0.05)

Accessibility

-- noahzgordon/elm-color-extra

contrastRatio : Color -> Color -> Float

luminance : Color -> Float


-- tesk9/palette

contrast : Color -> Color -> Float

luminance : Color -> Float
-- noahzgordon/elm-color-extra

maximumContrast : Color -> List Color -> Maybe Color




-- tesk9/palette

sufficientContrast : WCAGLevel
                     -> { fontSize : Float , fontWeight : Int }
                     -> Color -> Color -> Bool

Blending Colors













Color.Blending.difference 
    lightBlue 
    orange












Color.Blending.multiply 
    lightBlue 
    orange









Blend.add lightBlue orange









Blend.subtract lightBlue orange









Blend.multiply lightBlue orange









Blend.divide lightBlue orange













subtractive a b =
    let ( ra, ga, ba ) = 
            Color.toRGB a
        ( rb, gb, bb ) = 
            Color.toRGB b
    in
    Color.fromRGB
        ( abs (255 - (ra + rb))
        , abs (255 - (ga + gb))
        , abs (255 - (ba + bb))
        )














import Color.Blend 
    exposing (
        add
    )

Adjusting & Generating Colors

Adjusting Saturation

viewShades : Color -> Html msg
viewShades color =
    viewPalette color
        [ Color.Generator.shade 10 color
        , Color.Generator.shade 20 color
        , Color.Generator.shade 30 color
        , Color.Generator.shade 40 color
        ]
viewTints : Color -> Html msg
viewTints color =
    viewPalette color
        [ Color.Generator.tint 10 color
        , Color.Generator.tint 20 color
        , Color.Generator.tint 30 color
        , Color.Generator.tint 40 color
        , Color.Generator.tint 50 color
        ]
viewTones : Color -> Html msg
viewTones color =
    viewPalette color
        [ Color.Generator.tone -100 color
        , Color.Generator.tone -80 color
        , Color.Generator.tone -60 color
        , Color.Generator.tone -40 color
        , Color.Generator.tone -20 color
        ]

Generation

Through Interpolation

Generation

Through the Color Wheel

-- tesk9/palette
-- module Color.Generator


complementary : Color -> Color
-- tesk9/palette
-- module Color.Generator


triadic : Color -> ( Color, Color )
-- tesk9/palette
-- module Color.Generator


tetratic : Float -> Color -> ( Color, Color, Color )

Full Color Palettes

Building Towards Palettes

dawehner/elm-colorbrewer

Sequential data

Diverging data

Qualitative data

terezka/line-charts

Palette.X11

Palette.Cubehelix

Palette.Cubehelix

-- using tesk9/palette

import Color
import Palette.Cubehelix as Cubehelix


Cubehelix.generateAdvanced colorCount
  { startingColor = 
       Color.fromHSL ( 20, 100, 0 )
  , rotationDirection = Cubehelix.RGB
  , rotations = 0.9
  , gamma = 1.0
  }
-- using tesk9/palette

import Color
import Palette.Cubehelix as Cubehelix


Cubehelix.generateAdvanced colorCount
  { startingColor = 
       Color.fromHSL ( 20, 60, 0 )
  , rotationDirection = Cubehelix.BGR
  , rotations = 1.5
  , gamma = 0.5
  }

Elm State

🧡

(@t_kelly9)

Packages

References

Read more about cubehelix in this article and read Green's paper. 
Play with ColorBrewer colors on a map. 
Learn about the Tango project.
Read the Wikipedia article on web colors.
Reference the relative luminance algorithm and the contrast success criteria from WCAG.
Read Goethe's Theory of Colors or Newton's Opticks on Project Gutenberg. 
Dig up some fun-with-colors with Munsell's Soil Book of Colors.

Thank you!

Color Coding with Elm

By Tessa K

Color Coding with Elm

  • 1,654