背景
使用滚动特性来优化滚动效果。
官网建议:非标准特性,请不要在生产环境使用它。
个人建议:因为大多数的开发者对其并没有很清晰的认知,并且也不知道其会导致的隐性问题,因此不建议使用。
官方说明:链接
基本说明
值 | 效果 |
---|---|
auto | 移开之后滚动停止 |
touch | 保持一定时间的滚动 |
使用影响(想不到的)
影响子元素的z-index
效果就是ios上子元素的z-index失效的,比如本来期望通过z-index来实现让某元素覆盖在其他元素之上,但在上述条件下就会失效。
复现条件:
1 ios设备(较低的系统版本和较旧的设备版本)
2 父元素设置了 -webkit-overflow-scrolling:touch
3 子元素设置了z-index较大的值,期望展示在其他元素之上(基本的位置关系已经通过固定位置实现了)
复现的codepen案例:你要使用ios设备复现这个问题,复现链接 (待测试复现)
解决方案:
方案1 取消父元素设置的touch,或者设置其为auto即可,推荐的保守方案
方案2 需要展示的层级高的元素不要放在其原来滚动特性的容器内,不在遮罩内,尽量在body直接子级建立一个新的元素避免这种问题
方案3 组件内设置当出现模态框的时候,通过js设置其父容器的样式为非touch,模态框小时的时候隐藏。与此类当模态框出现的时候控制页面不可滚动设置body为overflow:hidden同理。
页面卡顿等相关问题
- 在safari上,使用了-webkit-overflow-scrolling:touch之后,页面偶尔会卡住不动。(中招)
- 在safari上,点击其他区域,再在滚动区域滑动,滚动条无法滚动的bug。
- 通过动态添加内容撑开容器,结果根本不能滑动的bug。(中招)
- 滚动中 scrollTop 属性不会变化
- 手势可穿过其他元素触发元素滚动
- 滚动时暂停其他 transition
解决方案:
1 子元素设置额外的高度,保证其触发一次滚动,推荐方案
2 设置父元素容器位置关系为static ,当其原来为fixed,absolute等不正常定位时
备注:整体布局建议额外增加一个div容器,高度为100%,超出滚动,不使用页面默认的滚动,使用正常的文档流
<style>
.outer{
height:100%;
overflow:auto;
-webkit-overflow-scrolling:touch;
}
.inner{
//方案一
height:101%;
//方案二
height:calc(100% + 1px);
}
</style>
<div class='outer'>
<div class='inner'></div>
</div>
彩蛋 1:antd-mobile modal模态框的布局技巧
技巧1:新增与content同级的元素,而不是在原来的内容内新增元素
技巧2:将新增元素内并级存放模态框和内容框
技巧3:遮罩和内容部分都设置了较高的显示等级,999
技巧4:只在内容的区域设置了滚动touch特性,其内部已经不再需要设置z-index来保证显示的层级
技巧5:内容容器设置了其内部任何内容都能自动水平垂直居中,内部用一个大的内容区块包裹
<style>
.mask{
position: fixed;
top: 0;
right: 0;
left: 0;
bottom: 0;
height: 100%;
z-index: 999;
background-color: rgba(0,0,0,.4);
}
.contentWrap{
position: fixed;
overflow: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
height: 100%;
z-index: 999;
-webkit-overflow-scrolling: touch;
outline: 0;
display: flex;
align-items: center;
justify-content: center;
transform: translateZ(1px);
}
</style>
<div>
<div class='mask'></div>
<div class='contentWrap'>
<div class='content'>content</div>
</div>
</div>
彩蛋2 :移动端页面整体布局技巧
我们经常会有固定头部和顶部的需求,这时候整体的布局不建议页面本身使用固定位置,而是建议整体使用绝对布局,或者就是相对布局也没关系,在布局的时候预留出上下的空间。
<style>
body{
height:100%;
}
.header{
position:fixed;
top:0;
left:0;
height:37px;
width:100%
}
.page-container{
padding-top: 37px;
padding-bottom: 43px;
height: 100%;
display: flex;
justify-content: center;
}
.safeBot{
// 包括了底部内容高度和安全高度 也可以直接设置在contentWrap里
padding-bottom:56px;
}
.contentWrap{
min-height:100%;
}
.foot{
position:fixed;
z-index:1001;
bottom:0;
left:0;
width:100%;
// 底部安全距离
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
</style>
<body class='page-container'>
<div class='header'>
</div>
<div class='contentWrap'>
<div class='content'></div>
<div class='safeBot'></div>
</div>
<div class='foot'>
</div>
</body>