- 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
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.