1

So I'm using a hoverdown menu at the top of my good free photos site.

On desktop, it works just fine when you hover down on it, the menu appears. When you hover off of it, it goes away.

However, mobile does not have the hover behaviour so when on mobile you click on the menu to make it appear, you can't get rid of it.

I need it to go away if you click on the menu (but not the sublinks) or anywhere else on the page.

Here is the HTML code I am using:

<div class="menu-wrap">
  <nav class="menu">
    <ul class="clearfix">       
      <li>

        <a href="#">Good Free Photos Menu<span class="arrow">&#9660;</span></a>

        <ul class="sub-menu">
          <li><a href="https://www.goodfreephotos.com/Free-Stock-Photos/">Free Stock Photos</a></li>
          <li><a href="https://www.goodfreephotos.com/public-domain-images/">Public Domain Images</a></li>
          <li><a href="https://www.goodfreephotos.com/tags/featured">Featured</a></li>
          <li><a href="https://www.goodfreephotos.com/pages/last-100-images">Last 100 images</a></li>
          <li><a href="https://www.goodfreephotos.com/news">News</a></li>
          <li><a href="https://www.goodfreephotos.com/category/tutorials/">Tutorials</a></li>
        </ul>
      </li>
    </ul>
  </nav> 
</div>

and the css:

 .clearfix:after {
    display:block;
    clear:both;
}

/*----- Menu Outline -----*/
.menu-wrap {
    width:100%;
    box-shadow:0px 1px 3px rgba(0,0,0,0.2);
    background:#3e3436;
}

.menu {
    width:1000px;
    margin:0px auto;
}

.menu li {
    margin:0px;
    list-style:none;
    font-family:'Ek Mukta';
}

.menu a {
    transition:all linear 0.15s;
    color:#919191;
}

.menu li:hover > a, .menu .current-item > a {
    text-decoration:none;
    color:#be5b70;
}

.menu .arrow {
    font-size:11px;
    line-height:0%;
}

/*----- Top Level -----*/
.menu > ul > li {
    float:left;
    display:inline-block;
    position:relative;
    font-size:19px;
}

.menu > ul > li > a {
    padding:10px 40px;
    display:inline-block;
    text-shadow:0px 1px 0px rgba(0,0,0,0.4);
}

.menu > ul > li:hover > a, .menu > ul > .current-item > a {
    background:#2e2728;
}

/*----- Bottom Level -----*/
.menu li:hover .sub-menu {
    z-index:1;
    opacity:1;
}

.sub-menu {
    width:160%;
    padding:5px 0px;
    position:absolute;
    top:100%;
    left:0px;
    z-index:-1;
    opacity:0;
    transition:opacity linear 0.15s;
    box-shadow:0px 2px 3px rgba(0,0,0,0.2);
    background:#2e2728;
}

.sub-menu li {
    display:block;
    font-size:16px;
}

.sub-menu li a {
    padding:10px 30px;
    display:block;
}

.sub-menu li a:hover, .sub-menu .current-item a {
    background:#3e3436;
}

I know this may require some JavaScript, but I don't know what code.

Louys Patrice Bessette
  • 33,375
  • 6
  • 36
  • 64
Yinan Chen
  • 11
  • 1

2 Answers2

0

You should read the following post : CSS :hover behaviour on touchscreen devices

The problem with your current design is that it relies on the :hover state to work, which would not always work (for keyboard navigation, and causes problem with touchscreens).

A lot of accessible implementations for dropdown menus are well documented

Your current code may work within your current configuration, all you have to do is set the focus outside of your menu, for instance:

<a href="#">close menu</a>
<div class="menu-wrap">
   <nav class="menu">

But this won't make accessible your menu and won't make it work in the browsers where the :hover state is not recognized as :focus

Adam
  • 17,838
  • 32
  • 54
  • This answer isn't really clear, at least give a code example. – Jacob Belanger May 30 '17 at 11:55
  • @JacobBelanger I included in my answer a link to a full implementation of a fly-out meny written by the WAI. Stackoverflow answers are not meant to provide full working code but to give clues and solutions, even if those solutions still require some work. – Adam May 30 '17 at 13:16
-1

Here's what I would do:
I would start by transferring the hover state from the css hover to a class name like .dropdown-open.
Using jquery:
if the website is viewed on a computer, control this class on mouseover and mousout.
else, toggle the class on mousedown of the element.

The jQuery would look something like this:

$(document).ready(function(){

  function checkWidthForMenu(){
    if($(window).width() > 760) {
      $('.sub-menu').mouseover(function(){
        $(this).addClass('dropdown-open');
      });
      $('.sub-menu').mouseout(function(){
        $(this).removeClass('dropdown-open');
      });


    } else {
      $(document).mousedown(function(){
        $('.sub-menu.dropdown-open').removeClass('dropdown-open');
      });
      $('.sub-menu').mousedown(function(){
        $(this).toggleClass('dropdown-open');
      });

    }
  }
  checkWidthForMenu();
  $(window).resize(checkWidthForMenu());

});


Edit:
Adam has a good point for accessibility; so in your css, add the styles for the opened menu to .sub-menu.dropdown-open, .sub-menu:focus {...} This will make it open on hover and on focus (using the tab key as navigation)

  • How does this address my computer, which is touch screen and which I use regularly with mouse and touch at the same time? – aardrian May 29 '17 at 14:05
  • If it's a wider screen, it will work on hover, if it's a smaller screen, it will toggle on click – Jacob Belanger May 29 '17 at 22:27
  • If you have time, I encourage you to watch Patrick Lauke's presentation "Getting Touchy": https://www.youtube.com/watch?v=jSL-RluQhMs Or just wade into the slides: https://patrickhlauke.github.io/getting-touchy-presentation/ – aardrian May 30 '17 at 00:12
  • My code right now, it toggles on click, I need it to toggle off when you click anywhere else on the document on mobile. – Yinan Chen May 30 '17 at 03:39
  • Damned, is it forbidden to have a touchscreen larger than 760px? – Adam May 30 '17 at 11:02
  • There is currently no way to know if the device you are using is touch in jQuery, so this is the best alternative I can find. – Jacob Belanger May 30 '17 at 11:32
  • @YinanChen I edited the code, it should no work as you want it to. – Jacob Belanger May 30 '17 at 12:36