Question

I have some custom styles for buttons. To simulate the 3D look of it being pressed, I'm shifting the text down a few pixels using the :active pseudo-class, like this:

input[type=button] {
  padding-top: 4px;
  padding-bottom: 4px;
}
input[type=button]:active {
  padding-top: 6px;
  padding-bottom: 2px;
}

Trouble is, when I do this, in Chrome there are 2 pixels of dead space under the text. When those pixels are clicked, the "click" event is not triggered.

You can see it in action here: http://jsfiddle.net/yg775/ I exaggerated the shifting to make it more obvious. Click below the text on the button to see the effect.

Observations:

  • The size of the dead space is directly proportional to the number of pixels I am shifting the text.
  • The dead space is only under the text. Moving the mouse left or right on the X axis, you can see that the click event triggers when not directly under the text.
  • This only happens on Google Chrome

Someone else noticed this a while ago (Small dead space on a div button in chrome) but this problem is actually more pervasive than just the case he mentioned. Also the "answer" was to trigger on mousedown, but that won't work for me. "click" has different behavior than "mousedown", and I need "click".

Any thoughts how to get around this?

Was it helpful?

Solution

Unfortunately, it seems to be a bug with the .click() command: https://stackoverflow.com/a/5081144. In summary (quoted from above link):

  • If you mousedown on the padding move the mouse and mouseup on the padding, click event fires.
  • If you mousedown on the padding move the mouse but now mouseup on the text, there is no click event.

Since you need to use the .click() command, here may be a fix: http://jsfiddle.net/yg775/12/.

JQuery:

$('#button_box').mousedown(function() {
    clicked = true;
});

$('#button_box').mouseup(function() {
    if (clicked) {
        paddingClicked = true;
        $("#button_box").trigger( "click" );
    }
});

$(document).mouseup(function() {
    if (!paddingClicked) {
        clicked = false;
    }
});

$('#button_box').click(function() {
    clicked = false;
    if (paddingClicked) {
        numClicks++;
        $('#display').text(numClicks.toString()+' clicks');
        paddingClicked = false;
    }
});

I have a container div called button_box that gets used with .mousedown() and .mouseup(). These set two flags, which then calls .trigger( "click" ) that simulates a click.

The $(document).mouseup(...) is in place to catch if you click in the button and then drag the mouse outside before the .mouseup() buttons is called to reset the flag. Without it, you can then click outside of the button and then drag the mouse back in and it would register the .mouseup(). A bit hacky, but it works.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top