Skip to content

calico32/postcss-color-contrast

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

postcss-color-contrast

This PostCSS plugin implements a polyfill for the color-contrast() function, part of the extremely new CSS Color Module Level 6 spec.

Because the color is computed at compile-time, this plugin only supports literal colors (i.e. hex, rgb(), hsl()) and does not support var() or calc() expressions, currentColor, etc., and therefore must be placed near the end of the PostCSS chain.

No guarantees are made about the spec-compliance of this plugin, but I tried my best.

TL;DR Spec behavior

Syntax

selector {
  color: color-contrast(<color> vs <color>, <color>[, ...] [to <number> | AA | AA-large | AAA | AAA-large]);
}

I'll call the first color the "background", the list of colors the "foreground" colors, and the number/keyword the "target ratio".

Semantics

No target ratio: color-contrast(<color> vs <color>, <color>[, ...])

  • The foreground color that has the highest contrast ratio with the background color is used.

Target ratio: color-contrast(<color> vs <color>, <color>[, ...] to <number> | AA | AA-large | AAA | AAA-large)

  • The first foreground color in the list that has a contrast ratio greater than or equal to the target ratio is used.
  • AA-large is the same as 3.
  • AA is the same as 4.5.
  • AAA-large is the same as 4.5.
  • AAA is the same as 7.

Usage

npm install --save-dev postcss-color-contrast
yarn add -D postcss-color-contrast

In your postcss.config.js file:

module.exports = {
  plugins: [
    require('postcss-color-contrast'),
  ],
};

Or programmatically:

const postcss = require('postcss')

postcss([
  // ... other plugins here
  require('postcss-color-contrast'),
  // ... maybe more plugins here
]).process(css)

Additionally, use the colorContrast() function from JavaScript:

import colorContrast from 'postcss-color-contrast/js'
const colorContrast = require('postcss-color-contrast/js')
// -> colorContrast(backgroundColor, foregroundColors, targetRatio, outputFormat)

// provide colors in any valid CSS color format, or a [r, g, b] array
colorContrast('#0f172a', ['#e5e5e5', '#171717']) // -> '#e5e5e5'
colorContrast('rgb(194, 65, 12)', ['hsl(0, 0%, 90%)', [23, 23, 23]], 'aa') // -> '#ffffff'

// provide an output format (defaults to 'hex')
const bg = '#6ee7b7'
const fg = ['#ecfdf5', '#d1fae5', '#a7f3d0', '#6ee7b7', '#34d399', '#10b981', '#059669', '#047857', '#065f46', '#064e3b']
const target = 'aa'
colorContrast(bg, fg, target)   // -> '#065f46'
colorContrast(..., 'hex')       // -> '#065f46'
colorContrast(..., 'rgb')       // -> 'rgb(6, 95, 70)'
colorContrast(..., 'rgb-array') // -> [6, 95, 70]
colorContrast(..., 'hsl')       // -> 'hsl(163, 88%, 20%)' (rounded)
colorContrast(..., 'hsl-array') // -> [163.14606741573033, 0.8811881188118811, 0.19803921568627453] (not rounded)

Examples

Arguments to color-contrast() wrapped onto multiple lines for clarity.

InputOutputImage
.container {
  background-color: #0f172a;
  color: color-contrast(
    #0f172a vs 
    #e5e5e5, #171717
  );
}
.container {
  background-color: #0f172a;
  /*
    picks the color in the list 
    (after "vs") that has the
    highest contrast ratio with
    the first color
  */
  color: #e5e5e5;
}

.container {
  background-color: #6ee7b7;
  color: color-contrast(
    #6ee7b7 vs 
    #ecfdf5, #d1fae5,
    #a7f3d0, #6ee7b7,
    #34d399, #10b981,
    #059669, #047857,
    #065f46, #064e3b 
    to AA
  );
}
.container {
  background-color: #6ee7b7;
  /*
    with a target contrast:
    picks the first color
    that meets or exceeds 
    the target contrast ratio
  */
  color: #065f46; /* 5.41:1 */
}

.container {
  background-color: #c2410c;
  color: color-contrast(
    #c2410c vs 
    #e5e5e5, #171717 
    to AA
  );
}
.container {
  background-color: #c2410c;
  /* 
    defaults to black or white 
    if the target contrast cannot 
    be met with the provided colors 
  */
  color: #fff;
}

About

PostCSS `color-contrast()` polyfill

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published