Minimal Hover Menu - The Right Way

Asked

Viewed 129 times

3

In the example below we have an interesting menu, with a effect Hover, which follows the mouse and its items. Everything is very beautiful and works well. The problem is that this menu is set with default dimensions, cannot add more items or change the size keeping the effect.

What I’d like is to have that same effect in a traditional menu, fluid, flexible, without defined dimensions, without :Nth-Child

@import url(https://fonts.googleapis.com/css?family=Roboto:100);
 
body {
  font-family:'HelveticaNeue-UltraLight', 'Helvetica Neue UltraLight', Roboto, Arial, Sans-serif;
  background:#ecf0f1;
}
 
nav {
  width:400px;
  height:60px;
  margin:125px auto 0;
  text-align:center;
  background:#fff;
  box-shadow:0 1px 2px #ddd;
  backface-visibility:hidden;
}
 
nav ul {
  position:relative;
}
 
nav ul li {
  display:inline-block;
  line-height:60px;
  width:100px;
  margin-right:-4px;
}
 
nav ul li:first-child {
  margin-left:-4px;
}
 
li:nth-child(4):after {
  content:"";
  width:100px;
  height:3px;
  position:absolute;
  background:#3498db;
  top:0;
  left:0;
  transform:translateX(0);
  transition:.5s;
}
 
nav ul li:nth-child(2):hover ~ li:nth-child(4):after { transform:translateX(100px); }
nav ul li:nth-child(3):hover ~ li:nth-child(4):after { transform:translateX(200px); }
nav ul li:nth-child(4):hover:after { transform:translateX(300px); }
 
nav ul li a {
  text-decoration:none;
  color:#2c3e50;
  cursor:pointer;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<nav>
  <ul>
    <li><a>Home</a></li>
    <li><a>About</a></li>
    <li><a>Clients</a></li>
    <li><a>Work</a></li>
  </ul>
</nav>

Example menu where I would like the effect of the above example to be applied.

.dropdownmenu ul, .dropdownmenu li {
	margin: 0;
	padding: 0;
}
.dropdownmenu ul {
	background: gray;
	list-style: none;
	width: 100%;
}
.dropdownmenu li {
	float: left;
	position: relative;
	width:auto;
}
.dropdownmenu a {
	background: #30A6E6;
	color: #FFFFFF;
	display: block;
	font: bold 12px/20px sans-serif;
	padding: 10px 25px;
	text-align: center;
	text-decoration: none;
	-webkit-transition: all .25s ease;
	-moz-transition: all .25s ease;
	-ms-transition: all .25s ease;
	-o-transition: all .25s ease;
	transition: all .25s ease;
}
.dropdownmenu li:hover a {
	background: #000000;
}
#submenu {
	left: 0;
	opacity: 0;
	position: absolute;
	top: 35px;
	visibility: hidden;
	z-index: 1;
}
li:hover ul#submenu {
	opacity: 1;
	top: 40px;	/* adjust this as per top nav padding top & bottom comes */
	visibility: visible;
}
#submenu li {
	float: none;
	width: 100%;
}
#submenu a:hover {
	background: #DF4B05;
}
#submenu a {
	background-color:#000000;
}
<nav class="dropdownmenu">
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">About Me</a></li>
    <li><a href="#">Articles on HTML5 & CSS3</a>
      <ul id="submenu">
        <li><a href="#">Difference between SVG vs. Canvas</a></li>
        <li><a href="#">New features in HTML5</a></li>
        <li><a href="#">Creating links to sections within a webpage</a></li>
      </ul>
    </li>
    <li><a href="#">News</a></li>
    <li><a href="#">Contact Us</a></li>
  </ul>
</nav>

Source 1: https://codepen.io/joacimnilsson/pen/WbNLwb

Source 2: https://codepen.io/dhanushbadge/pen/olsvi

2 answers

2


You can use Javascript to have the same effect. I modified this class by adding position: relative:

.dropdownmenu ul {
    background: gray;
    list-style: none;
    width: 100%;
    position: relative;
}

And I created a class that will be the "bar" that accompanies the mouse. The bar will be positioned initially in the li with class .current-link:

.barra {
  height:3px;
  position:absolute;
  background: #00F71C;
  transition:.5s;
  z-index: 9;
}

What I did was create the bar dynamically, positioned in the first <li>. When the mouse goes through the others lis, the bar changes position and width, taking advantage of the effect of transition:.5s;.

Behold:

document.addEventListener("DOMContentLoaded", function(){

   function barPos(bar, act){
      var pos = "left:"
      +act.offsetLeft
      +"px;"
      +"width:"
      +act.clientWidth
      +"px;"
      +"top:"
      +act.offsetTop
      +"px;";
      
      bar.style.cssText = pos;
   }
   
   var lis = document.body.querySelectorAll(".dropdownmenu > ul > li"),
       act = document.body.querySelector(".dropdownmenu > ul li.current-link"),
       bar = document.createElement("span"),
       cur = Array.prototype.indexOf.call(lis, act);
       
   bar.className = "barra";
   lis[0].appendChild(bar);
   var bar = document.body.querySelector(".barra");
   
   barPos(bar, act);
   
   for(x=0; x<lis.length; x++){
      lis[x].addEventListener("mouseover", function(){
         var idx = Array.prototype.indexOf.call(lis, this);
         if(cur != idx){
            cur = idx;
            bar.style.cssText = "left:"
            +this.offsetLeft
            +"px;"
            +"top:"
            +this.offsetTop
            +"px;"
            +"width:"
            +this.clientWidth
            +"px;";
         }
      });

      lis[x].addEventListener("mouseleave", function(){
         cur = Array.prototype.indexOf.call(lis, act);
         barPos(bar, act);
      });
   }
   
   window.addEventListener("resize", function(){ barPos(bar, act); });
   
});
.dropdownmenu ul, .dropdownmenu li {
	margin: 0;
	padding: 0;
}
.dropdownmenu ul {
	background: gray;
	list-style: none;
	width: 100%;
   position: relative;
}
.dropdownmenu li {
	float: left;
	position: relative;
	width:auto;
}
.dropdownmenu a {
	background: #30A6E6;
	color: #FFFFFF;
	display: block;
	font: bold 12px/20px sans-serif;
	padding: 10px 25px;
	text-align: center;
	text-decoration: none;
	-webkit-transition: all .25s ease;
	-moz-transition: all .25s ease;
	-ms-transition: all .25s ease;
	-o-transition: all .25s ease;
	transition: all .25s ease;
}
.dropdownmenu li:hover a {
	background: #000000;
}
#submenu {
	left: 0;
	opacity: 0;
	position: absolute;
	top: 35px;
	visibility: hidden;
	z-index: 1;
}
li:hover ul#submenu {
	opacity: 1;
	top: 40px;	/* adjust this as per top nav padding top & bottom comes */
	visibility: visible;
}
#submenu li {
	float: none;
	width: 100%;
}
#submenu a:hover {
	background: #DF4B05;
}
#submenu a {
	background-color:#000000;
}

.barra {
  height:3px;
  position:absolute;
  background: #00F71C;
  transition:.5s;
  z-index: 9;
}
<nav class="dropdownmenu">
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">About Me</a></li>
    <li><a href="#">Articles on HTML5 & CSS3</a>
      <ul id="submenu">
        <li><a href="#">Difference between SVG vs. Canvas</a></li>
        <li><a href="#">New features in HTML5</a></li>
        <li><a href="#">Creating links to sections within a webpage</a></li>
      </ul>
    </li>
    <li><a href="#">News</a></li>
    <li class="current-link"><a href="#">Contact Us</a></li>
  </ul>
</nav>

  • simply magnificent. that’s exactly it! The effect is fixed on the link Home this effect should also be active on the page of the respective link opened. li.current-link

  • I understand what I need to do.

  • I messed up, misjudged the code, tried, but couldn’t...

  • was perfect.

  • https://answall.com/q/285555/95735

  • it will be possible to put also that same effect, with the and event phocus ? same as css.

  • the issue of Focus/active for that menu, it would be necessary to ask a new question?

  • does not work, I also tested with mousedown, and only click works. But Hover does not. You cannot use these values together? mouseover and mousedown

  • Here it works: https://jsfiddle.net/q488npqp/

  • including Hover? Because only click works here.

  • I’ll ask another question.

  • I understand. Indeed, but the main one is only the contextmenu. Abrir em nova aba.

Show 7 more comments

1

John following all the rules you spoke I managed to get this result.

The example uses Flexbox so it is very responsive. vc can add as many items as you want that will fit right (Maybe you have to decrease the font a little if you have more items...) But it still works well on smaller screens to some extent.

html, body {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
}
body {
    background-image: url(http://placecage.com/800/600);
    background-size: cover;
    background-repeat: no-repeat;
}
.navbar {
    width: 100%;
    height: 50px;
    padding: 0;
    text-align: center;
    background-color: rgba(0,0,0,.5);
    display: flex;
    align-items: center;
    position: relative;
    top: 0;
}
.box {
    flex: 1;
    position: relative;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    cursor: pointer;
}

.box::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    height: 0.5rem;
    width: 100%;
    background-color: #0f0;
    transform: scaleX(0);
    transform-origin: right;
    transition: transform 350ms;
}
.box:hover::after {
    background-color: #0f0;
    transform: scaleX(1);
    transform-origin: left;
}

.link {
    color: #fff;
    text-transform: uppercase;
    font-size: 1.25rem;
    text-decoration: none;
    font-family: sans-serif;
}
<nav class="navbar">
    <div class="box">
        <a class="link" href="">item 1</a>
    </div>
    <div class="box">
        <a class="link" href="">item 2</a>
    </div>
    <div class="box">
        <a class="link" href="">item 3</a>
    </div>
    <div class="box">
        <a class="link" href="">item 4</a>
    </div>
    <div class="box">
        <a class="link" href="">item 5</a>
    </div>
</nav>

OBS: the only detail is that the animation is not always following the mouse. But if you want you can make it start in the "center" of .Box, just put transform-origin: center; so you can see how it looks.

  • Your solution is good, but I would prefer not to use flexbox, if possible I would just like to put this effect, in the menu of the second example, as it is, that menu is well done, works in all browsers, even in ie7... I know that the effect will only work in modern browsers...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.