Have you ever used the Slider Revolution WordPress plugin in a project? If the answer is “yes”, you might have noticed the mini toolbar that appears in the right corner of the plugin’s configuration page.
Initially, only the icons are visible, keeping the whole thing nice and compact. Then each time you hover over an icon, its associated text is revealed with a smooth slide-in animation.
In today’s exercise, let’s take inspiration from that effect and build something similar. Here’s what we’ll be working towards:
We’ll go through this pretty quickly, first writing out our markup, styling it with CSS, then finally adding some JavaScript behavior. Before calling it a day, we’ll take a look at a CSS-only approach too. Let’s get started!
1. Begin With the Page Markup
We’ll start with a header which will contain a heading and an unordered list. Each list item will include a button. This element will serve as a wrapper for an SVG icon and its corresponding text.
Here’s the required markup:
<header> <h1>Mini Toolbar</h1> <ul> <li> <button> <svg>...</svg> <span>Pages</span> </button> </li> <li> <button> <svg>...</svg> <span>Collection</span> </button> </li> <li> <button> <svg>...</svg> <span>Appearance</span> </button> </li> <li> <button> <svg>...</svg> <span>Options</span> </button> </li> <li> <button> <svg>...</svg> <span>Search</span> </button> </li> </ul> </header>
The icons used here are taken from Envato Elements. You may recognize this icon set as I’ve already used it in a previous tutorial as part of an SVG sprite.
2. Define the Styles with CSS
The header will behave as a flex container. Its children will be vertically centered and distributed across the main axis. We’ll also give it a maximum width and horizontally center it:
/*CUSTOM VARIABLES HERE*/ header { display: flex; align-items: center; justify-content: space-between; max-width: 1000px; padding-left: 15px; margin: 0 auto; border-radius: 5px; background: var(--blue); }
Both the list and buttons will be flex containers with vertically centered content:
header ul, header button { display: flex; align-items: center; }
All buttons will have different colors and the color values will match the values of the Slider Revolution’s mini toolbar. When a button is being hovered over, its color will lighten slightly, thanks to CSS’s native filter()
function.
We’ll also give them overflow: hidden
because we want to hide their overflowed content during the slide animation:
/*CUSTOM VARIABLES HERE*/ header button { padding: 15px; overflow: hidden; transition: filter 0.25s; } header li:nth-child(1) button { background: var(--green); } header li:nth-child(2) button { background: var(--blue); } header li:nth-child(3) button { background: var(--gray); } header li:nth-child(4) button { background: var(--red); } header li:nth-child(5) button { background: var(--orange); } header button:hover { filter: brightness(110%); }
SVG Icons
The SVGs will have a white color. And, as previously discussed, the text will initially be hidden. It will become visible when we hover over the parent button:
/*CUSTOM VARIABLES HERE*/ header button svg { fill: var(--white); } header button span { opacity: 0; visibility: hidden; transition: all 0.25s ease-out; } header button:hover span { margin-left: 15px; opacity: 1; visibility: visible; }
If you need a reminder of how Flexbox alignment works, this tutorial by Ana will tell you all you need to know:
3. JavaScript: Listen for Mouse Events
When the DOM is ready, we’ll grab all the header buttons. Then, we’ll loop through them and perform the following actions:
- Grab their text element and calculate the default width of it.
- Then, set the width of that element to 0.
- Each time we hover over a button, we’ll reset the default width of its text element.
- Then, each time we stop hovering over a button, we’ll set its width to 0.
Here’s the JavaScript that accomplishes this behavior:
const buttons = document.querySelectorAll("header button"); buttons.forEach(el => { // 1 const span = el.lastElementChild; const width = span.offsetWidth; // 2 span.style.width = 0; // 3 el.addEventListener("mouseenter", () => { span.style.width = `${width}px`; }); // 4 el.addEventListener("mouseleave", () => { span.style.width = 0; }); });
CSS-Only Solution
Time to discuss one last thing. My initial attempt was to build a CSS-only demo. So initially, I set the max-width
property of all span
s to 0. Next, when the buttons were being hovered, I changed that value to a fixed 110px. That works fine here, yet this solution has limitations because there’s a hardcoded value in the loop.
Check the CSS solution below (perhaps you have some ideas about how to improve it?):
If we add a new menu item which contains a lot more text we run into problems. You might think it’s possible to set the max-width
value to auto
, but unfortunately this solution won’t work at all!
These limitations are what prompted me to think about a quick JavaScript solution in the first place.
Conclusion
That concludes another short tutorial, folks! Thanks for following along, I hope you learned something new today. Feel free to extend the demo and (for example) make it work on click events instead of on mouse events. Plus, if you do so, be sure to make it accessible.
Thanks again for reading!
More Front-End Projects with a Touch of JavaScript
-
Navigation DesignBuild an Advanced Responsive Menu Inspired by Netflix
-
JavaScriptHow to Build a JavaScript Popup Modal From Scratch
No comments:
Post a Comment