I have a side navigation I'm building, and it needs to be fully keyboard accessible as well as have the links themselves nested in list items. Everything else works fine, but I've been asked to produce a hover animation which is an animated pseudo element.
I've got most of that done, being the structure of the nav and the animation. However, the animated ::before element always seems to show up at the top of the list item, and will push the anchor down by whatever height I've set. I've tried both height:inherit and 100% for the ::before content, but that doesn't work.
The ideal behavior is that the content would animate in-line with the anchor from the bottom to the top, and simply occupy the height (100%) of the li element with my specified width.
Note: I can't use list-style:none because a screen reader will not identify how many items are in the list.
EDIT: took out the button element. Just focusing on the menu.
Here's a CodePen: https://codepen.io/anon/pen/EZbLMY
Feel free to fork it.
HTML:
<div id="mySidenav" class="sidenav" aria-label="Menu" aria-hidden="true">
<nav>
<ul role="navigation">
<li id="about"><a href="#">About</a></li>
<li id="services"><a href="#">Services</a></li>
<li id="clients"><a href="#">Clients</a></li>
<li id="contact"><a href="#">Contact</a></li>
</ul>
</nav>
</div>
CSS:
/* The side navigation menu */
.sidenav {
height: 100%;
width: 250px;
position: absolute;
z-index: 2;
top: 0;
background-color: #fff;
overflow-x: hidden;
padding-top: 60px;
}
.showOverlay{
display: block !important;
}
/* The navigation menu links */
.sidenav a{
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #000;
display: block;
width: inherit;
}
/*Clean up space between elements*/
.sidenav nav ul{
padding: 0;
margin: 0;
}
.sidenav nav ul li::before{
content:"";
width: 4px;
height: 0px;
display: block;
background-color: #000000;
}
.sidenav nav ul li:hover::before{
height: 20px;
transition: 0.3s ease-out;
padding-left: 2px;
}
Change the position of the ::before
element to absolute
. Also, to line things up neatly, add a position:relative
to the li elements.
/* The side navigation menu */
.sidenav {
height: 100%;
width: 250px;
position: absolute;
z-index: 2;
top: 0;
background-color: #fff;
overflow-x: hidden;
padding-top: 60px;
}
.showOverlay {
display: block !important;
}
/* The navigation menu links */
.sidenav a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #000;
display: block;
width: inherit;
}
/*Clean up space between elements*/
.sidenav nav ul {
padding: 0;
margin: 0;
}
/*Make li elements relative, so that the before elements are positioned correctly*/
.sidenav nav ul li {
position: relative;
}
.sidenav nav ul li::before {
content: "*";
width: 4px;
height: 0px;
display: block;
background-color: #000000;
/*Add absolute positioning*/
position: absolute;
top: 8px;
}
.sidenav nav ul li:hover::before {
height: 20px;
transition: 0.3s ease-out;
padding-left: 2px;
}
<div id="mySidenav" class="sidenav" aria-label="Menu" aria-hidden="true">
<nav>
<ul role="navigation">
<li id="about"><a href="#">About</a></li>
<li id="services"><a href="#">Services</a></li>
<li id="clients"><a href="#">Clients</a></li>
<li id="contact"><a href="#">Contact</a></li>
</ul>
</nav>
</div>