132

I've had a look around but can't quite find what i'm looking for.

I currently have a css animation on my page which is triggered by :hover. I would like this to change to 'click' or 'touch' when the page is resized past width 700px using media queries.

Here is what i have at the moment: http://jsfiddle.net/danieljoseph/3p6Kz/

As you can see, the :hover will not work on mobile devices but i still want to ensure it works the same way just by click, not hover.

I would rather use css if possible but happy with JQuery also.

I have a feeling this is very easy to do but i am just missing something very obvious! Any help would be appreciated.

Here is the css animation:

.info-slide {
  position:absolute;
  bottom:0;
  float:left;
  width:100%;
  background:url(../images/blue-back.png);
  height:60px;
  cursor:pointer;
  overflow:hidden;
  text-align:center;
  transition: height .4s ease-in-out;
  -webkit-transition: height .4s ease-in-out;
  -moz-transition: height .4s ease-in-out;
}

.info-slide:hover {
  height:300px;
}
Alex Ljamin
  • 737
  • 8
  • 31
DannyBoy
  • 1,604
  • 2
  • 13
  • 12
  • there is a jquery plugin called hoverIntent – Pete Mar 21 '14 at 13:16
  • According to MDN, :active is now supported by all versions. Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/:active So you should be able to use it as a previous answer mentioned. – Shovely Joe Feb 24 '21 at 21:36
  • How can you see that this is not working on mobile? If I open the jsfiddle link from mobile, I can't see much. – Adam Jul 24 '21 at 05:53

9 Answers9

131

If you use :active selector in combination with :hover you can achieve this according to w3schools as long as the :active selector is called after the :hover selector.

 .info-slide:hover, .info-slide:active{
   height:300px;
 }

You'd have to test the FIDDLE in a mobile environment. I can't at the moment.
correction - I just tested in a mobile, it works fine

LOTUSMS
  • 10,317
  • 15
  • 71
  • 140
  • 41
    w3schools is not the best resource, therefore I'd loke to cite https://developer.mozilla.org/en-US/docs/Web/CSS/%3Aactive – 23tux Oct 24 '15 at 11:12
  • 4
    This does NOT work on Microsoft Edge on a touch-enabled Windows 10 laptop. – SepehrM May 22 '16 at 11:59
  • 19
    Ummmm ...sorry? Lol. Yeah Microsoft edge wasn't out yet when I posted this...I think – LOTUSMS May 22 '16 at 14:05
  • 2
    This doesn't seem to work on mobile safari. The answer below with onclick="" does the trick though! – Jason Godson Aug 01 '16 at 18:46
  • 4
    That is all very nice until the user taps the button again to close it and it won't close unless the user taps anywhere outside the button. Try Chrome dev tools responsive view where you have a touch simulator. If it could be somehow done in pure CSS, that another tap on the button closes it, now that would be awesome! – lowtechsun Jan 14 '17 at 15:45
  • @lowtechsun I haven't maintained this answer since I posted it. One day I will edit it with cross-browser functionality to include Edge and maybe some stress testing. Thanks – LOTUSMS Jan 14 '17 at 15:49
  • 1
    Check [this](http://editor.javascriptkit.com/?eg=dynamic-css-hover) on mobile or with touch simulator. Trying to achieve the 2nd step, close/open on tap of the hovered item, with this approach. If only the long touch could somehow also be taken care of. If/when you update this let me know somehow, thanks. – lowtechsun Jan 14 '17 at 15:55
  • I have a touch-enabled Windows 10 laptop and this works on Edge, for anyone still interested... – Sidders Aug 14 '22 at 12:41
18

You can add onclick="" to hovered element. Hover will work after that.

Edit: But you really shouldn't add anything style related to your markup, just posted it as an alternative.

Adam Azad
  • 11,171
  • 5
  • 29
  • 70
DifferentPseudonym
  • 1,004
  • 1
  • 12
  • 28
  • this worked for me. LOTUSMS's answer didn't - not sure why. maybe a future visitor to this page can enlighten – danyamachine Apr 19 '15 at 19:43
  • 1
    It works on safari with `onclick=""`, but then how to de-activate the element? It remains active forever after the first touch, even when touching outside. – gigabytes Mar 08 '18 at 03:17
  • 5
    Update 2019 : onclick="" is now deprecated – Gregdebrick Mar 19 '19 at 06:40
  • 1
    @gigabytes on mobile devices, use 'ontouchstart' event instead of 'onclick', then :hover effect will be deactivated. – MING WU Mar 25 '22 at 05:22
12
document.addEventListener("touchstart", function() {}, true);

This snippet will enable hover effects for touchscreens

indapublic
  • 2,208
  • 9
  • 38
  • 49
9

I got the same trouble, in mobile device with Microsoft's Edge browser. I can solve the problem with: aria-haspopup="true". It need to add to the div and the :hover, :active, :focus for the other mobile browsers.

Example html:

<div class="left_bar" aria-haspopup="true">

CSS:

.left_bar:hover, .left_bar:focus, .left_bar:active{
    left: 0%;
    }
help-info.de
  • 6,695
  • 16
  • 39
  • 41
Steve_Angel
  • 579
  • 5
  • 4
9

On most devices, the other answers work. For me, to ensure it worked on every device (in react) I had to wrap it in an anchor tag <a> and add the following: :hover, :focus, :active (in that order), as well as role="button" and tabIndex="0".

Ryan Walker
  • 715
  • 2
  • 10
  • 23
4

A CSS only solution for those who are having trouble with mobile touchscreen button styling.

This will fix your hover-stick / active button problems.

body, html {
  width: 600px;
}
p {
  font-size: 20px;
}

button {
  border: none;
  width: 200px;
  height: 60px;
  border-radius: 30px;
  background: #00aeff;
  font-size: 20px;
}

button:active {
  background: black;
  color: white;
}

.delayed {
  transition: all 0.2s;
  transition-delay: 300ms;
}

.delayed:active {
  transition: none;
}
<h1>Sticky styles for better touch screen buttons!</h1>

<button>Normal button</button>

<button class="delayed"><a href="https://www.google.com"/>Delayed style</a></button>

<p>The CSS :active psuedo style is displayed between the time when a user touches down (when finger contacts screen) on a element to the time when the touch up (when finger leaves the screen) occures.   With a typical touch-screen tap interaction, the time of which the :active psuedo style is displayed can be very small resulting in the :active state not showing or being missed by the user entirely.  This can cause issues with users not undertanding if their button presses have actually reigstered or not.</p>

<p>Having the the :active styling stick around for a few hundred more milliseconds after touch up would would improve user understanding when they have interacted with a button.</p>
TillyJonesy
  • 131
  • 6
3

I am a CSS noob but I have noticed that hover will work for touch screens so long as it's a "hoverable" element: image, link, button. You can do it all with CSS using the following trick.

Change your div background to an actual image tag within the div or create a dummy link around the entire div, it will then register as a hover when you touch the image.

Doing this will mean that you need the rest of your page to also be "hoverable" so when you touch outside of the image it recognizes that info-slide:hover has ended. My trick is to make all of my other content dummy links.

It's not very elegant but it works.

  • 3
    You're generalizing this a bit much - especially older iPhones don't apply `hover` on a click (but they do apply `active` and `focus`). To my knowledge, it also doesn't depend on the "clickability" of an object, as every element is "clickable" - but I might be wrong, as I haven't seen all devices out there, which is why it's good practice to not just go by observation, but documentation. – TheThirdMan Aug 04 '16 at 19:02
3

Well I agree with above answers but still there can be an another way to do this and it is by using media queries.

Suppose this is what you want to do :

body.nontouch nav a:hover {
    background: yellow;
}

then you can do this by media query as :

@media(hover: hover) and (pointer: fine) {
    nav a:hover {
        background: yellow;
    }
}

And for more details you can visit this page.

Prateek Gupta
  • 2,422
  • 2
  • 16
  • 30
1

I think this simple method can achieve this goal. With CSS you can turn off pointer event to 'none' then use jQuery to switch classes.

.item{
   pointer-events:none;
 }

.item.clicked{
   pointer-events:inherit;
 }
 
.item:hover,.item:active{
  /* Your Style On Hover Converted to Tap*/
  background:#000;
}

Use jQuery to switch classed:

jQuery('.item').click(function(e){
  e.preventDefault();
  $(this).addClass('clicked')l
});
Arash
  • 19
  • 1