Color.CSS (Color v0.4.0)

Copy Markdown

CSS Color Module Level 4 / 5 parsing and serialisation.

parse/1 accepts any of:

  • Hex — #fff, #ffffff, #ffff (RGBA), #ffffffff (RRGGBBAA).

  • Named — red, rebeccapurple, "Misty Rose", :transparent.

  • rgb() / rgba()rgb(255 0 0), rgb(255, 0, 0), rgb(255 0 0 / 50%), rgba(255 0 0 0.5). Both legacy comma-separated and modern whitespace forms are accepted.

  • hsl() / hsla()hsl(0 100% 50%), hsl(0deg 100% 50% / .5).

  • hwb()hwb(0 0% 0%).

  • lab() / lch()lab(50% 40 30), lch(50% 40 30deg). The lightness accepts % or the raw L value; lab / lch use the CIE 1976 L*a*b* / LCHab definitions with a D50 reference white as specified by CSS Color 4.

  • oklab() / oklch()oklab(63% 0.2 0.1), oklch(63% 0.2 30).

  • color()color(srgb 1 0 0), color(display-p3 1 0 0), color(rec2020 1 0 0), color(prophoto-rgb 1 0 0), color(xyz-d65 0.95 1 1.09), color(xyz-d50 ...), color(a98-rgb 1 0 0), color(srgb-linear 1 0 0).

  • device-cmyk() (CSS Color 5)device-cmyk(0% 100% 100% 0%), device-cmyk(0 1 1 0 / 50%). Returns a Color.CMYK struct.

  • color-mix() (CSS Color 5)color-mix(in oklch, red 40%, blue), color-mix(in lab, red, blue 30%). The first argument is in <space> (any space Color.Mix.mix/4 understands); the remaining two are colors with optional percentages. The mixed result is returned in the interpolation space.

  • Relative color syntax (CSS Color 5)rgb(from <color> r g b), oklch(from <color> l c calc(h + 30)), etc. Inside the function body the source color's components are bound to identifiers (r/g/b for rgb(), h/s/l for hsl(), l/c/h for LCH-style spaces, etc) and alpha is always available. Components may be referenced bare or wrapped in calc().

  • none keyword (CSS Color 4)rgb(none 0 0), oklch(0.7 none 30). A channel of none is treated as the space's neutral default (zero in the relevant unit).

  • calc()rgb(calc(255 / 2) 0 0), lab(calc(50 + 10) 0 0). Inside relative-color syntax, calc() expressions can reference the captured component identifiers, e.g. oklch(from teal calc(l + 0.1) c h).

to_css/2 serialises any color struct back to one of these forms. The default serialiser choice follows the struct type.

Summary

Functions

Parses a CSS Color 4 / 5 color string.

Serialises a color struct as a CSS Color 4 function string.

Functions

parse(input)

@spec parse(String.t()) :: {:ok, struct()} | {:error, Exception.t()}

Parses a CSS Color 4 / 5 color string.

Arguments

  • input is a string.

Returns

  • {:ok, struct} on success.

  • {:error, reason} otherwise.

Examples

iex> {:ok, c} = Color.CSS.parse("rgb(255 0 0)")
iex> {c.r, c.g, c.b}
{1.0, 0.0, 0.0}

iex> {:ok, c} = Color.CSS.parse("rgb(255 0 0 / 50%)")
iex> c.alpha
0.5

iex> {:ok, c} = Color.CSS.parse("hsl(120 100% 50%)")
iex> c.h
0.3333333333333333

iex> {:ok, c} = Color.CSS.parse("lab(50% 40 30)")
iex> {c.l, c.a, c.b}
{50.0, 40.0, 30.0}

iex> {:ok, c} = Color.CSS.parse("oklch(63% 0.2 30)")
iex> {Float.round(c.l, 2), Float.round(c.c, 2), Float.round(c.h, 2)}
{0.63, 0.2, 30.0}

iex> {:ok, c} = Color.CSS.parse("color(display-p3 1 0 0)")
iex> c.working_space
:P3_D65

iex> {:ok, c} = Color.CSS.parse("rgb(none 0 0)")
iex> {c.r, c.g, c.b}
{0.0, 0.0, 0.0}

iex> {:ok, c} = Color.CSS.parse("rgb(calc(255 / 2) 0 0)")
iex> Float.round(c.r, 4)
0.5

iex> {:ok, c} = Color.CSS.parse("device-cmyk(0% 100% 100% 0%)")
iex> {c.c, c.m, c.y, c.k}
{0.0, 1.0, 1.0, 0.0}

iex> {:ok, c} = Color.CSS.parse("color-mix(in oklab, red, blue)")
iex> c.__struct__
Color.Oklab

iex> {:ok, c} = Color.CSS.parse("oklch(from red calc(l + 0.1) c h)")
iex> c.__struct__
Color.Oklch

to_css(color, options \\ [])

@spec to_css(struct(), keyword()) :: String.t()

Serialises a color struct as a CSS Color 4 function string.

Arguments

  • color is any supported color struct.

  • options is a keyword list.

Options

  • :as — override the default serialiser form. One of :rgb, :hex, :hsl, :lab, :lch, :oklab, :oklch, :color.

Returns

  • A string.

Examples

iex> Color.CSS.to_css(%Color.SRGB{r: 1.0, g: 0.0, b: 0.0})
"rgb(255 0 0)"

iex> Color.CSS.to_css(%Color.SRGB{r: 1.0, g: 0.0, b: 0.0, alpha: 0.5})
"rgb(255 0 0 / 0.5)"

iex> Color.CSS.to_css(%Color.SRGB{r: 1.0, g: 0.0, b: 0.0}, as: :hex)
"#ff0000"

iex> Color.CSS.to_css(%Color.Oklch{l: 0.63, c: 0.2, h: 30.0})
"oklch(63% 0.2 30)"

iex> Color.CSS.to_css(%Color.Lab{l: 50.0, a: 40.0, b: 30.0})
"lab(50% 40 30)"

iex> Color.CSS.to_css(%Color.CMYK{c: 0.0, m: 1.0, y: 1.0, k: 0.0})
"device-cmyk(0% 100% 100% 0%)"