若是在一个区域内只容许部分区域产生滚动的效果,而其他部分不能移动,你会采用什么方法呢?css
做者:Icarus
原文连接:http://xdlrt.github.io/2016/1...前端
首先咱们能够把这个需求分解为两个小的问题来解决。ios
部分区域固定git
其他区域滚动github
为页面的body部分设置height: 100%
以及overflow: hidden
,即禁用页面原生的滚动,保证只会显示一屏的内容。web
固定区域采用绝对定位。浏览器
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
,以后,不管块级元素的内容是否溢出,浏览器都会生成一个滚动条而且隐藏容器中内容溢出的部分,只有在滚动以后才会显示。测试
举个例子:spa
.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,它就不再会出现了,用户交互时会有和原生滚动同样的感受,体验更佳。
@__prototype__ 经大大提醒,设置webkit浏览器的私有属性::-webkit-scrollbar
能更灵活的控制滚动条,在此感谢。若是只须要隐藏,以下代码便可:
::-webkit-scrollbar{ display: none }
虽然移动端的浏览器webkit内核居多,不过仍是要在真机测试后再得出结论,若是有些浏览器不支持这个属性的话,依然可使用上面的小hack。
在ios设备中,利用overflow
来模拟滚动会出现卡顿的状况,能够经过设置-webkit-overflow-scrolling: touch
来解决,缘由是设置后ios会为其建立一个UIScrollView
,利用硬件来加速渲染。
这个问题自己并不复杂,甚至需求更改后,实现变的很是简单。可是但愿能经过这个小例子能让每个前端人在思考需求时都可以尽量的去想更多样的方法来解决问题,即便由于兼容性或其它缘由暂时没法实现,在这个过程当中得到的成长也是很是有益的。