Grow your CSS skills. Land your dream job.

#123: If it Moves When You Click, Make Something Stick

The buttons on CSS-Tricks, at the time of this video, have a faux 3D effect. They look like a blue brick you are looking at from above at an angle. When you press down on them, their :active state is triggered (like all links/buttons/inputs) and the CSS moves them down and to the right, appearing as if you are literally pressing the brick down into the surface a bit.

What's the problem? When you move an element like that (in this case, transform: translate(3px, 3px);) you are changing the area in which that press will trigger the "click" DOM event. If the location of that press happens to be in an area now outsize of that "clickable" area, it won't trigger. So the button looks pressed, but never actually becomes pressed. That's weird and bad and unexpected behavior.

The effect is still cool though, so in this video we fix it by moving a pseudo element to fill the space left behind, making the "clickable" area always the same.

Check out the demo Pen.

Comments

  1. Permalink to comment#

    Hi Chris,

    I tried your solution in the latest Firefox version and some IE version but it still is a little buggy.
    Moving the button is not a good plan I think especially when you have a large shadow because how larger the shadow the more that’s not really firing the form.

    • James
      Permalink to comment#

      I get the same thing here. The solution on codepen works great in Chrome and Opera. But in Firefox 20 and IE9 it still fails to register a click event.

  2. InitArt
    Permalink to comment#

    Altough it says mousedown in this preview, is this fix applied to the three buttons in the right sidebar (Sign up!, RSS and iTunes)?

    They seem to have the problem stated above, with Chrome.

  3. CJ
    Permalink to comment#

    Great post! I had based the buttons for my companies new website on your BERG Cloud Buttons post. I’ve been extremely frustrated with how the click event wouldn’t always fire if you pressed down on the edge of the button, but haven’t had time to look into fixing it.

    I’ll see if this solution helps!

  4. Can you Provide a FF & IE9+ Option/Fallback for these – Maybe an update in written form to this post please Chris. Love this style but too new too css to work out how I can make an option for these other browsers.

    Love the site…

    Jayism – @Code_Collective

  5. This will also solve trigger issue ;)

    $(“button”).on(“mousedown”, function() {
    $(“#message”).text(“mousedown”);
    $(this).click();
    });

  6. btw, this issue become even worse if you have an html inside your button. For example try to click on top border of span in this example. Click event doesn’t work in the middle of button, not only edge in this case. But this trick seems to fix that issue too, thanks!

  7. Antache
    Permalink to comment#

    Could you just increase/decrease left/top invisible borders? It should push against the positioning and still be a clickable element part. I would be interested if this worked.

  8. Mathieu
    Permalink to comment#

    Hey,

    this trick seems not to be working with input type button.

    Do you have a solution ?

    • Lukasz
      Permalink to comment#

      “:after” element doesn’t work on inputs. Does anyone have an idea to solve this problem?

  9. John

    Thanks for sharing, Chris. As mentioned earlier, this won’t work with input:submit buttons. Here’s some jQuery that should solve the problem across the board:

    (function() {
        var DEPRESS_X = 1, 
            DEPRESS_Y = 1,
            $depressed;
    
        $(document).on('mousedown', '.depress', function() {
            if (event.which === 1)
            {
                $depressed = $(this);
    
                $(this).css({
                    position: 'relative',
                    top: DEPRESS_Y + 'px',
                    left: DEPRESS_X + 'px'
                });
            }
        }).on('mouseup', function(event) {
            var buttonLocation, xDelta, yDelta;
    
            if ($depressed)
            {
                if (!$(event.target).is('.depress'))
                {
                    buttonLocation = $depressed.offset();
                    xDelta = Math.abs(buttonLocation.left - event.pageX);
                    yDelta = Math.abs(buttonLocation.top - event.pageY);
    
                    if (xDelta <= DEPRESS_X && yDelta <= DEPRESS_Y)
                        $depressed.trigger('click');
                }
    
                $depressed.attr('style', '');
                $depressed = null;
            }
        });
    }());
    

Leave a Comment

Current day month ye@r *

*May or may not contain any actual "CSS" or "Tricks".