Is it possible to include the box-shadow in the div area that responds to a click event?

梦想与她 提交于 2019-12-20 02:27:42

问题


I have a div acting as a round button. It is styled so that a significant part of its overall appearance comes from a box-shadow:

<body style="background:black">
<div id="button" style="width: 50px; height: 50px; background: yellow; border: none; border-radius: 50px; box-shadow: 0 0 0 5px #c03, 0 0 2px 7px #fff"></div>
</body>

I have a click event listener attached to the button div. Unfortunately, it doesn't respond if the div is clicked on the box-shadow as the box-shadow is rendered outside the div.

This is particularly a problem on touch devices where the finger sometimes doesn't hit the center of the div. (Of course, it responds normally if the click is within the div's 50px area.)

Is it possible to make the event listener respond to clicks on the box-shadow as well as the actual div?

I realise I can use a separate and larger transparent div over the top of the button and attach the event listener to that, but is such a workaround necessary?

(The button div must be styled with box-shadow. I can't use the border property or increase padding.)


回答1:


Yes, changing the box-shadow to an inset shadow will make the area occupied by the shadow also clickable. An inset box-shadow is actually added within the element and hence even a click on the shadow is treated as a click on the div.

window.onload = function() {
  var btn = document.querySelector("#button");
  var btnOriginal = document.querySelector("#button-original");

  btn.addEventListener("click", function() {
    alert("I have been clicked");
  });
  btnOriginal.addEventListener("click", function() {
    alert("I have been clicked");
  });
}
#button {
  width: 64px;
  height: 64px;
  border: none;
  border-radius: 50px;
  box-shadow: inset 0 0 2px 2px #fff, inset 0 0 0 7px #c03;
}
#button-original {
  width: 50px;
  height: 50px;
  border: none;
  border-radius: 50px;
  box-shadow: 0 0 0 5px #c03, 0 0 2px 7px #fff;
}

/* Just for demo */

#button {
  margin: 10px;
}
#button-original {
  margin: 17px;
}
div:hover {
  cursor: pointer;
}
body{
  background: black;
<div id="button"></div><!-- modified version -->

<div id="button-original"></div><!-- original version -->

The following are some points that need to be considered while changing the shadow to an inset one:

  • Since the box-shadow is added inside, the height and width of the div should be increased by a bit to make sure the final outcome is the same size as your original version. In the normal box-shadow version, the size of the shape would be the container's radius + spread radius.
  • You may also have to adjust some margins like I have done in the sample below.
  • Any blur that is added to the shadow will now be applied inwards (that is, the blur will blend with the inner part of the container and not the body). We can do nothing about this.

Note: In the above snippet, I have replaced the inline style attribute's contents with CSS.


If you want the second shadow (the white colored one) to blur towards the outside and blend with the body background, you could replace the box-shadow with radial-gradient like in the below sample. But there are two drawbacks of using radial-gradient, one is it has lower browser support and second is the curves are not very smooth when the element's size is very small.

window.onload = function() {
  var btn = document.querySelector("#button");
  var btn2 = document.querySelector("#button-2");

  btn.addEventListener("click", function() {
    alert("I have been clicked");
  });
  btn2.addEventListener("click", function() {
    alert("I have been clicked");
  });
}
#button {
  width: 75px;
  height: 75px;
  border: none;
  border-radius: 50%;
  background-image: radial-gradient(circle at 50% 50%, transparent 57.5%, #c03 57.5%, #c03 65%, #fff 65%, transparent 72%);
}
#button-2 {
  height: 150px;
  width: 150px;
  border: none;
  border-radius: 50%;
  background-image: radial-gradient(circle at 50% 50%, transparent 57.5%, #c03 57.5%, #c03 65%, #fff 65%, transparent 72%);
}
div:hover {
  cursor: pointer;
}
body {
  background: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div id="button"></div>
<div id="button-2"></div>


来源:https://stackoverflow.com/questions/31333668/is-it-possible-to-include-the-box-shadow-in-the-div-area-that-responds-to-a-clic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!