Skip to content

Instantly share code, notes, and snippets.

@w3tweaks
Created June 26, 2020 01:26
Show Gist options
  • Save w3tweaks/bd56172de3e1e14e53babc0cc04bf808 to your computer and use it in GitHub Desktop.
Save w3tweaks/bd56172de3e1e14e53babc0cc04bf808 to your computer and use it in GitHub Desktop.
Stripe.com Style Dropdown Menu
header.main-header
ul.menu
li.menu__item(data-sub="product"): a(href="#") Product
li.menu__item(data-sub="developer"): a(href="#") Developer
li.menu__item(data-sub="company"): a(href="#") Company
.dropdown-holder
.dropdown__arrow
.dropdown__bg
.dropdown__bg-bottom
.dropdown__wrap
.dropdown-menu#product(data-sub="product")
.dropdown-menu__content
.top-section
.col-2
ul
li
a(href="")
h3 Payment
p Lorem ipsum dolor sit amet, consectetur adipisicing elit.
li
a(href="")
h3 Connect
p consectetur adipisicing elit nesciunt! Assumenda, adipisci.
li
a(href="")
h3 Atlas
p ipsum dolor sit amet, consectetur adipisicing elit. .
ul
li
a(href="")
h3 Subscription
p Lorem ipsum dolor sit amet, consectetur
li
a(href="")
h3 Relay
p amet, consectetur adipisicing elit. Nisi, sequi!
.bottom-section
ul
li: a(href="") Payment
li: a(href="") Connect
li: a(href="") Atlas
li: a(href="") Connect
li: a(href="") Atlas
.dropdown-menu#developer(data-sub="developer")
.dropdown-menu__content
.top-section
.col-2
div
h2.menu-title Front End
ul
li: a(href="") Payment
li: a(href="") Connect
li: a(href="") Atlas
div
h2.menu-title Back End
ul
li: a(href="") Payment
li: a(href="") Connect
li: a(href="") Atlas
.bottom-section.info
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit totam officia molestias
.dropdown-menu(data-sub="company")
.dropdown-menu__content
.top-section
ul
li: a(href="") Payment
li: a(href="") Connect
li: a(href="") Atlas
.bottom-section
ul
li: a(href="") Payment
li: a(href="") Connect
li: a(href="") Atlas
var menuItems = [].slice.call( document.querySelectorAll( '.menu__item' ) ),
menuSubs = [].slice.call( document.querySelectorAll( '.dropdown-menu') ),
selectedMenu = undefined,
subBg = document.querySelector( '.dropdown__bg' ),
subBgBtm = document.querySelector( '.dropdown__bg-bottom' ),
subArr = document.querySelector( '.dropdown__arrow' ),
subCnt = document.querySelector( '.dropdown__wrap' ),
header = document.querySelector( '.main-header' ),
closeDropdownTimeout,
startCloseTimeout = function (){
closeDropdownTimeout = setTimeout( () => closeDropdown() , 50 );
},
stopCloseTimeout = function () {
clearTimeout( closeDropdownTimeout );
},
openDropdown = function (el) {
//- get menu ID
var menuId = el.getAttribute( 'data-sub' );
//- get related sub menu
var menuSub = document.querySelector( '.dropdown-menu[data-sub="'+menuId+'"]' );
//- get menu sub content
var menuSubCnt = menuSub.querySelector( '.dropdown-menu__content' )
//- get bottom section of current sub
var menuSubBtm = menuSubCnt.querySelector('.bottom-section').getBoundingClientRect();
//- get height of top section
var menuSubTop = menuSubCnt.querySelector('.top-section').getBoundingClientRect();
//- get menu position
var menuMeta = el.getBoundingClientRect();
//- get sub menu position
var subMeta = menuSubCnt.getBoundingClientRect();
//- set selected menu
selectedMenu = menuId;
//- Remove active Menu
menuItems.forEach( el => el.classList.remove( 'active' ) );
//- Set current menu to active
el.classList.add( 'active' );
//- Remove active sub menu
menuSubs.forEach( el => el.classList.remove( 'active' ) );
//- Set current menu to active
menuSub.classList.add( 'active' );
//- Set dropdown menu background style to match current submenu style
subBg.style.opacity = 1;
subBg.style.left = menuMeta.left - ( (subMeta.width / 2) - menuMeta.width / 2 ) + 'px';
subBg.style.width = subMeta.width+'px';
subBg.style.height = subMeta.height+'px';
//- Set dropdown menu bottom section background position
subBgBtm.style.top = menuSubTop.height+'px';
console.log( menuSubBtm );
//- Set Arrow position
subArr.style.opacity = 1;
subArr.style.left = menuMeta.left + menuMeta.width/2 - 10 + 'px';
//- Set sub menu style
subCnt.style.opacity = 1;
subCnt.style.left = menuMeta.left - ( (subMeta.width / 2) - menuMeta.width / 2 ) + 'px';
subCnt.style.width = subMeta.width+'px';
subCnt.style.height = subMeta.height+'px';
//- Set current sub menu style
menuSub.style.opacity = 1;
header.classList.add('dropdown-active');
},
closeDropdown = function () {
//- Remove active class from all menu items
menuItems.forEach( el => el.classList.remove('active') );
//- Remove active class from all sub menus
menuSubs.forEach ( el => {
el.classList.remove( 'active' );
el.style.opacity = 0;
} );
//- set sub menu background opacity
subBg.style.opacity = 0;
//- set arrow opacity
subArr.style.opacity = 0;
// unset selected menu
selectedMenu = undefined;
header.classList.remove('dropdown-active');
};
//- Binding mouse event to each menu items
menuItems.forEach( el => {
//- mouse enter event
el.addEventListener( 'mouseenter', function() {
stopCloseTimeout();
openDropdown( this );
}, false );
//- mouse leave event
el.addEventListener( 'mouseleave', () => startCloseTimeout(), false);
} );
//- Binding mouse event to each sub menus
menuSubs.forEach( el => {
el.addEventListener( 'mouseenter', () => stopCloseTimeout(), false );
el.addEventListener( 'mouseleave', () => startCloseTimeout(), false );
} );

Stripe.com Style Dropdown Menu

Recently Stripe.com Redesign it site, and the primary menu interaction really grab my attention. So here is the simple version of it. Hope you love it guys :)

A Pen by Rian Ariona on CodePen.

License.

@import 'https://fonts.googleapis.com/css?family=Karla';
*{
box-sizing: border-box;
}
body{
min-height: 100vh;
background: linear-gradient(15deg, #25ddf5, #53f);
font-family: karla;
color: #666;
font-size: 18px;
-webkit-font-smoothing: antialiased;
}
h1,h2,h3,h4,h5,h6{
color: #444;
}
header{
position: relative;
padding: 20px 0 0;
transform-style: preserve3d;
perspective: 3000px;
}
.menu{
list-style: none;
margin: 0;
padding-left: 0;
display: flex;
justify-content: center;
a{
padding: 20px 20px;
display: block;
text-decoration: none;
color: white;
}
&__item{
position: relative;
&:hover > .sub-menu-shadow{
display: block;
}
}
.sub-menu-shadow{
position: absolute;
display: none;
}
}
.dropdown{
&-holder{
position: absolute;
width: 100%;
left: 0;
top: 100%;
}
&__bg, &__arrow{
position: absolute;
}
&__arrow{
width: 0;
height: 0;
border-width: 10px;
border-style: solid;
border-color: transparent transparent white;
top: -20px;
opacity: 0;
transition: .20s ease;
pointer-events: none;
}
&__bg{
width: 450px;
height: 400px;
background-color: white;
opacity: 0;
transition: .25s ease;
border-radius: 5px;
overflow: hidden;
z-index: -1;
&-bottom{
background-color: #fafafa;
position: absolute;
width: 100%;
left: 0;
top: 300px;
height: 700px;
transition: .3s ease;
}
}
&__wrap{
overflow: hidden;
position: absolute;
transition: .25s ease;
z-index: 1;
.top-section,.bottom-section{
padding: 20px;
}
}
&-menu{
&__content{
position: absolute;
opacity: 0;
transition: .25s ease;
min-width: 200px;
ul{
list-style: none;
padding-left: 0;
margin: 0;
}
a{
color: inherit;
text-decoration: none;
display: block;
padding: 5px 0;
&:hover{ color: #333 }
}
}
&.active{
.dropdown-menu__content{
opacity: 1;
}
}
}
}
#product .dropdown-menu__content{
width: 640px;
}
#developer .dropdown-menu__content{
width: 400px;
}
.col-2{
display: flex;
>ul,>div{
flex: 1 0 150px;
}
}
#product{
.col-2{
li{
display: block;
padding: 20px 20px 10px;
h3{
font-size: 18px;
margin: 0 0 10px;
color: turquoise;
}
p{
color: #999;
margin: 0;
}
}
}
}
.menu-title{
margin: 0 0 10px;
font-size: 18px;
color: #2196F3
}
.info{
line-height: 1.7;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment