When you click the Services
menu item, everything works properly, but the parent's scrollbar is showing on top of the child's scrollbar. I'm still able to scroll properly inside of the child menu, however that's not emulated with the visible scrollbar.
When I remove overflow: auto;
from the .sidebar
container, the child menu scroll works properly, but the parent menu's does not.
How can I make sure the visible scrollbar is for the menu that is active?
( function( $ ) {
var sidebar = $( '.sidebar' );
var menu = sidebar.find( '> ul, > div > ul' );
// submenus
( function() {
if ( ! sidebar.length || ! menu.children().length || ! menu.length ) {
return;
}
var hasChildren = menu.find( '.has-children > a' );
var goBack = menu.find( '.go-back' );
var toggleSub = function( e ) {
e.preventDefault();
var _this;
if ( ! $( e.target ).closest( '.go-back' ).length ) {
_this = $( this );
} else {
_this = $( this ).closest( '.sub-menu' ).prev();
}
_this.find( '~ .sub-menu' ).toggleClass( 'active' );
_this.closest( 'ul' ).toggleClass( 'slide-out' );
};
hasChildren.on( 'click', toggleSub );
goBack.on( 'click', toggleSub );
} ) ();
} ) ( jQuery );
html, body {
height: 100%;
background: #f5f5f5;
font-family: Arial, Helvetica, Helvetica Neue, sans-serif;
}
.sidebar {
position: fixed;
top: 0;
left: 0;
width: 280px;
height: 100%;
background: #fe6570;
box-shadow: 2px 0px 4px 0px rgba(50,50,50,0.5);
overflow: auto;
}
.sidebar ul li a {
display: block;
padding: 0 1rem;
color: rgba(255, 255, 255, 0.8);
line-height: 3.5rem;
text-transform: capitalize;
text-decoration: none;
border-bottom: 1px solid rgba(230, 230, 230, 0.2);
transition: transform 0.3s ease-in-out;
}
.sidebar ul .has-children > a {
position: relative;
}
.sidebar ul .has-children > a:after,
.sidebar .go-back > a:before {
content: '›';
position: absolute;
font-size: 1.5rem;
right: 1rem;
}
.sidebar .go-back > a:before {
content: '‹';
position: relative;
right: initial;
left: 0;
margin-right: 10px;
}
.sidebar .sub-menu {
position: fixed;
z-index: 1;
top: 0;
left: 0;
height: 100%;
width: 280px;
background: #fe8065;
transition: transform 0.3s ease-in-out;
transform: translateX(-100%);
}
.sidebar ul {
overflow-y: auto;
list-style: none;
padding: 0;
}
.sidebar .sub-menu.active {
transform: translateX(0);
}
.sidebar .slide-out > li > a {
transform: translateX(100%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="sidebar">
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About Us</a></li>
<li class="has-children">
<a href="#">Services</a>
<ul class="sub-menu">
<li class="go-back"><a href="#">Services</a></li>
<li><a href="#">Consultations</a></li>
<li><a href="#">Design & Planning</a></li>
<li><a href="#">Service Item 1</a></li>
<li><a href="#">Service Item 2</a></li>
<li><a href="#">Service Item 3</a></li>
</ul>
</li>
<li><a href="#">Photo Gallery</a></li>
<li><a href="#">Resources</a></li>
<li><a href="#">Find a Location</a></li>
<li><a href="#">Contact Us</a></li>
</ul>
</div>
Simple, change the .sidebar
element from overflow: auto;
to overflow: hidden
when the Services submenu is opened, like this:
( function( $ ) {
var sidebar = $( '.sidebar' );
var menu = sidebar.find( '> ul, > div > ul' );
// submenus
( function() {
if ( ! sidebar.length || ! menu.children().length || ! menu.length ) {
return;
}
var hasChildren = menu.find( '.has-children > a' );
var goBack = menu.find( '.go-back' );
var toggleSub = function( e ) {
e.preventDefault();
var _this;
if ( ! $( e.target ).closest( '.go-back' ).length ) {
_this = $( this );
} else {
_this = $( this ).closest( '.sub-menu' ).prev();
}
_this.find( '~ .sub-menu' ).toggleClass( 'active' );
_this.closest( '.sidebar' ).toggleClass( 'overflow-off' );
_this.closest( 'ul' ).toggleClass( 'slide-out' );
};
hasChildren.on( 'click', toggleSub );
goBack.on( 'click', toggleSub );
} ) ();
} ) ( jQuery );
html, body {
height: 100%;
background: #f5f5f5;
font-family: Arial, Helvetica, Helvetica Neue, sans-serif;
}
.sidebar {
position: fixed;
top: 0;
left: 0;
width: 280px;
height: 100%;
background: #fe6570;
box-shadow: 2px 0px 4px 0px rgba(50,50,50,0.5);
overflow: auto;
}
.overflow-off {
overflow: hidden;
}
.sidebar ul li a {
display: block;
padding: 0 1rem;
color: rgba(255, 255, 255, 0.8);
line-height: 3.5rem;
text-transform: capitalize;
text-decoration: none;
border-bottom: 1px solid rgba(230, 230, 230, 0.2);
transition: transform 0.3s ease-in-out;
}
.sidebar ul .has-children > a {
position: relative;
}
.sidebar ul .has-children > a:after,
.sidebar .go-back > a:before {
content: '›';
position: absolute;
font-size: 1.5rem;
right: 1rem;
}
.sidebar .go-back > a:before {
content: '‹';
position: relative;
right: initial;
left: 0;
margin-right: 10px;
}
.sidebar .sub-menu {
position: fixed;
z-index: 1;
top: 0;
left: 0;
height: 100%;
width: 280px;
background: #fe8065;
transition: transform 0.3s ease-in-out;
transform: translateX(-100%);
}
.sidebar ul {
overflow-y: auto;
}
.sidebar .sub-menu.active {
transform: translateX(0);
}
.sidebar .slide-out > li > a {
transform: translateX(100%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="sidebar">
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About Us</a></li>
<li class="has-children">
<a href="#">Services</a>
<ul class="sub-menu">
<li class="go-back"><a href="#">Services</a></li>
<li><a href="#">Consultations</a></li>
<li><a href="#">Design & Planning</a></li>
<li><a href="#">Service Item 1</a></li>
<li><a href="#">Service Item 2</a></li>
<li><a href="#">Service Item 3</a></li>
<li><a href="#">Service Item 4</a></li>
<li><a href="#">Service Item 5</a></li>
</ul>
</li>
<li><a href="#">Photo Gallery</a></li>
<li><a href="#">Resources</a></li>
<li><a href="#">Find a Location</a></li>
<li><a href="#">Contact Us</a></li>
</ul>
</div>
A few ways to accomplish this, in the example above I've added
_this.closest( '.sidebar' ).toggleClass( 'overflow-off' );
to the toggleSub
function, with the overflow-off
class being:
.overflow-off {
overflow: hidden;
}