Modern CSS can build a full color palette from a single brand color and switch between light and dark mode with one line. No Sass functions and no JavaScript.

oklch: perceptual colors

The oklch() function uses lightness, chroma and hue. Changing the lightness gives predictable results, unlike hex or hsl.

css">:root {
    --lotgrafix-brand: oklch( 65% 0.25 35 );
}

color-mix: blend two colors

.lotgrafix-button {
    background: var( --lotgrafix-brand );
}

.lotgrafix-button:hover {
    background: color-mix( in oklch, var( --lotgrafix-brand ), black 20% );
}

.lotgrafix-tint {
    background: color-mix( in oklch, var( --lotgrafix-brand ), white 85% );
}

Relative colors: derive a color from another

Use the from keyword to read the channels of a color and change only what you need.

.lotgrafix-light {
    background: oklch( from var( --lotgrafix-brand ) calc( l + 0.2 ) c h );
}

.lotgrafix-transparent {
    background: oklch( from var( --lotgrafix-brand ) l c h / 0.3 );
}

light-dark: automatic dark mode

Set color-scheme first, then pick a value for each mode in a single declaration.

:root {
    color-scheme: light dark;
    --lotgrafix-bg: light-dark( #ffffff, #111111 );
    --lotgrafix-text: light-dark( #222222, #eeeeee );
}

body {
    background: var( --lotgrafix-bg );
    color: var( --lotgrafix-text );
}

contrast-color: readable text automatically

The newer contrast-color() function picks black or white text depending on the background. Check browser support before relying on it.

.lotgrafix-badge {
    background: var( --lotgrafix-brand );
    color: contrast-color( var( --lotgrafix-brand ) );
}

Wide gamut colors

.lotgrafix-vivid {
    background: color( display-p3 1 0.3 0 );
}

@supports not ( color: color( display-p3 1 0 0 ) ) {
    .lotgrafix-vivid {
        background: #ff4d00;
    }
}
«
»