- let ratios = [ '1/ 3', '1/ 2', '9/ 16', '3/ 5', '2/ 3', '3/ 4', '4/ 5', '1/ 1', '5/ 4', '4/ 3', '3/ 2', '5/ 3',  '16/ 10', '16/ 9', '1.85/ 1', '2/ 1', '2.35/ 1', '3/ 1', '4/ 1' ];
- let n = ratios.length;
- let ratio = '1/ 1';
- let val = Math.max(0, ratios.indexOf(ratio));

- let palettes = [
- 	'#ffb528, #ff8c40, #f86759, #e14b71, #bb3e85, #883d90', 
- 	'#95ffdc, #47fff1, #00e1fa, #00c1f6, #419fe3, #717dbf', 
- 	'#b5ce4f, #eed54e, #fbb64b, #ff9854, #fc7c64, #eb6575', 
- 	'#885789, #cf6c84, #f7966f, #f6d169, #8bbd69, #139d7f', 
- 	'#00aab7, #2889ac, #48678f, #8478ac, #c486b8, #fd98b3', 
- 	'#ffca81, #f29e85, #cc7d8e, #94688c, #595678, #4c7ba3', 
- 	'#f9ffce, #e7cab2, #b8a09f, #91ffe2, #00edff, #00b3ff', 
- 	'#92ffe1, #00ecff, #5baeff, #fdffcd, #ff82a3, #a06eb2'
- ];
- let m = palettes.length;
- let u = palettes[0].split(', ')
- let p = u.length, q = Math.ceil(.5*p);
- let e = .5;

body(style=`--ratio: ${ratio}; --val: ${val}`)
	style
		| .card {
		| 	--sl0: #{u.slice(0, q).map((c, i) => `var(--c${q - i - 1}) 0% ${(i + 1)*45/q}deg`)};
		| 	--sl1: #{u.slice(q).map((c, i) => `var(--c${q + i}) 0% ${(i + 1)*45/q}deg`)}
		| }
	form(style=`--max: ${n - 1}`)
		label(for='val') Control card aspect ratio
		input#val(type='range' value=val max=n - 1 list='l')
		output(for='val') #{ratio}
		datalist#l
			- for(let i = 0; i < n; i++)
				option(value=i label=ratios[i] style=`--idx: ${i}`)
	section
		- for(let i = 0; i < m; i++)
			.card(style=`${palettes[i].split(', ').map((c, j) => `--c${j}: ${c}`).join('; ')}`)
View Compiled
$g: #000 #1b1d22 #22242a #323741 #484d5a #7b849c #c4c4c4 #fff;
$c: #bf79f0 #fb678c #fb8c6c #eaa753;
$u: 1.25;
$t: .3s;

$label-w: 24ch;

$value-w: 9ch;
$value-b: 1ch;
$value-r: 5px;
$value-a: 70deg;
$value-e: 5deg;

$thumb-d: 2ch;
$thumb-r: .5*$thumb-d;
$thumb-f: .5;
$thumb-l: 3px;

$track-s: .5*$value-w - $thumb-r;
$track-h: 6px;
$track-r: .5*$track-h;

$ruler-h: .375em;

$card-r: .25em;

@mixin track() {
	border: none;
	width: 100%; height: $track-h;
	border-radius: $track-h;
	background: 
		radial-gradient(circle at var(--pos), 
			transparent calc(#{$thumb-f}*#{$thumb-r} + #{$thumb-l}), 
			nth($g, 5) calc(#{$thumb-f}*#{$thumb-r} + #{$thumb-l} + 1px))
}

@mixin thumb($f: 0) {
	margin-top: calc(#{$f}*(#{$track-r} - #{$thumb-r}));
	border: none;
	width: $thumb-d; height: $thumb-d;
	border-radius: 50%;
	transform: scale(calc(var(--not-hl)*#{$thumb-f} + var(--hl)));
	background: nth($c, 4);
	transition: transform $t;
	cursor: ew-resize
}

* { box-sizing: inherit; margin: 0; border: none; padding: 0; background: transparent; color: inherit; font: inherit }

html {
	overflow-x: hidden;
	background: nth($g, 3);
	color: nth($g, 6);
	font: clamp(.625em, 6.25vw, #{$u*1em}) 
		ubuntu mono, consolas, monaco, monospace;
}

body, form, section, datalist, option, div { display: grid }

body {
	box-sizing: border-box;
	grid-gap: .5*$track-s;
	padding: .5*$track-s
}

form, section { max-width: 100% }

form {
	--i: var(--narr, 1);
	--not-i: calc(1 - var(--i));
	--j: var(--wide, 0);
	--not-j: calc(1 - var(--j));
	--hl: 0;
	--not-hl: calc(1 - var(--hl));
	--pos: calc(#{$thumb-r} + var(--val)/var(--max)*(100% - #{$thumb-d}));
	--col: calc(100% + var(--j)*#{-1*$label-w} + var(--not-i)*#{-1*$value-w});
	overflow-x: hidden;
	padding: .5*$track-s $track-s;
	border-radius: $card-r;
	grid-template-columns: 
		calc(var(--j)*#{$label-w}) var(--col) calc(var(--not-i)*#{$value-w});
	box-shadow: 0 0 1px 1px nth($g, 5);
	background: nth($g, 2);
	filter: Saturate(var(--hl));
	
	&:focus-within { --hl: 1 }
	
	@media (min-width: 1005px) { --narr: 0 }
	@media (min-width: 1600px) { --wide: 1 }
}

label {
	align-self: center;
	grid-column: 1/ calc(2 + var(--not-j));
	font: 1rem / 1.25 raleway, 
		trebuchet ms, verdana, arial, sans-serif
}

input, output {
	grid-row: calc(1 + var(--not-j))
}

input {
	&, &::-webkit-slider-runnable-track, 
	&::-webkit-slider-thumb { -webkit-appearance: none }
	
	grid-column: 2;
	padding: $ruler-h 0;
	background: 
		repeating-linear-gradient(90deg, 
				nth($g, 5) 0 2px, 
				transparent 0 calc((100% - #{$thumb-d})/var(--max))) 
		calc(#{$thumb-r} - 1px) 100%/ 100% #{$ruler-h} no-repeat;
	
	&:focus { outline: none }
	
	&::-webkit-slider-runnable-track { @include track }
  &::-moz-range-track { @include track }
	
	&::-webkit-slider-thumb { @include thumb(1) }
  &::-moz-range-thumb { @include thumb }
}

output {
	--xy: calc(var(--i)*50%) calc((1 + var(--i))*50%);
	grid-column: calc(2 + var(--not-i));
	place-self: center start;
	position: relative;
	left: calc(var(--i)*var(--pos));
	border: solid $value-b transparent;
	padding: .25em 0;
	width: $value-w;
	border-radius: calc(#{$value-b} + #{$value-r});
	transform: 
		translate(calc(var(--i)*-50%), calc(var(--i)*(-50% - #{$thumb-r}))) 
			scale(calc(var(--not-i) + var(--i)*var(--hl)));
	background: nth($c, 4) padding-box;
	color: nth($g, 2);
	text-align: center;
	transition: transform $t;
	
	&::before {
		position: absolute;
		top: -$value-b; right: -$value-b; bottom: -$value-b; left: -$value-b;
		z-index: -1;
		background: 
				conic-gradient(
						from calc((1 - var(--i))*90deg - .5*#{$value-a}) 
						at var(--xy), 
						transparent, 
						nth($c, 4) $value-e $value-a - $value-e, 
						transparent  $value-a) 
					var(--xy)/ 50% 50% no-repeat;
		content: ''
	}
}

output, datalist { word-spacing: -1ch }

datalist {
	--ruler-w: calc((var(--max) + 1)*(100% - #{$thumb-d})/var(--max));
	grid-area: calc(2 + var(--not-j))/ 2;
	grid-template-columns: repeat(calc(var(--max) + 1), calc(100%/(var(--max) + 1)));
	place-self: center;
	width: var(--ruler-w)
}

option {
	place-content: center;
	place-self: center;
	
	@media (max-width: 1250px) { font-size: .8em }
	@media (max-width: 900px) and (min-width: 641px) {
		&:not(:nth-child(2n + 1)) { transform: scale(0) }
	}
	@media (max-width: 640px) {
		&:not(:nth-child(3n + 1)) { transform: scale(0) }
	}
}

section {
	grid-gap: $card-r;
	grid-template-columns: repeat(auto-fit, Min(100%, calc(5em*(1 + var(--ratio)))));
	place-content: center
}

.card {
	aspect-ratio: var(--ratio);
	position: relative;
	color: nth($g, 8);
	font: 600 1.5em parisienne, z003, segoe script, comic sans ms, cursive;
	text-align: center;
	text-shadow: 1px 1px 1px nth($g, 2);
	
	&::before {
		position: absolute;
		z-index: -1;
		padding: 50%;
		border-radius: #{$card-r}/ calc(#{$card-r}*(var(--ratio)));
		transform-origin: 50% 0;
		transform: scaley(calc(1/(var(--ratio))));
		background: 
			conic-gradient(from 45deg at 0 100%, 
					var(--sl0), transparent 0%), 
			conic-gradient(from 225deg at 100% 0, 
					var(--sl1), transparent 0%) 
			var(--c0);
		content: ''
	}
	
	&::after {
		display: grid;
		place-content: center;
		padding: $card-r;
		border-radius: $card-r;
		background: rgba(nth($g, 6), .1);
		backdrop-filter: blur(1px);
		content: 'Hello, Gorgeous!'
	}
}
View Compiled
addEventListener('input', e => {
	let _t = e.target, 
			val = +_t.value, 
			ratio = document.querySelector(`option[value='${val}']`).label;
	
	document.body.style.setProperty('--val', val);
	document.body.style.setProperty('--ratio', _t.nextElementSibling.textContent = ratio)
})
/*
Context: created for my Variable Aspect Ratio Card With Conic Gradients Meeting Along the Diagonal (https://css-tricks.com/variable-aspect-ratio-card-with-conic-gradients-meeting-along-the-diagonal/) article on CSS-Tricks.
*/
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.