如果在一个区域内只允许部分区域产生滚动的效果,而其余部分不能移动,你会采用什么方法呢?
作者:Icarus
原文链接: http://xdlrt.github.io/2016/12/02/2016-12-02
首先我们可以把这个需求分解为两个小的问题来解决。
height: 100%
以及 overflow: hidden
,即禁用页面原生的滚动,保证只会显示一屏的内容。 overflow-y
mdn对于overflow-y的定义
The overflow-y property specifies whether to clip content, render a scroll bar, or display overflow content of a block-level element, when it overflows at the top and bottom edges.
overflow-y属性指定或是裁剪内容并且渲染一个滚动条,或是当块级元素在其顶部或底部溢出时显示溢出的内容。
简单来说, overflow-y
属性在垂直方向上存在溢出的时候,通过设置不同的值会产生不同的表现。为了实现滚动功能我们需要将该属性设置为 scroll
,之后,无论块级元素的内容是否溢出,浏览器都会生成一个滚动条并且隐藏容器中内容溢出的部分,只有在滚动之后才会显示。
举个例子:
.test{ width: 200px; /* 关键样式 */ height: 200px; overflow-y: scroll; /* 以下无关样式 */ background: #f14c5c; color: #fff; } <div class="test"> 这里面只是一段测试的内容这里面只是一段测试的内容这里面只是一段测试的内容 这里面只是一段测试的内容这里面只是一段测试的内容这里面只是一段测试的内容 这里面只是一段测试的内容这里面只是一段测试的内容这里面只是一段测试的内容 这里面只是一段测试的内容这里面只是一段测试的内容这里面只是一段测试的内容 </div>
效果如下:
这里面只是一段测试的内容这里面只是一段测试的内容这里面只是一段测试的内容这里面只是一段测试的内容这里面只是一段测试的内容这里面只是一段测试的内容这里面只是一段测试的内容这里面只是一段测试的内容这里面只是一段测试的内容这里面只是一段测试的内容这里面只是一段测试的内容这里面只是一段测试的内容
通过刚才的例子我们可以得出结论,只要限制块级元素的高度,自然就可以实现只有该元素的内容可滚动而不影响其它内容。但是在实现过程中遇到了新的问题,如何实现对设计图的精确还原?设计图如下:
整个弹出框高度是随页面高度自适应的,标题部分和底部按钮部分位置是固定的,中间列表需要占满剩余高度,并且内容可滚动。整个弹窗被最外层div包裹,底部按钮相对于它进行定位。经过思考后,尝试了四种方案,分享给大家。
我们需要确定的核心问题就是中间内容的高度,也即是 height
在不同尺寸屏幕下的精确高度。
相对于视口的高度,视口被均分为100单位,即1vh等于视口高度的1%。
但是vh单位对低版本安卓和ios支持不够好,微信浏览器X5内核不支持,虽然已经升级到blink内核,但是为了确保万无一失,放弃采用这种方案。另外也无法精确控制和底部按钮边距。
和vh类似,无法精确控制和底部按钮的边距,自适应效果不好。
对于以上两种方案的存在的问题, calc
计算属性可以很好的解决,只需要设置 height:calc(100% - 60px)
,就可以精准的占满中间部分,并且保持和底部按钮的边距。
可惜的是对于低版本的安卓浏览器、ios浏览器包括微信浏览器在内的主流浏览器支持都不好,依然只能弃用。
如果兼容性再好一点的话,calc方案应该是最好用且最优雅的一种实现方式。
单纯的使用css无法实现,就只能借助js来动态计算内容所需要的高度来进行设置。同时这种方法也几乎不会遇到兼容性的问题,是对优雅降级的一种实践。
如果直接设置 overflow-y:scroll
在ios下始终会出现很丑的滚动条,我们可以对该元素设置以下属性:
margin-right: -20px; padding-right: 20px;
对滚动条进行一个小小的hack,它就再也不会出现了,用户交互时会有和原生滚动一样的感觉,体验更佳。