Skip to content

Instantly share code, notes, and snippets.

@depoulo
Last active December 18, 2018 10:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save depoulo/4d66a1799c3fbb8992ff07e93a538e2a to your computer and use it in GitHub Desktop.
Save depoulo/4d66a1799c3fbb8992ff07e93a538e2a to your computer and use it in GitHub Desktop.
The CSS4 contrast adjuster mimicked with just custom properties and calc(). Demo: https://codepen.io/depoulo/pen/WLGeQz
/*
The CSS4 contrast adjuster mimicked with just custom properties and calc().
While it's pretty straightforward to mimick the hue, saturation and
lightness adjusters, color contrast requires some "serious" math.
Results are not perfect, but very much usable IMHO.
Syntax of course is even more bloated than for the simple adjusters stated above.
*/
html::before {
/* A few demo styles. */
position: fixed;
top: 50vh;
left: 50vw;
transform: translate(-50%, -50%);
z-index: 2;
font-weight: bold;
font-size: 26px;
padding: 1em;
content: "Foreground";
/* If you see a red foreground,
you have a syntax error somwehere below this. */
color: hsl(0, 100%, 50%);
/* Foreground hue and saturation
(lightness omitted as it's calc'ed to achieve contrast). */
--fg-h: 100;
--fg-s: 75;
/* Background hue, saturation, lightness. */
--bg-h: 100;
--bg-s: 75;
--bg-l: 30; /* <--- MODIFY ME AND WATCH THE FOREGROUND ADAPT! */
/* The ratio for the contrast() adjuster,
see https://www.w3.org/TR/css-color-4/#modifying-colors */
--contrast-ratio: 80%;
/* This is how colors need to be specified.
Conversion of saturation and lightness to percentage done here
to enable prior calculations. */
background-color: hsl(
var(--bg-h),
calc(var(--bg-s) * 1%),
calc(var(--bg-l) * 1%)
);
/* The foreground color with contrast adjuster. */
color: hsl(
var(--fg-h),
calc(var(--fg-s) * 1%),
/* Calculate the lightness:
1. Take the 1/x function
2. Turn it upside down: -1/x
2. Adjust it to the x and y axis: -1/(x-50)+x
3. Make it less curved,
so the y-axis makes sense between 0 and 100: -2500/(x-50)+x
4. Adjust the curve with the contrast ratio,
but make sure we're never multiplying by 0: (-2500*(c/100+1))/(x-50)+x
*/
calc((-2500 * (var(--contrast-ratio) / 100 + 1%)) / (var(--bg-l) - 50) + var(--bg-l) * 1%)
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment