惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
L
Lohrmann on Cybersecurity
aimingoo的专栏
aimingoo的专栏
V
V2EX
S
Security Affairs
T
Threatpost
C
CXSECURITY Database RSS Feed - CXSecurity.com
IT之家
IT之家
J
Java Code Geeks
The Register - Security
The Register - Security
U
Unit 42
C
CERT Recently Published Vulnerability Notes
月光博客
月光博客
A
About on SuperTechFans
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
The Blog of Author Tim Ferriss
Cisco Talos Blog
Cisco Talos Blog
Project Zero
Project Zero
S
Schneier on Security
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
D
DataBreaches.Net
博客园 - 司徒正美
V
Vulnerabilities – Threatpost
T
Tor Project blog
Security Latest
Security Latest
T
The Exploit Database - CXSecurity.com
T
Threat Research - Cisco Blogs
Scott Helme
Scott Helme
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
M
MIT News - Artificial intelligence
云风的 BLOG
云风的 BLOG
小众软件
小众软件
L
LangChain Blog
Attack and Defense Labs
Attack and Defense Labs
Recent Commits to openclaw:main
Recent Commits to openclaw:main
P
Palo Alto Networks Blog
A
Arctic Wolf
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
C
Cyber Attacks, Cyber Crime and Cyber Security
博客园 - 叶小钗
D
Darknet – Hacking Tools, Hacker News & Cyber Security
L
LINUX DO - 最新话题
MongoDB | Blog
MongoDB | Blog
Webroot Blog
Webroot Blog
H
Hacker News: Front Page
Know Your Adversary
Know Your Adversary
Spread Privacy
Spread Privacy
AWS News Blog
AWS News Blog
Engineering at Meta
Engineering at Meta

daverupert.com

Finding curated public domain images A workaround for hiding empty slots in Chromium Spoons by Sam Vibe Check №42 The duality of language models in the browser 10,000-watt GPU meet 40-watt lump of meat I don’t want a screenshot of your Claude conversation When moving fast, talking is the first thing to break Inverted themes with light-dark() Ozempic dreams Before I go: People like it when other people make things People are not friction Smaller and dumber Priority of idle hands Magic Words Write about the future you want I’m swearing off APIs entirely Waiting for the power to go out The best version of my site so far… Focus rings with nested contrast-color()? Interpolate contrast-color() to manipulate lightness Using your design system colors with contrast-color() Twenty Twenty-Five Vibe Check №41 One thing churches do well Grid Paper Inkwell Games
Algorithmic hover states with contrast-color()
Dave Rupert · 2026-01-09 · via daverupert.com

Firefox 146 added support for contrast-color() joining Safari 26 in the First Implementor’s Club. For those unfamiliar, contrast-color(<color>) is a new CSS function that will take a <color> as input and returns either white or black depending on which has the most contrast.

The quintessential example is choosing a foreground text color with the best contrast.

button {
	--button-bg: red;
	background: var(--button-bg);
	color: contrast-color(var(--button-bg)); 
	/* @returns black (5.25:1 WCAG AA Pass) 
			not white (3.99:1 WCAG AA Fail) */
}

If someone changes --button-bg to purple, the foreground color automatically resolves to the either white or black, whichever has more contrast. It avoids having to set an extra token for color and takes the guess work out of picking an accessible foreground color.

I think this is going to be an incredible boon to design systems where I don’t control what --button-bg is, but I do care about providing accessible experiences. And I think that’s the goal of this feature; to have “smart defaults” that lead to more accessible websites, easier algorithmically-driven color systems, and better “theme a whole website from a single color picker” demos.

Sure contrast-color() can do foreground colors, but what about backgrounds?

We’re having conversations at work about algorithmically driven rest/hover/active states for Buttons. In the current Baseline you can use color-mix() to lighten/darken colors on :hover

button {
	background-color: var(--button-bg);
	color: contrast-color(var(--button-bg));

	&:hover, &:focus {
		background-color: color-mix(
			in srgb,
			var(--button-bg) 90%,
			black 10%
		)
	}
}

The code above will dim your button on :hover 10% by mixing in black. But what if our Buttons are already dark (black, navy, etc)? In that situation we want to lighten the background-color instead of dimming. We can glue on new classes like button.lighten-on-hover or button.invert-hover and that works… until we get to light and dark theme modes of our Button where you probably want to lighten/darken oppositely depending on the mode…

Ugh. In that situation you’d have @media (prefers-color-scheme: dark), [data-theme="dark"] styles in your Button styles and people are mad now because the Button styles are too complex. There’s got to be a better way!

Well, do I have good news for you…

See the Pen contrast-color() powered lighten/darken bg on hover by Dave Rupert (@davatron5000) on CodePen.

Per my previous conversations, I wondered if we could use contrast-color() to programmatically lighten/darken an button based on its current background-color. If the Button is black, and the contrast-color is white, let’s mix in white (and vice versa):

:root {
	color-scheme: light dark;
	--button-bg: light-dark(navyblue, lightpurple);
}

button {
	background-color: var(--button-bg);
	color: color-contrast(var(--button-bg));

	&:hover, &:focus {
		background-color: color-mix(
			in srgb,
			var(--button-bg) 75%, 
			contrast-color(var(--button-bg)) 10%
		)
	}
}

Huzzah! Now our Button’s hover states go in the desired direction and our foreground color is intrinsically styled based on its own background-color. Nice. From a design systems perspective I’m pretty excited about the possibility to remove a bunch of state-based tokens from our collection.

Now available in… everywhere?

This approach only works in Safari and Firefox. However, if I use Lea Verou’s method of polyfilling contrast-color(), we can pop in a custom @function --contrast-color() that works in Chromium 139+. The final working solution looks like this:

/* @function supported in Chromium */
@function --contrast-color(--bg-color) {
  --l: clamp(0, (l / var(--l-threshold, 0.623) - 1) * -infinity, 1);
  result: oklch(from var(--bg-color) var(--l) 0 h);
}

button {
  /* contrast-color() supported in Safari & Firefox */
  --button-fg: contrast-color(var(--button-bg));
  
  @supports not (color: contrast-color(red)) {
    --button-fg: --contrast-color(var(--button-bg));
  }
  
  background: var(--button-bg);
  color: var(--button-fg);
  
  &:hover,
  &:focus{
    background-color: color-mix(
      in srgb,
      var(--button-bg) 75%,
      var(--button-fg) 10%
    );
  }
}

Depending on your browser matrix, this may work for you. It’s probably a smidge too new for us to roll out to customers, right now but for personal sites heck yeah.

This is interesting tech and I’m excited to dig in more. And spoiler alert, this is the first post in a small little series I have already written up for you.