<div class='card' style='--k: 50'>
	<input type='range'/>
</div>
$img: url(https://assets.codepen.io/2017/blend_me_kreator_painless.jpg);
$t: .25s;

$card-0: 8em;
$card-1: 80;
$card-2: 50em;
$card-f: 2;
$card-a: 10deg;

$thumb-w: 5em;
$thumb-r: .5*$thumb-w;
$thumb-l: 2px;
$thumb-c: #fff;

$arrow-s: 37.5%;
$arrow-a: 60deg;

$label-l: 15;
$label-m: .5em;
$label-h: 1.5;

@mixin track() {
	border: none;
	width: 100%; height: 100%;
	background: transparent
}

@mixin thumb() {
	--list: #{$thumb-c} #{$arrow-a}, transparent 0%;
	border: none;
	width: $thumb-w; height: 100%;
	background: 
		conic-gradient(from 90deg - .5*$arrow-a, var(--list)) 
			0/ #{$arrow-s}, 
		conic-gradient(from -90deg - .5*$arrow-a, var(--list)) 
			100%/ #{$arrow-s}, 
		radial-gradient(circle, 
			transparent calc(#{$thumb-r} - #{$thumb-l} - 1px), 
			$thumb-c calc(#{$thumb-r} - #{$thumb-l}) calc(#{$thumb-r} - 1px), 
			transparent $thumb-r), 
		linear-gradient(
			$thumb-c calc(50% - #{$thumb-r} + .5*#{$thumb-l}), 
			transparent 0 calc(50% + #{$thumb-r} - .5*#{$thumb-l}), 
			$thumb-c 0) 50%/ #{$thumb-l};
	background-repeat: no-repeat;
	filter: drop-shadow(2px 2px 3px #000);
	cursor: ns-resize
}

* { margin: 0; font: inherit }

body, div { display: grid }

body {
	overflow-x: hidden;
	height: 100vh;
	perspective: 35em;
	background: #333
}

.card {
	--hl: 0;
	--card-w: clamp(#{$card-0}, calc(#{$card-1}*1vw), #{$card-2});
	--card-h: calc(#{$card-f}*var(--card-w));
	--p: calc(var(--k)*1%);
	--dif-inf: clamp(0, calc(var(--k) - #{$label-l}), 1);
	--dif-sup: clamp(0, calc(100 - #{$label-l} - var(--k)), 1);
	align-content: space-between;
	grid-template: 
		repeat(2, calc(#{$label-h}*1em + 2*#{$label-m}))/ 
		var(--card-w);
	place-self: center;
	overflow: hidden;
	width: var(--card-w); height: var(--card-h);
	border-radius: .5em;
	box-shadow: 4px 4px 23px;
	background: 
		linear-gradient(0deg, transparent var(--p), #fff 0), 
		$img 50%/ cover;
	background-blend-mode: exclusion;
	filter: sepia(calc(1 - var(--hl)));
	transition: $t;
	transition-property: transform, filter;
	
	&::before, &::after {
		--q: 0;
		--not-q: calc(1 - var(--q));
		z-index: 1;
		grid-area: calc(1 + var(--not-q))/ 1;
		justify-self: start;
		margin: $label-m;
		padding: 0 .25em;
		border-radius: .25em;
		opacity: 
			calc(var(--hl)*(var(--not-q)*var(--dif-inf) + 
											var(--q)*var(--dif-sup)));
		background: tomato;
		font: 300 1em/ #{$label-h} lato, sans-serif;
		text-transform: uppercase;
		filter: Invert(var(--q));
		pointer-events: none;
		transition: opacity $t;
		content: 'before'
	}
	
	&::after {
		--q: 1;
		content: 'after'
	}
	
	&:hover, &:focus-within { --hl: 1 }
	
	&:hover {
		transform: 
			rotatex(calc(clamp(-.5, var(--j), .5)*#{$card-a})) 
			rotatey(calc(clamp(-.5, var(--i), .5)*#{-$card-a}));
	}

	@media (min-aspect-ratio: 1/ #{$card-f}) {
		--card-h: clamp(#{$card-0}, calc(#{$card-1}*1vh), #{$card-2});
		--card-w: calc(var(--card-h)/#{$card-f})
	}
}

[type='range'] {
	&, &::-webkit-slider-thumb, 
	&::-webkit-slider-runnable-track { -webkit-appearance: none }
	
	grid-area: 1/ 1/ span 2/ span 1;
	place-self: center;
	width: calc(var(--card-h) + #{$thumb-w}); height: var(--card-w);
	transform: rotate(-90deg);
	background: transparent;
	cursor: pointer;
	
	&::-webkit-slider-runnable-track { @include track }
	&::-moz-range-track { @include track }
	
	&::-webkit-slider-thumb { @include thumb }
	&::-moz-range-thumb { @include thumb }
	
	&:focus { outline: none }
}
View Compiled
/*
Created for 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!
*/

const _CARD = document.querySelector('.card');

let rect;

function setRect() { rect = _CARD.getBoundingClientRect() }

setRect();

addEventListener('input', e => {
	_CARD.style.setProperty('--k', +e.target.value)
}, false);

addEventListener('resize', e => setRect, false);

_CARD.addEventListener('mousemove', e => {
	_CARD.style.setProperty('--i', +((e.clientX - rect.left)/rect.width - .5).toFixed(2));
	_CARD.style.setProperty('--j', +((e.clientY - rect.top)/rect.height - .5).toFixed(2));
}, false);
View Compiled

External CSS

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

External JavaScript

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