扩大按钮点击区域的实现
背景
在某些场景下,页面中的按钮等可以发生点击交互行为的元素本身的尺寸可能会比较小,并没有那么容易的准确点击,这一点在移动端上更加明显。
如果我们把相应的点击事件绑定在这个小小的按钮或是图标上,用户将很难触发该元素的行为。举个例子,手机上某些 app 的开屏广告、早期 web 页面角落的小广告,都会有一个“跳过”或是“关闭”按钮,如果点击不准确,可能一不小心就点到广告上,从而打开新的 app 或是 web 页面(当然,这里可能是广告行业的产品经理为了提高广告的点击率,故意这么做的)。
对于我们普通的网页来说,需要尽量避免这种“难以点击”的情况,具体来说,就是要扩大按钮的可点击区域。可能有的开发同学就要说了,那个按钮 / icon 本身就是这么大,我如果在外面再套一层元素,那不仅不符合语义,页面结构也会变得很复杂,好麻烦啊。本文就介绍一种成本比较低的扩大按钮点击区域的解决方案,如有雷同,那就是巧了。
借助伪元素扩大按钮点击区域
以下图中的箭头 icon 为例,如果我们已经在 icon 上绑定了点击事件,现在其可点击区域就只有图中蓝色背景的 14px * 14px
的大小。
我们现在给这个元素添加一个相对定位:
i.el-icon-arrow-up {
position: relative;
}
并添加 after 伪元素:
i.el-icon-arrow-up::after {
content: '';
position: absolute;
left: -16px;
right: -16px;
top: -16px;
bottom: -16px;
}
我们可以发现,可点击区域扩大到了 46px * 46px
,这个区域内的点击行为都会触发绑定在 i
元素上的事件。
原理也很简单,元素本身是非 static
定位,伪元素是 absolute
定位,其 left
等属性是相对于该元素本身定位的,负值则是往外扩大。
在具体开发过程中,我们可以给所有需要扩大按钮点击区域的元素增加一个类,比如就叫 expand-click-area
,然后添加以下样式:
.expand-click-area {
position: relative;
}
.expand-click-area::after {
content: '';
position: absolute;
left: -16px;
right: -16px;
top: -16px;
bottom: -16px;
}
当然,这个方案也不能无脑使用,下面说一下使用该方法的注意点。
注意点
注意按钮之间的重叠
对于两个距离比较近的元素,如果使用该方法,可能会使伪元素区域产生重叠,重叠区域只能响应后者的点击事件,如下图所示:
所以,对于距离较近的元素,需要谨慎处理。上图中的例子可能比较极端,两个元素完全贴在一起。在类似的情况下,可以考虑只扩大垂直方向的点击区域。我们给这些元素额外增加一个类 expand-click-area-vertical
,其样式如下:
.expand-click-area-vertical::after {
left: 0;
right: 0;
}
注意需要通过样式嵌套等方式让这个样式的优先级高于前面的样式,才能使 left
和 right
属性发生覆盖。
对于只扩大水平方向按钮点击区域的场景则同理,指定 top
和 bottom
属性为 0 即可。
注意该元素原本有没有伪元素
既然我们的方法中用到了 after
伪元素,那么我们需要注意该元素原本有没有 after
伪元素。如果已经有了,我们再去覆盖,可能会产生其他问题,这里不再举例说明。
注意元素本身的定位
我们在上面的例子中给元素添加了 position: relative;
,那么如果元素本身已经有了其他定位方式,可能会使其属性被覆盖,导致页面布局问题。
另一方面,如果元素本身没有非 static
的定位,我们也忘记添加 position: relative
了,将会使按钮点击区域向外层扩大到父级第一个非 static
元素。说起来有点绕,到底是什么意思呢?让我们看一个真实的案例。
真实反面案例
在“扩大按钮点击区域”功能上线后,陆续收到客户反馈(投诉),称我们为了赚钱,脸都不要了,页面上点哪里都会进入广告。经过一通复现、排查,发现是前端的锅,罪魁祸首就是这个“扩大按钮点击区域”。
如下图所示(倒也不是特意做了模糊处理,只能找到这么模糊的图了),该页面是手机浏览器的搜索联想页,用户输入关键词后,页面中会展示相关的应用、广告、联想词等条目。页面中第二行右侧的深蓝色按钮为广告页面的入口,整个页面的浅蓝色是该元素的 after
伪元素大小(准确来说,还要再往外扩大十几像素),点击整个页面都相当于点到了广告页面的入口。
为什么呢?因为该按钮没有非 static
定位,这一条广告元素也没有定位,导致伪元素的 absolute
定位是相对于整个页面的,它又通过 top bottom left right
等值为负的属性往外扩大了一圈,它又响应了按钮的点击事件…
为什么开发、测试的时候没注意到,上线了才被用户发现?这就是另外的问题了,这里不再展开讨论。
总结
本文介绍了一种借助伪元素的扩大按钮点击区域的方法,伪元素的定位方式为 position: relative
,并且设置 left、right、top、bottom
为负值,使按压区域比元素本身大一圈。但如果按压元素本身没有设置非 static 的定位,伪元素的定位基础会逐层往外层查找,直到找到第一个非 static 元素或根元素。
虽然该方法比较简单,但我们在使用时需要多加注意,以免引入其他问题。
转载自:https://juejin.cn/post/7239987776552058940