chickadee » web-colors


Project / Source Code Repository
Issue Tracker
John Croisant
BSD 2-Clause

This library can parse and write colors in a variety of formats used in HTML/CSS:

This library does not provide color math or color space conversion. It is intended to be used with other libraries.

Table of Contents


(import web-colors)

(parse-web-color "#B64926") ; → (rgb 182 73 38 1)
(web-color->string '(rgb 182 73 38 1)) ; → "#b64926"

(parse-web-color "rgb(93 152 121 / 51%)") ; → (rgb 93 152 121 51/100)
(web-color->string '(rgb 93 152 121 51/100)) ; → "rgba(93, 152, 121, 0.51)"

(parse-web-color "rgba( 100%, 72.9%, 33%, 0.5 )") ; → (rgb% 1 0.729 33/100 0.5)
(web-color->string '(rgb% 1 0.729 33/100 0.5)) ; → "rgba(100%, 72.9%, 33%, 0.5)"

(parse-web-color "hsl(210 51% 87% / 77%)") ; → (hsl 210 51/100 87/100 77/100)
(web-color->string '(hsl 210 51/100 87/100 77/100)) ; → "hsla(210, 51%, 87%, 0.77)"

(parse-web-color "indigo") ; → (rgb 75 0 130 1)
(web-color->string '(rgb 75 0 130 1)) ; → "#4b0082"
(web-color-name '(rgb 75 0 130 1)) ; → "indigo"

;; Create file styles.css containing "body { color: #010203; }"
(call-with-output-file "styles.css"
  (lambda (port)
    (display "body { color: " port)
    (write-web-color '(rgb 1 2 3 1) port)
    (display "; }" port)))

;; Use with other libraries
(import (prefix sdl2 "sdl2:"))
(apply sdl2:make-color
 (rgb-color->bytes (parse-web-color "indigo")))
;; → #<sdl2:color (75 0 130 255)>

Data representation

Colors are represented as a list starting with a symbol indicating the color type, followed by the color components. See above for examples. The semantics of each component depends on the color type:


       red         [0, 255]
       green       [0, 255]
       blue        [0, 255]
       alpha       [0, 1]

       red         [0, 1]
       green       [0, 1]
       blue        [0, 1]
       alpha       [0, 1]

       hue         [0, 360)  see below
       satur.      [0, 1]
       lumin.      [0, 1]
       alpha       [0, 1]

Values with a typical range of [0, 1] are usually represented with floating point numbers or ratios. Values with a larger range are usually represented with integers, but floating point numbers or ratios are allowed.

Values outside of the typical range are allowed. You can use normalize-web-color to clamp/wrap values to their typical range.

In CSS Color Module Level 4, the hue component can optionally have a unit: deg, rad, grad, or turn. The parser converts the hue to degrees, and the writer assumes it is in degrees.


parse-web-color stringprocedure
parse-hex-color stringprocedure
parse-named-color stringprocedure
parse-rgb-color stringprocedure
parse-hsl-color stringprocedure

The parse-web-color procedure parses any type of color from a string. It returns an rgb, rgb%, or hsl color list depending on the input.

The other procedures can only parse certain types of colors, but are more efficient if you only need to parse those types.

  • parse-hex-color parses hex colors with 3, 4, 6, or 8 digits. It returns a rgb color list.
  • parse-named-color parses named colors, a.k.a. color keywords. It returns a rgb color list.
  • parse-rgb-color parses rgb() or rgba() colors. It returns a rgb% color list if the red/green/blue values are percentages, or a rgb color list if they are non-percentages.
  • parse-hsl-color parses hsl() or hsla() colors. It returns a hsl color list. The hue is converted to degrees.

These procedures signal an error if parsing fails.


write-web-color color-list #!optional portprocedure
write-hex-color color-list #!optional portprocedure
write-rgb-color color-list #!optional portprocedure
write-hsl-color color-list #!optional portprocedure

The write-web-color procedure writes any type of color to port (by default, the current output port). Its behavior is as follows:

  • rgb color lists are written in #RRGGBB format if alpha is 1, or in rgb() format with integers if alpha is other than 1. (Not all browsers support #RRGGBBAA format yet.)
  • rgb% color lists are written in rgb() format with percentages if alpha is 1, or in rgba() format with percentages if alpha is other than 1.
  • hsl color lists are written in hsl() format if alpha is 1, or in hsla() format if alpha is other than 1. For compatibility, the hue is written without a unit (degrees is implied).

The other procedures can only write certain types of colors, but are more efficient if only need to write one color type. You can also use them to write in a format that write-web-color would not use. For example, write-hex-color will write an 8 digit hex color if given an rgb or rgb% color list with alpha other than 1, whereas write-web-color would write a rgba() color.

write-hex-color and write-rgb-color accept rgb or rgb% color lists. write-hsl-color accepts hsl color lists.

These procedures signal an error if the color list is invalid or an unsupported type.

web-color->string color-listprocedure
rgb-color->hex-string color-listprocedure
rgb-color->string color-listprocedure
hsl-color->string color-listprocedure

Like write-web-color, etc. except that the color is written to a string and returned. Equivalent to:

  (lambda (port)
    (write-web-color color-list port)))
web-color-name color-listprocedure

Attempts to find a named color exactly matching the given color list. Returns the color name string if found, or #f if not found.

The colors are compared with equal?, so the given color list should be a rgb type with exact integers, not ratios or floats. Alpha should usually be 1, except "transparent" which has alpha 0.

Note that some colors are synonyms (e.g. "aqua" and "cyan"). In such cases only the first match is returned. (By default, color names are ordered alphabetically, but this can be overridden with the *web-color-names* parameter.)



A list of symbols for the color types supported by this library: '(rgb rgb% hsl). This may be expanded in future versions.

color-list? x #!optional typesprocedure

Returns #t if x is a valid color list, i.e. a list containing a color type symbol and 4 numbers. It does not check that the numbers are in the typical range.

types can be a list of symbols to check that x is one of the specified color types. If types is omitted it defaults to +web-color-types+, so it checks for any supported color type.

(color-list? '(hsl 1 2 3 4))  ; → #t
(color-list? '(hsl 1 2 3 4) '(rgb rgb%))  ; → #f
rgb-color->bytes color-listprocedure

Converts a rgb or rgb% color list into a list containing the RGBA color components as exact integers in the range [0, 255].

(rgb-color->bytes '(rgb 123 256 -1 50/100)) ; → (123 255 0 128)
(rgb-color->bytes '(rgb% 0.4 1.1 -0.1 0.25)) ; → (102 255 0 128)
normalize-web-color color-listprocedure

Returns a normalized copy of the given color list. All values are clamped or wrapped to their typical range.

  • For rgb color lists, red/green/blue are rounded to the nearest integers and clamped to [0, 255], and alpha is clamped to [0, 1].
  • For rgb% color lists, all values are clamped to [0, 1].
  • For hsl color lists, hue is rounded to the nearest integer and wrapped (not clamped) to [0, 360), and alpha is clamped to [0, 1].

Signals an error if the color list is invalid.


Contains a list of (symbol . list) pairs for named colors. You can override this parameter to change the color names recognized by parse-web-color, parse-named-color, and web-color-name. Color names should contain only lower-case letters, numbers, and hyphens.

;; Add the colors "amaranth" and "viridian".
 `((amaranth . (rgb 229 43 80 1))
   (viridian . (rgb 64 130 109 1))

(parse-web-color "amaranth")
; → (rgb 229 43 80 1)

(web-color-name '(rgb 64 130 109 1))
; → "viridian"

Version History

1.0.0 (2019-12-31)
Initial release.

Contents »