背景
半页面弹窗是前端移动端中非常常用的组件,效果如下:
一个用户体验好的半页面弹窗,应该有如下特点:
- 出现弹窗时,背景有个黑色半透明遮罩层,应该是逐渐出现的,透明度渐变。
- 出现弹窗时,弹窗是从下至上移动出现的,而不是闪现的。
- 关闭弹窗时,背景色也要逐渐消失,弹窗从上至下移动走。
一个好用的半页面弹窗,应该有如下特点:
- 动画样式实现不耦合弹窗的高度。无论里面放多少内容,弹窗有多高,不改样式的情况下,渐入渐出的动画都表现正常,且出现时,底部应该贴合屏幕底部。
- 控制出现/隐藏的方法简单,自动播放出现/隐藏的渐变动画,而非手动调用API播放渐变动画。
本文参考WeUI的实现,介绍如何优雅的实现半页面弹窗。
遮罩层样式
遮罩层动画
我们可以让遮罩层默认是隐藏状态(opacity为0),当要展示时,需要开发者设置一个新的class(比如叫show)给mask对应的标签。
然后,我们给遮罩层设置个transition即可。代码如下:
注意,我们必须设置visibility
属性。因为当你设置opacity
后,只是修改了透明度,它会在顶部挡住所有的交互事件。所以我们需要修改visibility
,这样它就不会挡住那些交互事件了。
弹窗样式
为了让弹窗无论什么高度都可贴紧屏幕底部,我们直接设置bottom: 0
即可。
此外,为了防止弹窗太低不美观,弹窗太高挡住页面,最好设置个min-height
和max-height
。欢迎阅读《你真的了解 width height 吗?》了解min-height
和max-height
的优先级。
也许你会好奇为什么设置3个padding
:下面的合法的padding会覆盖前面的,constant
和env
可能在一些浏览器并不支持,这时候下面的就不合法了,会使用兜底的0 24px
这个padding值。
为什么要用env(safe-area-inset-bottom)
呢?主要是iPhone最近几年的产品,底部有一个条带,如下图:
如果你贴紧底部放置文本,用户是看不清的。所以就有了「安全区域」概念,给弹窗设置底部的安全区域到padding里,保证了弹窗内容不会跟这个条带重合,保障了iOS用户体验。
在近代iPhone系列产品中,env(safe-area-inset-bottom)通常是34px,其它产品中,这个值是0。
弹窗动画
如果没有.show
,就隐藏,把他放在屏幕底下,通过transform的translateY实现。为了让动画跟元素高度像素值无关,我们使用100%,代表元素整体高度。
看看wxml怎么写
这里以小程序为例:
注意这里的catchtouchmove="return"
,是为了在打开弹窗后,拦截了用户滑动事件,避免弹窗下面的文档被滑动。
看看html怎么写
我写了个demo,可以参考下: