Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save WangShuXian6/8b9c3ed4e89bbfc44f4f3b67c2f6e8d5 to your computer and use it in GitHub Desktop.
Save WangShuXian6/8b9c3ed4e89bbfc44f4f3b67c2f6e8d5 to your computer and use it in GitHub Desktop.
#codeVember #18/2021: popup menu (click it, you know you want to!)

#codeVember #18/2021: popup menu (click it, you know you want to!)

Inspiration.


Dedicated to the memory of someone dear who passed away in January 2019. Missing you every day.

A Pen by Ana Tudor on CodePen.

License.

- let items = ['create', 'browse', 'settings'];
- let n = items.length;
- let spark = [
- { typ: '🔺', rad: 7, ang: 80 },
- { typ: '🔴', rad: 3, ang: 150 },
- { typ: '🔴', rad: 5, ang: -45 }
- ];
- let m = spark.length;
form(style=`--exp: 0`)
input(type='checkbox' id='m' aria-controls='popup' aria-haspopup='true' aria-expanded='false')
label(for='m'): span menu
nav(style=`--n: ${n}` id='popup')
- for(let i = 0; i < n; i++)
a(href='#' style=`--i: ${i}`) #{items[i]}
- for(let i = 0; i < m; i++)
- let c = spark[i];
i(class=`✨ ${c.typ}` style=`--r: ${c.rad}px; --a: ${c.ang}deg`)
let exp = 0;
addEventListener('change', e => {
let _t = e.target;
if(exp = 1*_t.checked) _t.setAttribute('aria-expanded', true);
_t.parentNode.style.setProperty('--exp', exp);
});
addEventListener('transitionend', e => {
let _t = e.target;
if(_t.tagName.toLowerCase() === 'nav' && !exp) {
_t.parentNode.firstElementChild.setAttribute('aria-expanded', false)
}
});
@use 'sass:math';
$c: #265b63 #f7d15a;
$d: 2em;
$l: 2px;
$a: 90deg;
$e: 4deg;
$t: .3s;
@mixin poly($n: 3) {
$ba: 360deg/$n;
$va: ($n - 2)*180deg/$n;
$dr: $l/math.sin(.5*$va);
$ip: ();
$op: ();
@for $i from 0 through $n {
$ca: $i*$ba;
$cos: math.cos($ca);
$sin: math.sin($ca);
$op: $op, 50%*(1 + $cos) 50%*(1 + $sin);
$ip: $ip, calc(50% + (50% - #{$dr})*#{$cos}) calc(50% - (50% - #{$dr})*#{$sin})
}
clip-path: polygon($op, $ip)
}
body, form, label { display: grid }
body {
overflow: hidden;
margin: 0;
height: 100vh;
background: nth($c, 1)
}
form {
--not-exp: calc(1 - var(--exp));
place-self: end center;
position: relative;
margin: 1em 2em 15vh;
font: 1em/ 2 ubuntu, trebuchet ms, sans-serif;
text-align: center;
text-transform: capitalize;
> * {
grid-area: 1/ 1;
place-self: center
}
}
input, label { cursor: pointer }
input {
z-index: 2;
width: $d; height: $d;
opacity: 0
}
label {
grid-template-columns: $d;
place-content: center;
overflow: hidden;
width: calc(#{$d}*(1 + 1.5*var(--not-exp)));
border-radius: $d;
background: rgba(nth($c, 2), var(--not-exp));
box-shadow: inset 0 0 0 $l nth($c, 2);
color: nth($c, 1);
transition:
width $t .5*$t,
background-color $t calc(var(--not-exp)*#{$t});
&::before, &::after, span {
grid-area: 1/ 1;
place-self: center
}
&::before, &::after {
--i: 0;
z-index: -1;
width: $l; height: .5*$d;
border-radius: $l;
transform: rotate(calc(var(--i)*90deg + var(--exp)*135deg));
background: nth($c, 2);
transition:
transform $t cubic-bezier(.32, -.85, .68, 1.85) calc(var(--exp)*#{$t});
content: ''
}
&::after { --i: 1 }
}
span {
transform: translatey(calc(var(--exp)*1em));
opacity: var(--not-exp);
transition:
transform $t,
opacity $t;
transition-delay: calc(var(--not-exp)*#{$t})
}
nav, .✨ {
--k: var(--vis, 0);
[aria-expanded='true'] ~ & { --vis: 1 }
}
nav {
display: var(--vis, none);
position: absolute;
bottom: calc(100% + .5em); left: 50%;
border-bottom: solid .5em red;
border-image:
conic-gradient(from -.5*$a at 50% 100%,
transparent, nth($c, 2) $e $a - $e, transparent $a) 9;
padding: .0 2em;
transform: translate(-50%);
opacity: var(--exp);
box-shadow: inset 0 0 0 $l nth($c, 2);
background:
linear-gradient(nth($c, 1) .5*$l, transparent 0)
50% #{-.25*$l}/ 80% calc(100%/var(--n)) repeat-y padding-box
nth($c, 2);
transition: $t calc(var(--not-exp)*#{2*$t});
animation: vis calc(var(--vis)*#{$t})
}
@keyframes vis {
0% { opacity: 0; clip-path: inset(100% 0 0) }
100% { opacity: 1; clip-path: inset(0) }
}
a {
--dt: calc((1 - (var(--i) + 1)/var(--n))*#{$t});
display: block;
transform: translatey(calc(var(--not-exp)*37%));
opacity: var(--exp);
color: nth($c, 1);
font-size: .75em;
line-height: 2.75;
text-decoration: none;
transition:
transform $t,
opacity $t;
transition-delay: var(--dt);
animation: mov calc(var(--vis)*#{$t}) var(--dt) backwards
}
@keyframes mov {
0% { transform: translatey(-37%); opacity: 0 }
100% { transform: none; opacity: 1 }
}
.✨ {
z-index: -1;
padding: var(--r);
border-radius: 50%;
animation: exp calc(var(--vis)*1.5*#{$t}) ease-out $t both
}
@keyframes exp {
0% { transform: rotate(var(--a)) translatey(calc(.5*(#{$l} + -1*#{$d}))) scale(0) }
50% { opacity: 1 }
100% { transform: rotate(var(--a)) translatey(-1*$d) scale(1) rotate(1turn); opacity: 0 }
}
.🔴 { box-shadow: inset 0 0 0 $l nth($c, 2) }
.🔺 { background: nth($c, 2); @include poly() }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment