是否可以在响应点击事件的 div 区域包含 box-shadow ?

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

我有一个 div 作为圆形按钮。它的样式使其整体外观的很大一部分来自 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>

我在按钮 div 上附加了一个点击事件侦听器。不幸的是,如果在 box-shadow 上单击 div,它不会响应,因为 box-shadowdiv 之外呈现。

这在手指有时不会碰到 div 中心的触摸设备上尤为严重。 (当然,如果点击在div的50px区域内,则正常响应。)

是否可以让事件侦听器响应对 box-shadow 以及实际 div 的点击?

我知道我可以在按钮顶部使用一个单独的更大的透明 div 并将事件侦听器附加到它,但是这样的解决方法是否必要?

(按钮 div 必须使用 box-shadow 样式。我不能使用 border 属性 或增加 padding。)

是的,将 box-shadow 更改为 inset 阴影将使阴影占据的区域也可点击。 inset box-shadow 实际上是在 元素 中添加的,因此即使单击阴影也会被视为单击 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 -->

以下是将阴影更改为插图时需要考虑的一些要点:

  • 由于在里面添加了box-shadow,所以div的高度和宽度应该增加一点,以确保最终结果与原始版本的大小相同。在正常的 box-shadow 版本中,形状的大小将是容器的半径 + 展开半径。
  • 您可能还需要调整一些边距,就像我在下面的示例中所做的那样。
  • 添加到阴影的任何模糊现在都将向内应用(也就是说,模糊将与容器内部而不是主体混合)。我们对此无能为力。

注意: 在上面的代码片段中,我将内联样式属性的内容替换为 CSS。


如果您希望第二个阴影(白色阴影)向外模糊并与主体背景融合,您可以将 box-shadow 替换为 radial-gradient,如下例所示。但是使用 radial-gradient 有两个缺点,一是它对浏览器的支持较低,二是当元素的尺寸很小时曲线不是很平滑。

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>