若是在一個區域內只容許部分區域產生滾動的效果,而其他部分不能移動,你會採用什麼方法呢?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
,利用硬件來加速渲染。
這個問題自己並不複雜,甚至需求更改後,實現變的很是簡單。可是但願能經過這個小例子能讓每個前端人在思考需求時都可以儘量的去想更多樣的方法來解決問題,即便由於兼容性或其它緣由暫時沒法實現,在這個過程當中得到的成長也是很是有益的。