RSS FeedTwitterMastodonBlueskyShare IconHeart IconGithub IconArrow IconClock IconGUI Challenges IconHome IconNote IconBlog IconCSS IconJS IconHTML IconShows IconOpen Source Software IconSpeaking IconTools IconShuffle IconNext IconPrevious IconCalendar IconCalendar Edit IconNotebook IconObservable Notebooks IconSlash IconGoogle G Icon
Screenshot of the final code snippet from this blog post.
A cartoon skull with a hotpink hat on.4 min read

A color-contrast() strategy for complimentary translucent backgrounds

css

The goal I had in mind was to have maximized text contrast against any color. This meant the text color should contrast well, but also I wanted a supportive translucent background to help bump that contrast even further, for situations where it may have otherwise had low contrast.

To do this:

  1. I find a good contrasting text color with color-contrast().
  2. Then I find a contrasting color for that text color with color-contrast().
  3. Use that text contrast color as a supportive translucent background with relative color syntax oklch(from black l c h / 40%)

tldr;

  1. If the text color is white, it's supportive background should be translucent black.
  2. If the text color is black, it's supportive background should be translucent white.

It's so much easier to see, but you can try it here:

See how I've automated the text color and a supportive background on that text? I don't have to care about the color I'm overlaying now, the browser handles all of it dynamically!

The essentials of the effect #

I use 2 future CSS features that aren't well supported yet (but are very fun to play with):

  1. color-contrast() - spec
  2. "Relative color syntax" - spec

Safari Tech Preview is the only browser with support for relative color syntax at the time of writing this post. Chrome Canary has color-contrast() support but won't have the dynamic supportive background (see generic bg in CSS below).

First, the container background needs to be in a custom property so we can share it with other functions:

section {
  --bg: hsl(var(--hue) 50% 50%);
}

Then, the h1 need to put it's contrasting text color into a custom property so we can share it too:

h1 {
  /* pick either black or white based on --bg */
  --text: color-contrast(var(--bg) vs black, white);
  color: var(--text);
  
  /* generic semitransparent bg */
  background: hsl(0 0% 0% / 40%);
}

For the cherry on top, if the browser understands relative color syntax, then create a new semi-transparent color from the contrasting color of --text.

/* if relative color syntax is supported */
@supports (background: hsl(from red h s l)) {
  h1 {
    /* pick either black or white 
       depending which contrasts with --text,
       extract it and make it 40% semitransparent */
    background: oklch(from color-contrast(var(--text) vs black,white) l c h / 40%);
  }
}

All of it together:

@layer demo {
  section {
    --bg: hsl(var(--hue) 50% 50%);
  }
  
  h1 {
    --text: color-contrast(var(--bg) vs black, white);
    color: var(--text);
    background: hsl(0 0% 0% / 40%);
  }
  
  @supports (background: hsl(from red h s l)) {
    h1 {
      background: oklch(from color-contrast(var(--text) vs black,white) l c h / 40%);
    }
  }
}

Conclusion #

There you have it, dynamically contrasting text with a supportive translucent background. I think that's pretty rad stuff.

Here's the Codepen embedded, so in the future it'll just work 🤓

39 comments #

388likes
75reposts
  • Alexis Mora Angulo
  • tigerh
  • Віталій Бобров 🇺🇦💗🛡️⚔️
  • sarai-ap03
  • H. EL-WATANY
  • hiro:processinger
  • Cristiano Rastelli
  • Jason Lawton :wordpress:
  • T. Afif @ CSS Challenges
  • Ст. 122 УК РБ
  • CSS by T. Afif :verified:
  • Scott Tolinski - Syntax.fm - LevelUpTuts
  • Josef Ježek
  • Sergio Gallardo. Especialista en Marketing Digital
  • John Sim
  • Una 🇺🇦
  • Šimon DSK
  • Audrey Le Mercier
  • Rodrigo Castro
  • Katy Castillo
  • Support striking workers
  • GENKI
  • Maxime Rossignol
  • techie quickhatch ⚛ 🐾 (Айті Росомаха)
  • siriwatknp
  • Mike-麥-Mai/index.html
  • CNine
  • Chanfi Attoumani
  • K Anne
  • Coinbroccoli
  • John Miller
  • Mike Shtilerman
  • Sujal Shah ⚡
  • Rishi
  • Ali Syahidin
  • Aykhan Huseyn
  • Vi Pro
  • Евгений Резниченко
  • Lingxi Li
  • Оля
  • geoffrey.crofte@mastodon.design 🐧
  • ❖ Adrian
  • KuronNazaki
  • Ulf Hansen
  • L!on 💙💛
  • Umma
  • Arnoldyall
  • Aarav Sareen
  • Roman Czerkies
  • its_Classyd
  • Lorien
  • Carlos Caballero
  • Sang Nguyen
  • PawaOx4th
  • Jesse Holden
  • D7460N
  • Melvin Rimachi
  • jota
  • Jon Graft
  • Fresh Frontend Links
  • Jesus Rodriguez
  • Nicolas Giethlen
  • fg
  • x
  • Thomas Kowalski
  • Michelle Barker
  • Elly Loel ✨🌱
  • David G. Smith
  • Ricard Torres
  • Sine 🏳️‍🌈
  • Virtual Boy :bec_wink:
  • kaiserkiwi :kiwibird:
  • Tyler Sticka
  • Shannon Moeller
  • Callie 🏳️‍⚧️
6 pingbacks

Join the conversation on

Another conditional CSS feature 🤩
Ahmad ShadeedAhmad Shadeed

@argyleink last i remember, this feature was blocked by discussions around WCAG contrast algorithm not being perfect. is that still the case?

my take is that the algorithm could be changed to match what WCAG 3.0 recommends (years from now) and that it shouldn't block this feature today.

MayankMayank

@argyleink that's so unfortunate that it's still blocked. especially since it's not something that can be easily emulated at build time (css vars being computed at runtime and whatnot) 😔

MayankMayank

@argyleink also holy hell ColorJS is so cool

MayankMayank

@argyleink slightly off topic: Is that gif in your website a custom character from 'OlliOlli World'?

jerryjerry

@argyleink I loved OO1 and OO2. Finally got started on OOW and I love it for multiple reasons.

jerryjerry
This is rad! I remember hacking with calc() and CSS variables to simulate such behavior 3 years ago 😅 stackoverflow.com/a/59287516/862…
T. Afif @ CSS ChallengesT. Afif @ CSS Challenges
Bro. I cannot wait for this.
Scott Tolinski - Syntax.fm - LevelUpTutsScott Tolinski - Syntax.fm - LevelUpTuts
Ringing bells over here too, but I don't think anyone can hear them.
Scott Tolinski - Syntax.fm - LevelUpTutsScott Tolinski - Syntax.fm - LevelUpTuts
I did it with filter codepen.io/thebabydino/pe… Based on one of the tactics from this article I wrote 6 years ago css-tricks.com/methods-contra…
Ana Tudor 🐯🖤🌻Ana Tudor 🐯🖤🌻
nerdy.dev/color-from-col… this page is broken in android chrome 110.0.5481.61
🌞 kit is squiggly 🌚🌞 kit is squiggly 🌚
i don't think so, i just recorded a trace and sent it over email
🌞 kit is squiggly 🌚🌞 kit is squiggly 🌚
A color-contrast() strategy for complimentary translucent backgrounds That's really interesting and would make both contrast setting and design system theming way easier. nerdy.dev/color-from-col…
geoffrey.crofte@mastodon.design 🐧geoffrey.crofte@mastodon.design 🐧
Text is overflowing and outside the screen (at right) on mobile devices
(H)edocode 👨🏻‍💻(H)edocode 👨🏻‍💻
It solves very important problems - Accessibility
Rishi ShahRishi Shah
Сегодня впервые в жизни использовала hsl colors, это прорыв! Понимать hsl цвета все же гораздо проще и притом можно легко выполнять математические операции с ними. Надо переходить на генеративные палитры
разработчица в Амстердамеразработчица в Амстердаме
A color-contrast() strategy for complimentary translucent backgrounds nerdy.dev/color-from-col…
Fresh Frontend LinksFresh Frontend Links
A “color-contrast()” Strategy for Complimentary Translucent Backgrounds, by @argyleink: nerdy.dev/color-from-col…
Frontend DogmaFrontend Dogma
A color-contrast() strategy for complimentary translucent backgrounds · 7 febbraio 2023 nerdy.dev/color-from-col…
Giusè ✏️Giusè ✏️

@argyleink Great post, as always! 👏 In browsers only supporting color-contrast() but not the relative color syntax, you could compose the background in the same way, they do it in Tailwind: https://adamwathan.me/composing-the-uncomposable-with-css-variables/#:~:text=Using%20CSS%20variables%20for%20partial%20values

Composing the Uncomposable with CSS Variables – Adam Wathan
Christian "Schepp" SchaeferChristian "Schepp" Schaefer
@argyleink@front-end.social oh! you're in the fediverse. how could i've missed that. great!
samrecitersamreciter
A color-contrast() strategy for complimentary translucent backgrounds nerdy.dev/color-from-col… Thank you, @argyleink 👍 #webdev #CSS
Phuoc NguyenPhuoc Nguyen
🔗 A color-contrast() strategy for complimentary translucent backgrounds > The goal I had was to have maximized text contrast against any color. This meant the text color should contrast well, but also I wanted a supportive translucent background. nerdy.dev/color-from-col…
trovstertrovster
A #CSS color-contrast() strategy for complimentary translucent backgrounds: "The goal was to have maximized text contrast against any color. This meant a translucent background to help bump that contrast further, for situations where it has low contrast." nerdy.dev/color-from-col…
CSS BasicsCSS Basics