Particles experiments in order to explore several moves only in CSS. Feel free to add your own!
Created
May 23, 2022 09:45
-
-
Save vineeth-pappu/a91aefb5142f2f2db0cc225725d575b0 to your computer and use it in GitHub Desktop.
SCI-FI UI #2 - WAVING SQUARE DROPDOWN
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-var x = 1 | |
-var sqr = 174 | |
mixin option(label) | |
-var x = 1 | |
-var sqr = 174 | |
div(class='option' onclick='getOption(this)') | |
.label= label | |
.sqrs | |
while x <= sqr | |
div(class='sqr sqr-' + x++) | |
#shot | |
.card | |
button#component | |
input(type='checkbox', name='toggle') | |
.select | |
#select.label.placeholder= 'choose a city…' | |
.arrow | |
svg(width='14px', height='28px', viewBox='0 0 14 28', version='1.1', xmlns='http://www.w3.org/2000/svg', xmlns:xlink='http://www.w3.org/1999/xlink') | |
g(id='chevrons') | |
polygon(id='chevron-1', points='0 18 7 24 14 18 14 22 7 28 0 22') | |
polygon(id='chevron-2', points='0 12 7 18 14 12 14 16 7 22 0 16') | |
path(d='M-0,6 L7,0 L14,6 L14,10 L7,16 L0,10 L-0,6 Z M7,4 L2,8 L7,12 L12,8 L7,4 Z', id='losange') | |
.sqrs | |
while x <= sqr | |
div(class='sqr sqr-' + x++) | |
.options | |
+option('gotham city') | |
+option('metropolis') | |
+option('atlantis') | |
.description | |
h1 | |
| waving square dropdown | |
p | |
| Click on the white button to unlock the following options | |
.title | |
.options | |
p | |
| Type of transition | |
// transition controler | |
.btns | |
each val, index in ['row', 'following'] | |
button(id='btn-'+index onclick='setAnim(this)')= val | |
p | |
| Aurelien Grimaud, <a href='https://twitter.com/inVoltag' target='_blank'>@inVoltag</a> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// transition controler | |
function addClass(component, className) { | |
var y = document.querySelector('#component'); | |
y.removeAttribute('class'); | |
y.classList.add(className); | |
}; | |
function setAnim(z) { | |
var btn = document.getElementsByTagName('button') | |
for (i = 1; i < btn.length; i++) { | |
btn[i].classList.remove('active'); | |
} | |
z.classList.toggle('active'); | |
value = z.innerText; | |
addClass('component', value); | |
} | |
// dropdown control | |
var option = document.querySelectorAll('.option'); | |
var select = document.querySelector('#select'); | |
var check = document.querySelector('input'); | |
var card = document.querySelector('.card'); | |
var body = document.querySelector('body'); | |
function getOption(e) { | |
var optVal = e.innerText; | |
// toggle button | |
if (e.classList.contains('active')) { | |
check.checked = false; | |
e.classList.remove('active'); | |
select.innerText = "choose a city…"; | |
select.style.color = 'rgba(17, 17, 17, .5)'; | |
} else { | |
for (i = 0; i < option.length; i++) { | |
var x = option[i].classList; | |
x.remove('active'); | |
x.add('inverted'); | |
}; | |
check.checked = false; | |
e.classList.add('active'); | |
select.innerText = optVal; | |
select.style.color = 'rgba(17, 17, 17, .75)'; | |
}; | |
// back to the default start point after ending transition | |
setTimeout(function() { | |
for (i = 0; i < option.length; i++) { | |
var x = option[i].classList; | |
x.remove('inverted'); | |
} | |
}, 500) | |
}; | |
// close options when clicked outside | |
document.addEventListener('click', function(evt) { | |
var tgt = evt.target; | |
if (tgt == card || tgt == body) { | |
check.checked = false; | |
} | |
}); | |
// first transition by default | |
var btn = document.querySelectorAll('button'); | |
btn[1].classList.add('active'); | |
value = btn[1].innerText; | |
addClass('component', value); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// colors | |
$onyx: #111; | |
$white: #fff; | |
$ketchup-mayo: #f5d546; | |
$leather: #4f4c4d; | |
$light-azur: #C7E3F9; | |
$tomato: #d64444; | |
// squares | |
$sqr: 174; | |
$row: 29; | |
$line: 6; | |
// speed | |
$speed: 300ms; | |
$delay: 100ms; | |
// options | |
$option: 3; | |
button#component { | |
width: 290px; | |
height: 60px; | |
border: none; | |
display: flex; | |
background: transparent; | |
margin: auto; | |
padding: 0; | |
position: relative; | |
flex-wrap: wrap; | |
font-family: 'Barlow', sans-serif; | |
transform: translateY(-90px); | |
&:focus { | |
outline: none | |
} | |
.sqrs { | |
width: 100%; | |
height: 100%; | |
position: absolute; | |
display: flex; | |
flex-wrap: wrap; | |
z-index: -1; | |
.sqr { | |
width: 10px; | |
height: 10px; | |
background-color: $white; | |
transform-origin: 50% 50%; | |
transition-property: all; | |
transition-timing-function: ease-out; | |
transition-duration: $speed; | |
} | |
} | |
input[type=checkbox] { | |
position: absolute; | |
width: 100%; | |
height: 100%; | |
margin: 0; | |
-webkit-appearance: unset; | |
z-index: 10; | |
outline: 0; | |
top: 0; | |
cursor: pointer; | |
// expand and collapse only in CSS | |
&:checked~.select { | |
background: $ketchup-mayo; | |
svg { | |
#losange { | |
transform: translateY(12px) | |
} | |
#chevrons { | |
transform: rotateX(180deg); | |
transform-origin: 0 14px; | |
} | |
} | |
} | |
&:checked~.options { | |
.option { | |
transform: translateX(0); | |
transform: translateY(0); | |
opacity: 1; | |
pointer-events: all; | |
& .sqrs .sqr { | |
transform: scale(1); | |
} | |
} | |
} | |
} | |
.select, .options { | |
width: 100%; | |
height: 100%; | |
display: flex; | |
position: absolute; | |
top: 0; | |
left: 0; | |
z-index: 9; | |
.label { | |
font-weight: 600; | |
font-size: 18px; | |
text-align: center; | |
letter-spacing: 4px; | |
text-transform: uppercase; | |
margin: auto; | |
transition: $speed ease-out all; | |
&.placeholder { | |
color: rgba($onyx, .5) | |
} | |
} | |
.arrow { | |
flex: 0 1 60px; | |
display: flex; | |
svg { | |
margin: auto; | |
fill: rgba($onyx, .5); | |
overflow: visible; | |
& * { | |
transition: 200ms ease-out all; | |
} | |
} | |
} | |
} | |
.options { | |
top: 60px; | |
z-index: 8; | |
height: auto; | |
.option { | |
width: 100%; | |
height: 60px; | |
display: flex; | |
align-items: center; | |
opacity: 0; | |
pointer-events: none; | |
cursor: pointer; | |
transition-duration: $speed; | |
transition-timing-function: ease; | |
transition-property: all; | |
// feedback when an option is selected | |
&.active { | |
$k: 3; | |
@while $k <= $sqr { | |
& .sqr-#{$k} { background: $ketchup-mayo } | |
$k: $k + $row; | |
} | |
.label { | |
transform: translateX(10px); | |
} | |
} | |
// dephasing each option | |
@for $i from 1 through $option { | |
$k: $i - 1; | |
&:nth-child(#{$i}) { | |
transition-delay: $k * $delay; | |
} | |
} | |
.label{ | |
padding: 0 0 0 30px; | |
color: $white; | |
text-align: left; | |
margin: 0; | |
flex: 1; | |
} | |
.sqr { | |
background: rgba($white, .2); | |
transform: scale(0); | |
// yellow padding-left | |
$i: 1; | |
$j: 2; | |
@while $i <= $sqr { | |
&.sqr-#{$i} { background: $ketchup-mayo } | |
$i: $i + $row; | |
@while $j <= $sqr { | |
&.sqr-#{$j} { background: $ketchup-mayo } | |
$j: $j + $row; | |
} | |
} | |
} | |
} | |
} | |
} | |
// row transition with inverted style when an option has been choosen | |
@for $i from 0 through $row { | |
@for $j from 1 through $option { | |
$k: $j - 1; | |
$r: $sqr + $i; | |
@while $r > 0 { | |
#component.row .option:nth-child(#{$j}) .sqr-#{$r} { | |
transition-delay: ($k * $delay) + (5ms * $i) | |
} | |
$r: $r - $row | |
} | |
} | |
} | |
#component.row .option { | |
transform: translateX(-50px); | |
&.inverted { | |
transform: translateX(50px); | |
} | |
} | |
// following transition with inverted style when an option has been choosen | |
@for $i from 1 through $sqr { | |
@for $j from 1 through $option { | |
$k: $j - 1; | |
button#component.following .option:nth-child(#{$j}) .sqr-#{$i} { | |
transition-delay: ($k * $delay) + (1ms * $i) | |
} | |
// inverted animation | |
button#component.following .option:nth-child(#{$j}).inverted .sqr-#{$i} { | |
$i: $sqr - $i + 1; | |
$k: $option - $j; | |
transition-delay: ($k * $delay) + (1ms * $i) | |
} | |
button#component.following .option:nth-child(#{$j}).inverted { | |
$k: $option - $j; | |
transition-delay: $delay * $k; | |
} | |
} | |
} | |
#component.following .option { | |
transform: translateY(-25px); | |
} | |
// template style, the least interesting | |
$duration: 400ms; | |
$shift: 200ms; | |
$start: 800ms; | |
body { | |
background: lighten($onyx, 5%) url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAG0lEQVQYV2P8//+/FCMj4zMGJMCIzIGxKRQEAJgPBAbJqUVTAAAAAElFTkSuQmCC) repeat; | |
display: flex; | |
height: 100vh; | |
font-family: 'Barlow', sans-serif; | |
font-size: 14px; | |
font-weight: 500; | |
color: $white; | |
margin: 0; | |
padding: 0; | |
} | |
h1 { | |
background-color: $ketchup-mayo; | |
padding: 0 5px 3px 5px; | |
color: lighten($onyx,.1); | |
letter-spacing: 1px; | |
text-transform: uppercase; | |
font-size: 32px; | |
letter-spacing: 2px; | |
margin: 20px 0 10px; | |
border: 1px $ketchup-mayo solid; | |
border-radius: 5px; | |
} | |
h1, p { | |
font-weight: 500; | |
} | |
p { | |
opacity: .3; | |
margin: 0 0 10px 0; | |
letter-spacing: 1px; | |
} | |
a { | |
color: $ketchup-mayo; | |
&:hover { | |
background: $ketchup-mayo; | |
color: $onyx; | |
text-decoration: none; | |
} | |
} | |
#shot { | |
width: 400px; | |
margin: auto; | |
position: relative; | |
.card { | |
width: 100%; | |
height: 300px; | |
display: flex; | |
background: linear-gradient(0deg, rgba($ketchup-mayo, .1) 0%, rgba($onyx, 0) 100%); | |
border: 1px $ketchup-mayo solid; | |
border-radius: 5px; | |
animation: entrance $duration $start linear backwards 1; | |
#component { | |
margin: auto | |
} | |
} | |
.description { | |
animation: entrance $duration ($start + $shift) linear backwards 1; | |
} | |
.title { | |
height: 100%; | |
width: 5px; | |
position: absolute; | |
top: 0; | |
left: -50px; | |
background: $ketchup-mayo; | |
animation: entrance $duration ($start + $shift * 2) linear backwards 1; | |
&::before { | |
@extend p; | |
content: 'sci-fi ui #2'; | |
text-transform: uppercase; | |
text-align: right; | |
position: absolute; | |
left: -92px; | |
top: -17px; | |
transform-origin: 100% 100%; | |
transform: rotateZ(-90deg); | |
} | |
} | |
.options { | |
width: 200px; | |
height: auto; | |
display: flex; | |
flex-wrap: wrap; | |
position: absolute; | |
top: 0; | |
right: -220px; | |
animation: entrance $duration ($start + $shift * 3) linear backwards 1; | |
button { | |
height: 40px; | |
padding: 0 10px; | |
margin: 0 10px 15px 0; | |
border: 2px $onyx solid; | |
outline: 1px $ketchup-mayo solid; | |
background-color: transparent; | |
font-size: 14px; | |
letter-spacing: 1px; | |
color: $white; | |
cursor: pointer; | |
transition: 300ms all ease-out; | |
&:hover, &:focus, &.active { | |
background-color: rgba($ketchup-mayo,.5); | |
} | |
&.active { | |
border: 2px $ketchup-mayo solid; | |
background-color: rgba($ketchup-mayo,1); | |
color: lighten($onyx,.1) | |
} | |
} | |
} | |
} | |
// entrance animation | |
@-webkit-keyframes entrance { | |
to, 20%, 40%, 60%, 80% { opacity: 1 } | |
from, 10%, 30%, 50%, 70%, 90% { opacity: 0 } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment