Skip to content

Instantly share code, notes, and snippets.

@asafge
Created March 10, 2020 13:29
Show Gist options
  • Save asafge/86e1f076e4ec5910c16db16f928b2a19 to your computer and use it in GitHub Desktop.
Save asafge/86e1f076e4ec5910c16db16f928b2a19 to your computer and use it in GitHub Desktop.
Infinite Multilevel Dropdown
<ul class="nav site-nav">
<li><a href=#>Lorem</a></li><!--
--><li><a href=#>Ipsum</a></li><!--
--><li class=flyout>
<a href=#>Dolor</a>
<!-- Flyout -->
<ul class="flyout-content nav stacked">
<li><a href=#>Foo Bar</a></li>
<li><a href=#>Bar Baz</a></li>
<li class="flyout-alt">
<a href=#>Baz Foo</a>
<!-- Flyout -->
<ul class="flyout-content nav stacked">
<li><a href=#>Foo Bar</a></li>
<li><a href=#>Bar Baz</a></li>
<li class="flyout-alt">
<a href=#>Baz Foo</a>
<!-- Flyout -->
<ul class="flyout-content nav stacked">
<li class="flyout-alt">
<a href=#>Foo Bar</a>
<!-- Flyout -->
<ul class="flyout-content nav stacked">
<li><a href=#>Bar Baz</a></li>
<li class="flyout-alt">
<a href=#>Baz Foo</a>
<!-- Flyout -->
<ul class="flyout-content nav stacked">
<li><a href=#>Bar Baz</a></li>
<li><a href=#>Baz Foo</a></li>
<li><a href=#>Foo Bar</a></li>
</ul>
</li>
<li><a href=#>Foo Bar</a></li>
</ul>
</li>
<li><a href=#>Bar Baz</a></li>
<li class="flyout-alt">
<a href=#>Baz Foo</a>
<!-- Flyout -->
<ul class="flyout-content nav stacked">
<li><a href=#>Bar Baz</a></li>
<li><a href=#>Baz Foo</a></li>
<li><a href=#>Foo Bar</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li><!--
--><li><a href=#>Sit</a></li><!--
--><li><a href=#>Amet</a></li>
</ul>​
/*------------------------------------*\
$HOUSEKEEPING
\*------------------------------------*/
*{ margin:0; padding:0; }
html{
padding:5%;
font:1em/1.5 Georgia, serif;
overflow-y:scroll;
}
ul{
margin-bottom:1.5em;
margin-left:1.5em;
}
a{
text-decoration:none;
}
/*------------------------------------*\
$NAV
\*------------------------------------*/
/**
* Throw any `ul` or `ol` into horizontal mode, as per csswizardry.com/2011/09/the-nav-abstraction.
<ul class=nav>
<li><a href=/>Home</a></li>
<li><a href=/about>About</a></li>
<li><a href=/portfolio>Portfolio</a></li>
<li><a href=/contact>Contact</a></li>
</ul>
*/
.nav{
list-style:none;
margin-left:0;
}
.nav > li,
.nav > li > a{
display:inline-block;
*display:inline;
zoom:1;
}
/**
* Create a vertically stacked nav by extending `.nav` with `.stacked`.
<ul class="nav stacked">
<li><a href=/>Home</a></li>
<li><a href=/about>About</a></li>
<li><a href=/portfolio>Portfolio</a></li>
<li><a href=/contact>Contact</a></li>
</ul>
*/
.stacked > li{
display:list-item;
}
.stacked > li > a{
display:block;
}
/*------------------------------------*\
$FLYOUT
\*------------------------------------*/
/**
* Flyouts are pieces of content that fly out of a parent when said parent is hovered.
* They typically appear bottom-left of the parent.
<div class=flyout>
Foo
<div class=flyout-content>
<h1>Lorem</h1>
<p>Ipsum</p>
</div>
</div>
*/
.flyout,
.flyout-alt{
position:relative;
}
.flyout-content{
/* Position the flyouts off-screen. This is typically better than `display:none;`. */
position:absolute;
top:100%;
left:-99999px;
/**
* Even though they are out of document flow, lots of nested flyouts can
* eventually force scroll bars to appear as they become taller than the viewport.
* We can undo this effect by giving them zero height.
*/
height:0;
overflow:hidden;
}
/**
* Bring the flyouts into view when you hover their parents.
* Two different types of flyout; ‘regular’ (`.flyout`) and ‘alternative’ (`.flyout-alt`).
*/
/* Regular flyouts sit all the way from the top, flush left. */
.flyout:hover > .flyout-content{
left:0;
}
/* Alternative flyouts sit all the way from the left, flush top. */
.flyout-alt:hover > .flyout-content{
top:0;
left:100%;
}
.flyout:hover > .flyout-content,
.flyout-alt:hover > .flyout-content{
/* Give the flyouts their height back once they come into view. */
height:auto;
overflow:visible;
}
/*------------------------------------*\
$SITE-NAV
\*------------------------------------*/
/**
* Site nav specific styling.
* Extends `.nav{}`
*/
.site-nav{
font-size:0.75em;
font-family:sans-serif;
}
.site-nav a{
line-height:1;
padding:1em;
background-color:#09f;
color:#fff;
white-space:nowrap;
}
/*--- SITE-NAV FLYOUTS ---*/
/**
* Site nav specific flyouts, extension of `.flyout`.
* Set up some styles to apply and persist when we hover things in the site nav.
* This allows us to keep parents highlighted as we hover their contained flyouts [1].
*/
.site-nav .flyout:hover > a /* [1] */,
.site-nav .flyout-alt:hover > a /* [1] */,
.site-nav a:hover{
color:#435704;
background-color:#BADA55;
}
/**
* Add an indicator to any flyout parents in the site nav to show there’s a flyout.
*/
.site-nav .flyout-alt > a:after{
content:" »";
}
/**
* Here we set up a load of shared borders on the site-nav specific flyouts.
* The code looks a little scattered but it allows us to cleverly share declarations:
* We set up a non-existent [1] solid [2] border on all sides of the relevant elements.
* We can now also change the style [2] and colour [3] of all borders in one go.
* Now we have set up border colours and styles, we need to just turn the desired borders ‘on’ [4].
*/
.site-nav a,
.site-nav .flyout-content{
border:0 /* [1] */
solid /* [2] */
#fff /* [3] */;
}
.site-nav > li > a{
border-left-width:1px; /* [4] */
}
/* The first link in the site-nav doesn’t require a border at all. */
.site-nav > li:first-child > a{
border:none;
}
.site-nav .flyout-content{
border-width:1px 0 0 1px; /* [4] */
}
.site-nav .flyout-content a{
border-bottom-width:1px; /* [4] */
}
.site-nav .flyout-alt:hover > .flyout-content{
/**
* To account for the 1px top border on the flyout containers, we need to
* bring the flyouts back up by 1px in this special instance.
*/
top:-1px;
}​
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment