If you use anchors then the ipad will assume a first touch is a hover and show your image. The problem arises in that the the image won’t go away until you touch somewhere else which usually means blocking part of the page (sometimes this works when the trigger item is not an anchor but a child item is an anchor).
Here’s an example:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<style>
.menu {
margin:0;
padding:0;
list-style:none;
position:relative;
}
.menu li a {
height:200px;
border:1px solid green;
display:block;
}
.image {
position:absolute;
left:-999em;
width:200px;
height:200px;
background:red;
}
.menu li:hover{cursor:pointer}
.menu li:hover span,
.menu li.over span {
left:0;
}
</style>
</head>
<body>
<ul class="menu">
<li><a href="#"><span class="tnail">Thumbnail</span> <span class="image">img</span></a> </li>
<li><a href="#"> <span class="tnail">Thumbnail</span> <span class="image">img</span></a> </li>
<li><a href="#"> <span class="tnail">Thumbnail</span> <span class="image">img</span></a> </li>
<li><a href="#"> <span class="tnail">Thumbnail</span> <span class="image">img</span></a></li>
<li><a href="#"> <span class="tnail">Thumbnail</span> <span class="image">img</span></a> </li>
</ul>
</body>
</html>
A safer alternative is to add some js to monitor touch and add a class at touchstart/touchend and duplicate the hover rules.
Here’s a live example.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<style>
.menu {
margin:0;
padding:0;
list-style:none;
position:relative;
}
.menu li {
height:200px;
width:200px;
border:1px solid green
}
.image {
position:absolute;
left:-999em;
width:200px;
height:200px;
background:red;
}
.no-touch .menu li:hover span{left:0}/* for non touch devices*/
.menu li.over span {/* for touch devices */
left:0;
}
</style>
</head>
<!-- class added to body so that the hover isn't applied when on mobile as it messes with the touchstart events -->
<body class="no-touch">
<ul class="menu">
<li> <span class="tnail">Thumbnail</span> <span class="image">img</span> </li>
<li> <span class="tnail">Thumbnail</span> <span class="image">img</span> </li>
<li> <span class="tnail">Thumbnail</span> <span class="image">img</span> </li>
<li> <span class="tnail">Thumbnail</span> <span class="image">img</span> </li>
<li> <span class="tnail">Thumbnail</span> <span class="image">img</span> </li>
</ul>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function() {
$('.menu li').bind('touchstart touchend', function(e) {
e.preventDefault();
$(this).toggleClass('over');
$('body').removeClass('no-touch');
});
});
</script>
</body>
</html>
A class of no-touch is added to the body.
<body class="no-touch">
This is then used to trigger the normal hover rules.
.no-touch .menu li:hover span{left:0}/* for non touch devices*/
The no-touch class is then removed with a script that monitors touch events and at the same time we add (and then remove) a class to the items when touched (touchstart and touchend).
$(document).ready(function() {
$('.menu li').bind('touchstart touchend', function(e) {
e.preventDefault();
$(this).toggleClass('over');
$('body').removeClass('no-touch');
});
The reason that we apply no-touch class to the body is that once the touch events are added to the page the hover effects seem to start working on the touch device and ruin the effect because they don’t ‘un-hover’.
When a user touches the element a class of .over is added so we just duplicate our hover rules.
.menu li.over span {/* for touch devices */
left:0;
}
It’s pretty straight forward.
These days I usually avoid hover for important items and use click instead using js (e.g. dropdown menus) and let all devices have a click effect instead.