- let mode = 'exclusion'

h3
	code #{mode}
	|  blend mode
form.controls
	.toggle(role='group' aria-labelledby='toggle-lbl')
		#toggle-lbl Show layers:
		input#lyr-separated(type='radio' name='lyr' style='--i: 0' value='0' checked)
		label(for='lyr-separated' style='--i: 0') separated
		input#lyr-overlaped(type='radio' name='lyr' style='--i: 1' value='1')
		label(for='lyr-overlaped' style='--i: 1') overlapping
section(style=`--mode: ${mode}`)
	.lyr(style=`--i: 0`)
		.grad
		.info destination (bottom) layer
	.lyr(style=`--i: 1`)
		.grad
			.col(data-text='if one layer is black, the resulting layer is identical to the other layer')
			.col(data-text='if one layer is white, the resulting layer is identical to the other layer inverted')
		.info source (top) layer
View Compiled
$ctrl-c: hotpink;
$ctrl-d: 1.1em;
$ctrl-l: 3px;

$rect-m: 1.5rem;
$rect-d: 15rem;
$text-w: 13.5rem;
$text-b: .25rem;

*, ::before, ::after {
	--not-i: calc(1 - var(--i));
	--sgn-i: calc(2*var(--i) - 1);
	margin: 0; 
	padding: 0; 
	font: inherit
}

html {
	font: 200 1.5em/ 1.5 montserrat, sans-serif;
	
	@media (max-width: 700px) { font-size: 1.25em }
	@media (max-width: 585px) { font-size: 1em }
	@media (max-width: 465px) { font-size: .75em }
	@media (max-width: 350px) { font-size: .625em }
}

body {
	--o: 0;
	--not-o: calc(1 - var(--o));
	display: grid;
	align-content: space-between;
	grid-template-rows: max-content calc(#{$rect-d} + #{$rect-m}) max-content;
	overflow-x: hidden;
	min-height: 100vh;
	background: #333;
	color: #eee
}

h3 {
	grid-row: 3;
	place-self: center;
	color: #222;
	font-size: 1.5em;
	font-weight: 600;
	text-shadow: 0 1px #444, 0 -1px 1px #000
}

code {
	font-size: 1.1em;
	font-family: ubuntu mono, consolas, monaco, monospace
}

form { z-index: 1 }

.toggle {
	--hl: 0;
	--not-hl: calc(1 - var(--hl));
	display: grid;
	grid-gap: 2*$ctrl-l;
	grid-template-columns: max-content repeat(2, $ctrl-d) max-content;
	place-content: center;
	filter: grayScale(var(--not-hl));
	transition: filter .3s ease-out;
	
	[id]:not(input) { grid-column: 1/ -1 }
	
	:not(:first-child), &::before, &::after {
		grid-row: 2; 
		align-self: center;
		color: $ctrl-c;
		cursor: pointer
	}
	
	[type='radio'] {
		--d: calc(#{$ctrl-d} + 2*#{$ctrl-l});
		justify-self: center;
		grid-column: calc(2 + var(--i));
		z-index: 2;
		width: var(--d); height: var(--d);
		opacity: 0;
	}
	
	[for] {
		--abs: max(calc(var(--o) - var(--i)), calc(var(--i) - var(--o)));
		margin: 0 .25em;
		filter: grayScale(var(--abs));
		transition: inherit
	}
	
	&::before, &::after {
		--i: 0;
		grid-column: 2/ span calc(1 + var(--not-i));
		align-self: center;
		margin: 0 calc(var(--i)*#{$ctrl-l});
		width: calc(#{$ctrl-d} + var(--not-i)*(#{$ctrl-d} + 2*#{$ctrl-l}));
		height: calc(#{$ctrl-d} + var(--not-i)*2*#{$ctrl-l});
		transform: translate(calc(var(--i)*var(--o)*100%));
		border-radius: $ctrl-d;
		box-shadow: 0 0 0 calc(var(--not-i)*#{$ctrl-l}) currentcolor;
		background: rgba($ctrl-c, var(--i));
		transition: transform .3s ease-out;
		content: ''
	}
	
	&::after { --i: 1 }
	
	&:focus-within, &:hover { --hl: 1 }
}

section {
	display: grid;
	place-content: center;
	padding-top: $rect-m;
	isolation: isolate
}

.lyr {
	display: grid;
	position: relative;
	grid-row: calc(1 + var(--not-i));
	width: $rect-d; height: $rect-d;
	transform: 
		translate(
			calc(var(--not-o)*Max(#{-.5*$text-w}, calc(.5*#{$rect-d} - 50vw))), 
			calc(var(--sgn-i)*(var(--o)*50% + var(--not-o)*25%)));
	mix-blend-mode: var(--mode);
	transition: transform .3s ease-out
}

.grad {
	display: grid;
	grid-auto-flow: column;
	transform: 
		perspective(35em)
		rotatex(calc(var(--not-o)*65deg));
	background: 
		linear-gradient(90deg, #000 50%, #fff 0), 
		linear-gradient(#5e3e67, #fcffc5, #ffc759, #ff8f5a, #902d59);
	background-size: calc(var(--i)*100%), 100%;
	transition: inherit
}

.col, .info {
	font-size: 1.125em;
	font-family: handlee, purisa, segoe script, comic sans ms, cursive;
	text-align: center;
	transition: .3s ease-out;
	transition-property: transform, opacity;
}

.col {
	--sel: 0;
	position: relative;
	
	&::after {
		box-sizing: border-box;
		position: absolute;
		bottom: 100%;
		left: -.25*$rect-d;
		border: solid $text-b transparent;
		width: $rect-d;
		border-radius: 2*$text-b;
		transform-origin: 50% 100%;
		transform: scale(calc(var(--o)*var(--sel)));
		opacity: calc(var(--o)*var(--sel));
		background: 
			linear-gradient($ctrl-c, $ctrl-c) padding-box, 
			conic-gradient(from -45deg at 50% 100%, 
					$ctrl-c 0% 25%, transparent 0) 
				50% 100%/ 50% 50% no-repeat border-box;
		color: black;
		font-size: Max(10px, .75em);
		content: attr(data-text)
	}
	
	&:hover { --sel: 1 }
}

.info {
	position: absolute;
	top: 50%;	left: 100%;
	width: Min($text-w, calc(100vw - #{$rect-d}));
	transform: 
		translate(0, -50%) 
		scale(var(--not-o));
	opacity: var(--not-o);
}
View Compiled
addEventListener('input', e => {
	document.body.style.setProperty('--o', +e.target.value)
}, false)
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.