这篇文章发布于 2020年12月13日,星期日,00:21,归类于 CSS相关。 阅读 24809 次, 今日 5 次 24 条评论
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=9736
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。
一步一步都是源自多年来持之以恒的不断积累。
一、实现效果示意
这个效果大家应该都见过,左滑对话列表,会显示藏在后面的按钮,iOS微信可以看到这种交互效果,大家手上如果有iPhone手机,可以试试。
在Web中,是可以纯CSS实现几乎一致的交互效果的。
下面一步一步来。
二、滚动、绝对定位与按钮显示
如果大家认为看过《CSS世界》,应该知道CSS中绝对定位元素有这么一个特性:
绝对定位元素的包含块在滚动容器之外,那么这个容器滚动的时候,绝对定位元素是不会跟着滚动的。
所以,如果我们希望列表左滑的时候背后按钮显示,只需要:
- 每个列表元素是个水平滚动容器;
- 背后按钮设置
position:absolute
; - 确保列表元素没有设置
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录屏效果:
不足
虽然交互效果的精髓出来了,但是却有个不好的体验,那就是如果滚动到一半距离再停止,只会显示一半的按钮内容,就像下图这样:
这样的效果显然无法用在生产环境,不急,有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也是可以实现富有层次的视差滚动效果的。
//zxx: 如果你看到这段文字,说明你现在访问是体验糟糕的垃圾盗版网站,你可以访问原文获得很好的体验:https://www.zhangxinxu.com/wordpress/?p=9736(作者张鑫旭)
四、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视角上,这样滚动的时候,由于近大远小,视觉上就会有视差滚动效果的。
眼见为实,看看实现的效果吧:
五、Demo页面及其他说明
上面4个GIF演示效果均可以亲自体验,您可以狠狠地点击这里:纯CSS touch左滑按钮显示demo
如果您是PC电脑访问的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的潜力。
本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=9736
(本篇完)
- 大侠,请留步,要不过来了解下CSS Scroll Snap? (0.492)
- CSS scroll-snap滚动事件停止及元素位置检测 (0.486)
- 小tip: 纯CSS实现视差滚动效果 (0.397)
- 杀了个回马枪,还是说说position:sticky吧 (0.306)
- 还算有点用的scrollTo和scrollBy两个JS API (0.208)
- 好吧,CSS3 3D transform变换,不过如此! (0.119)
- Safari 3D transform变换z-index层级渲染异常的研究 (0.119)
- CSS CSS3实现3D开门动画效果 (0.119)
- 第五届CSS大会主题分享之CSS创意与视觉表现 (0.119)
- 直线等图形3D穿过文字的CSS实现 (0.119)
- IE下css bug集合-翻译自haslayout.net (RANDOM - 0.006)
虽然css可以实现,但是感觉js实现更简单些
视察滚动这一块 不太好理解
请教:在视差滚动的介绍中,translateX 偏移 2rem,这个值是怎么计算得来的?
我来反馈问题因为不能截屏,放一个网页。https://hongweizhu.com/keep/zhangxinxu.php
/* 让红色遮住黄色并且不裂开 */
.content{z-index:2}
[data-type=”danger”]{z-index:1;box-shadow: 4rem 0px 0px #eb4646;}
[data-type=”warning”]{box-shadow: 4rem 0px 0px #f59b00;}
有两个问题:
1、请问你的滚动回弹是怎么实现的?
2、我的浏览器出现了很神奇的渲染错误(动图红框内),但是手机上没有问题,请问你知道为什么吗?(87.0.4280.88 (正式版本) (64 位) (cohort: Stable))
https://sm.ms/image/mYvNl6AWTGJbgwB
1、作者不是写的很清楚吗,Scroll Snap 啊
1. 回弹是CSS的能力。
2. 这个问题我看看,感谢反馈。
传说IOS政策限制,这些浏览器用的都是Safari的内核……
每次都有新收获
css3新世界啥时候出啊?我已经等不及了?
ios 10,11下用微信内置浏览器、手机自带sarafi、安装的Chrome均试过,都不行。
太棒了,有人知道文中二维码是怎么生成的吗
地址:https://www.zhangxinxu.com/sp/qrcode.html
最后一个例子,加上视差滚动后会导致能往左滑超出滚动距离,两个按钮中间有间隙
可否告知浏览器?
视差滚动:ios13.3.1 按钮没有效果,而且特别大。在pc端QQ浏览器一直往左拖,会有空隙,然后按钮收不回去了
不好意思这么久才回复,安卓微信内置浏览器和谷歌内核浏览器;(另外我一直以为被回复会有邮件通知来着)
很好,学以致用。很多时候,看了很多学了一些,然后很少用,基本就忘记了,就比方说grid,看完基本没用过,也是不熟练,还是要常用,然后遇到问题,会想到更多的解决方案
题外话,什么时候XHR支持边下载边读取就好了……
但是,貌似fetch支持……抱歉。
谢谢大佬,这个太棒了。
这个例子很好
在 Firefox 上好像还是有点问题