JSFiddle - React, Tailwind, and code Playground
HTML
<div id="menu">
<div id="wrapper">
<div id="logo"></div>
</div>
<nav>
<ul>
<li>Note one</li>
<li>Note two</li>
<li>Note three</li>
<li>Not four much longer</li>
</ul>
</nav>
</div>
CSS
#menu {
position: relative;
background: #ccc;
display: inline-block;
}
#wrapper {
margin: 5px;
}
#logo {
width: 150px;
height: 50px;
border: 1px solid #000;
margin: 0px auto;
z-index: 10;
}
nav {
width: 100%;
overflow: hidden;
text-align:center;
height: 2em;
}
ul {
position: relative;
display:inline-block;
margin: 0 auto;
padding: 0;
list-style-type: none;
text-align:left;
}
li {
display: block;
margin: 0;
padding:0.25em 0;
line-height: 1.5em;
}
ul.animated, nav {
transition: all 500ms linear 1s;
}
#menu.hover ul, #menu.hover nav {
transition-delay: 0s;
}
li:hover, li.hover {
background-color: #999;
}
li.ignoreHover {
background-color: #ccf;
/* a touch of blue, so you can see it */
}
.selected {
color: #fff;
}
JavaScript
var item = 3;
var minPadding = 5;
var hover = "hover"; // class
var $li = $("li");
var $ul = $("ul");
var $menu = $("#menu");
var $nav = $("nav");
var itemHeight = parseInt($li.outerHeight(), 10);
var itemCount = $ul.children().length;
var menuWidth = $menu.outerWidth(true);
var padding = (menuWidth - $ul.width()) / 2;
var transitionDone = false;
var mouseOver = false;
var top;
// Pad the list items to fill the width of the menu
if (padding < minPadding) {
// Widen the menu to allow for the minimum padding
menuWidth += (minPadding - padding) * 2;
$menu.width(menuWidth);
padding = minPadding;
}
$li.css({
paddingLeft: padding,
paddingRight: padding
});
// Scroll to the current selected item
selectItem(true);
function selectItem(scroll) {
$ul.children().removeClass("selected");
$ul.children().eq(item).addClass("selected");
if (scroll) {
top = -(itemHeight * item);
$ul.css({
top: top
});
}
}
// Wait until the initial settings are applied
// before animating the transitions
setTimeout(function () {
$ul.addClass("animated");
}, 1);
// Handle interaction with the menu
$menu.on("mouseover", openMenu);
$menu.on("mouseleave", closeMenu);
$menu.on("transitionend", menuIsOpen);
$ul.on("click", treatClickOnItem);
// <WORKAROUND...
var x;
var y;
// ... WORKAROUND>
function openMenu(event) {
if (mouseOver) {
// This method may be called multiple times as
// the menu is transitioning to its open state
return;
}
// <WORKAROUND...
$menu.on("mousemove", function updateXY(event) {
x = event.pageX;
y = event.pageY;
});
// ... WORKAROUND>
$menu.addClass(hover);
transitionDone = false;
mouseOver = true;
$nav.css({
height: (itemHeight * itemCount)
});
$ul.css({
...