- 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
/* the following 4 lines are ALL the JS needed for the demo to work */
addEventListener('change', e => {
let _t = e.target;
_t.parentNode.style.setProperty('--k', +_t.value)
});
/* external resources only used to add the "watch me code this" link */
/*
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