纯CSS实现微信列表左滑显示按钮的交互效果

一、实现效果示意

这个效果大家应该都见过,左滑对话列表,会显示藏在后面的按钮,iOS微信可以看到这种交互效果,大家手上如果有iPhone手机,可以试试。

效果示意

在Web中,是可以纯CSS实现几乎一致的交互效果的。

下面一步一步来。

二、滚动、绝对定位与按钮显示

如果大家认为看过《CSS世界》,应该知道CSS中绝对定位元素有这么一个特性:

绝对定位元素的包含块在滚动容器之外,那么这个容器滚动的时候,绝对定位元素是不会跟着滚动的。

所以,如果我们希望列表左滑的时候背后按钮显示,只需要:

  1. 每个列表元素是个水平滚动容器;
  2. 背后按钮设置position:absolute
  3. 确保列表元素没有设置position:relative或者transform等影响绝对定位包含块的CSS属性。

实地跑一下代码看看:

<div class="list">
    <button class="button" data-type="danger">删除</button>
    <a href="javascript:" class="content">我是列表,试试左滑我</a>
    <s class="space"></s>
</div>

核心CSS如下:

/* 列表仅水平滚动 */
.list { display: flex; overflow-y: hidden;}
/* 主内容宽度100%,白色背景覆盖 */
.content { flex: 0 0 100vw; background-color: #fff; position: relative; }
/* 空标签元素,作用是腾出水平滚动空间 */
.space { flex: 0 0 4rem; }
/* 按钮绝对定位,藏在内容白色背景后面 */
.button { width: 4rem;  position: absolute; right: 0; }

于是就有下图所示的GIF录屏效果:

GIF列表左滑出现删除按钮录屏

不足

虽然交互效果的精髓出来了,但是却有个不好的体验,那就是如果滚动到一半距离再停止,只会显示一半的按钮内容,就像下图这样:

按钮显示一半示意

这样的效果显然无法用在生产环境,不急,有CSS属性可以优化这个交互体验,那就是CSS Scroll Snap

三、Scroll Snap与按钮边缘定位

CSS Scroll Snap是CSS中一个独立的模块,定义了在滚动行为中,滚动停止的位置可以根据子元素的位置决定,之前有专门撰文介绍过,“要不过来了解下CSS Scroll Snap?”。

iOS 11+支持,已经支持很多年了,可以在生产环境使用,不支持的浏览器可以简单几行JS代码Polyfill一下。

回到这里,想让滚动超过一半距离的时候显示完整按钮,滚动不足一半的时候回到初始位置,只需要加几行CSS就可以了,如下所示:

/* 新增的CSS */
.list { scroll-snap-type: x mandatory; }
.space { scroll-snap-align: end; }
.content { scroll-snap-align: start; }

也就是滚动时候,主列表内容左边缘对齐,占位元素(可以看成是按钮)右边缘对齐。

于是就有如下GIF所示的录屏效果:

滚动时候自动边缘位置定位

支持多个按钮

实现了1个按钮的滑动显示效果,2个按钮自然也不在话下,只需要调整.space这个元素的宽度正好是2个按钮的宽度就可以了。

/* 2个按钮宽度 */
.space { flex: 0 0 8rem; }

此时的效果可以参考下图我录屏的GIF:

多个按钮定位滑动示意

不足
然而,仔细观察上面2个按钮的滑动交互效果,发现没有微信效果那么有质感,因为微信列表左滑的时候,后面的几个按钮,是有先后顺序、上下顺序显示的,也就是俗称的“视差”效果,而我这里CSS实现的效果就是硬邦邦的出现。

不急,CSS也是可以实现富有层次的视差滚动效果的。

 

四、3D透视与按钮视差滚动出现

相关的CSS技术我之前也分享过,都是很棒的技术,可惜很多人都没注意,也没重视,有兴趣可以访问这篇文章:“纯CSS实现视差滚动效果”。

这里不讲原理,只展示实现。

在原来实现的CSS基础上,再新增如下的CSS代码:

/* 视差滚动 */
.list { perspective: 1px; transform-style: preserve-3d; perspective-origin: 100% 50%; }
.button:last-of-type { transform: translate3D(2rem, 0, -1px) scale(2); }
.button:first-of-type { transform: translate3D(2rem, 0, -3px) scale(4); }

也就是把两个按钮放在3D视角上,这样滚动的时候,由于近大远小,视觉上就会有视差滚动效果的。

眼见为实,看看实现的效果吧:

多按钮同时视差滚动gif截图

五、Demo页面及其他说明

上面4个GIF演示效果均可以亲自体验,您可以狠狠地点击这里:纯CSS touch左滑按钮显示demo

如果您是PC电脑访问的demo页面,务必进入移动端模式体验,否则没有效果。

然后为了方便大家手机体验,提供了二维码:

demo页面二维码

demo页面有完整的CSS代码供大家参考与学习,然后点击按钮大家可以看到会有提示出现,类似下图这样,表示按钮并未遮挡,点击行为完全OK的。

按钮可以点击截图示意

其他说明

我自己手机测试了下,Android中完美,和PC Chrome下效果一致;iPhone Safari浏览器效果平平(iOS 12),没有看到滚动停止自动边缘定位。

实际上,按照以外的经验,iPhone设备支持scroll-snap-type/scroll-snap-align是没有任何问题的,因此,我猜想,可能与我这次水平滚动采用的是Flex布局有关,换成inline-block布局应该就妥了,我有6~7成的把握,由于赶着发文,我暂时就没测,日后我看看怎么回事再来补充。

或者在做的各位帮忙测测看inline-block布局是否OK,以及为何Flex布局中iOS Safari滚动停止时候没有Snap定位。

结语

本文背景源自厂子最近的一个项目,设计师设计了左滑出现后面按钮的效果,被我看到了,当时我就琢磨,似乎CSS就可以实现这种交互效果,不需要大动干戈写一段JS代码。

然后今天周末,正好有时间验证自己的想法,于是就有了本文的内容。

大家通过阅读应该可以发现,最终的实现效果,实际上,就是把我以前学到的那些看起来没什么大用处的CSS特性,一个一个累加了起来,对吧。比方说,从基础的CSS绝对定位特性,到CSS Scroll Snap,再到CSS 3D transform在视差滚动中的应用,都是自己以前积累并记录过的内容。

这就是重视基础的好处,当基础足够扎实,积累足够多,这个时候看到某个需求,你就能像电火花一样,一下子迸发出全新的灵感,创造出全新的实现,有助于提升个人成就感和技术热爱度。

好,就说这些。

如果您觉得本文内容还挺不错的,欢迎分享,让更多人看到CSS的潜力。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值