patternhtmlMinor
Mobile touch menu
Viewed 0 times
menumobiletouch
Problem
I want to make a menu-item which:
Here's my HTML fragment (to be enclosed within HTML5 `
Furthermore the Mozilla help says not to rely on hover:
On touch screens :hover is problematic or impossibl
- Reveals a drop-down submenu, when the item is hovered (using a mouse) or touched (using a touch-screen).
- Lets you click on a link in the submenu, while the submenu is visible
- Closes the submenu (without clicking on a link), if you move the mouse outside the submenu (using a mouse) or touch anywhere outside the submenu (using a touch-screen).
Here's my HTML fragment (to be enclosed within HTML5 `
element):
Drop-down menu item
First sub-item
Second sub-item
Heading
Lorem ipsum.
Here's my CSS:
div.menuitem
{
height: 3em;
}
div.menuitem:hover ul.submenu
{
left: auto;
}
ul.submenu
{
left: -999em;
z-index: 1;
margin: 0;
position: absolute;
width: 10em;
list-style: none;
padding: 0;
line-height: 1.6;
background-color: Black;
}
ul.submenu a
{
color: White;
}
The important part of the CSS is:
ul.submenu {left: -999em; makes the ul.submenu invisible, off to the left of the screen
div.menuitem:hover ul.submenu { left: auto; makes the ul.submenu visible (not off to the left of the screen) when the div is hovered.
Here is a demo.
This seems to work correctly (e.g. the submenu items become visible) when I touch it using the browser on an Android tablet.
Is the above code sufficient? If not then in what circumstance would it malfunction?
IMO, on a touch screen the browser is (or at least, all browsers that I have tried are) synthesizing a 'hover' event (and applying the hover style) when it detects a user touch.
Other solutions that I've seen on the 'net seem much more complicated than this, for example:
- Handling Hover Events on a Touch Screen uses JavaScript
- Click function for
:hover states on touch devices suggests that it's necessary to use :focus or :active, because :hover` doesn't work.Furthermore the Mozilla help says not to rely on hover:
On touch screens :hover is problematic or impossibl
Solution
Interesting question,
as I noted, the provided code does not work, but you can do accomplish what you tried by using
Because of the 2nd problem, I think the whole mouse down and move to the right menu item does not really work for mobile (YMMV). This works fine for me ( just click to show sub items and click again to remove them ).
with toggleMenu being
or (less Golfic)
I tested ( the Golfic version, and the :active version ) on my iPhone and it does work.
as I noted, the provided code does not work, but you can do accomplish what you tried by using
:active note that this will not work without also setting `. The problem with that set up is two-fold:
- The drop down menu item
div` is still the 'owner' of the touch event, and you cannot select a sub item (lifting the finger will hide the sub-menu again, most frustrating)- The sub-menu items appear right under your finger, not the best user experience
Because of the 2nd problem, I think the whole mouse down and move to the right menu item does not really work for mobile (YMMV). This works fine for me ( just click to show sub items and click again to remove them ).
Drop-down menu itemDrop-down menu item
First sub-item
Second sub-item
with toggleMenu being
function toggleMenu( menu )
{
for (var i = 0, child ; style = menu.children[i++].style; )
{
style.left = style.left != 'auto' ? 'auto' : '-999em';
}
}or (less Golfic)
function toggleMenu( menu )
{
var i = 0,
showValue = 'auto',
hideValue = '-999em',
child, style;
while( child = menu.children[i++] ){
style = child.style;
style.left = style.left != showValue ? showValue : hideValue;
}
}I tested ( the Golfic version, and the :active version ) on my iPhone and it does work.
Code Snippets
<div class="menuitem" onclick="toggleMenu(this)">
Drop-down menu item<span>Drop-down menu item
<br />
<ul class="submenu">
<li><a href="foo.html">First sub-item</a></li>
<li><a href="bar.html">Second sub-item</a></li>
</ul>
</div>function toggleMenu( menu )
{
for (var i = 0, child ; style = menu.children[i++].style; )
{
style.left = style.left != 'auto' ? 'auto' : '-999em';
}
}function toggleMenu( menu )
{
var i = 0,
showValue = 'auto',
hideValue = '-999em',
child, style;
while( child = menu.children[i++] ){
style = child.style;
style.left = style.left != showValue ? showValue : hideValue;
}
}Context
StackExchange Code Review Q#56267, answer score: 5
Revisions (0)
No revisions yet.