- let data = [
- 	{ col: '#007b7e', txt: 'gingerbread' }, 
- 	{ col: '#0f586f', txt: 'brownie' }, 
- 	{ col: '#26364e', txt: 'lava cake' }, 
- 	{ col: '#5a4a6c', txt: 'macaron' }, 
- 	{ col: '#955c7a', txt: 'ice cream' }, 
- 	{ col: '#b76567', txt: 'chocolate' }
- ];
- let n = data.length;

form(style=`--k: 0`)
	- for(let i = 0; i < n; i++) {
		- let c = '#' + data[i].col.match(/\w{2}/g).map(ch => (255 - parseInt(`0x${ch}`, 16)).toString(16)).join('')
		input(type='radio' name='o' id=`o${i}` value=i checked=!i)
		label(for=`o${i}` style=`--i: ${i}; --c: ${c}` data-txt=data[i].txt)
	- }
View Compiled
$pad: .5em;

form {
	display: grid;
	grid-auto-flow: column;
	grid-gap: $pad;
	place-content: center;
	padding: $pad;
	min-width: max-content;
	background: #222;
	font: 1.5em/ 1.5 sans-serif;
	white-space: nowrap;
	filter: invert(1)
}

[type=radio] {
	position: absolute;
	opacity: 0;
	
	&, & + label { cursor: pointer }
	
	+ label {
		--sgn: clamp(-1, var(--k) - var(--i), 1);
		overflow: hidden;
		position: relative;
		padding: 0 2*$pad;
		background: #000;
		color: var(--c);
		
		&::before, &::after { transition: transform .5s }
		
		&::before {
			display: block;
			transform: translate(calc(var(--sgn)*-.5*#{$pad}));
			content: attr(data-txt)
		}
		
		&::after {
			position: absolute;
			top: 0; right: 0; bottom: 0; left: 0;
			transform: translate(calc(var(--sgn)*(100% - #{$pad})));
			background: currentcolor;
			mix-blend-mode: difference;
			content: '';
		}
	}
}
View Compiled
addEventListener('change', e => {
	let _t = e.target;
	_t.parentNode.style.setProperty('--k', +_t.value)
});

/*
Used in my Taming Blend Modes: `difference` and `exclusion` (https://css-tricks.com/taming-blend-modes-difference-and-exclusion/) article on CSS-Tricks - check it out for context!
*/
View Compiled

External CSS

  1. https://codepen.io/thebabydino/pen/evPbxv.scss

External JavaScript

  1. https://codepen.io/thebabydino/pen/evPbxv.js