對“粘連”footer佈局的思考和總結
經典的"粘連"footer佈局
參考文章連結在文章末尾,簡單的語言總結如下:
經典的“粘連”footer佈局就是。我們有一塊內容<main>
。當<main>
的高度足夠長的時候,緊跟在<main>
後面的元素<footer>
會跟在<main>
元素的後面。當<main>
元素比較短的時候(比如小於螢幕的高度),我們期望這個<footer>
元素能夠“粘連”在螢幕的底部。如下圖所示:
當main
足夠長時
當main
比較短時
上面佈局的實現方法在參考文章中已經有提到。下面主要探討我們專案中遇到的情況:
我們需要實現的佈局就是 按鈕“提交”所在的區域能夠自由伸縮。當螢幕較低時,最就是“提交”按鈕和表單所在的區域接觸或者有一定的間隙。
當螢幕足夠高的時候
當螢幕比較低的時候
上面的佈局在移動端需要考慮以下因素對佈局的影響:
安卓上鍵盤彈起會對
absolute
和fixed
產生影響;我們的絕對定位的元素是使用的
bottom
相對於螢幕的底部定位;
為了解決以上的兩個問題的解決方案:
使用正常文件流的元素包裹絕對定位的元素;
絕對定位元素的父級元素應該有一個
min-height
防止,父級元素太低時,絕對定位元素“溢位”父級元素;(min-height >= 絕對定位元素 + bottom);
根據“粘連”footer佈局的思想,結合彈性盒佈局。我們需要的這種佈局可以有兩種方式,分別介紹如下:
1.使用vh
單位
先來了解下vh
vw
這兩個單位。vh
相對於視口的高度。視口被均分為100單位的vh。vw
相對於視口的寬度。視口被均分為100單位的vw。
上面兩個單位通俗的意義就是在css中獲取當前螢幕的高度和寬度(不通過js計算)。
示例程式碼如下:
<body>
<div class="item1"></div>
<div class="item2"></div>
<div class="item3">
<div class="btn-item">你好</div>
</div>
</body >
css程式碼如下:
* {
margin: 0;
padding: 0;
}
body {
/*主要就是這裡獲取視視窗的高度*/
min-height: 100vh;
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
-webkit-flex-flow: column;
-ms-flex-flow: column;
flex-flow: column;
}
.item1 {
height: 100px;
background-color: #ddd
}
.item2 {
height: 300px;
background-color: #fea0a0
}
.item3 {
/*防止絕對定位的元素溢位父級元素*/
min-height: 30px !important;
border: 1px solid #481eff;
position: relative;
height: 0;
-webkit-box-flex: 1;
-webkit-flex: 1;
-moz-box-flex: 1;
-ms-flex: 1;
flex: 1;
-webkit-flex-basis: 0;
-ms-flex-preferred-size: 0;
flex-basis: 0;
max-height: 100%;
}
.btn-item {
position: absolute;
bottom: 10px;
border: 1px solid #000;
}
以上就是完全使用css來實現我們專案中佈局的方法,但是這個方法有一個很明顯的缺點就是vh
單位的相容性問題。相容列表如下:
因為相容性問題,純css的方法在我們的專案中使用還是不現實。但是我們想下問題的本質:在使用彈性盒的基礎上,我們唯一需要做的就是知道彈性盒元素的高度(就是我們專案中螢幕的高度)。
2.js簡單計算滿足相容問題。
就是在dom樹渲染完成以後給body
設定高度未螢幕的高度。為了避免不必要的“重繪”或者是“重排”在head標籤中新增如下js。
var callback = function(){
document.body.style.height=window.screen.height+'px';
};
//是否是頁面載入觸發綁定了事件
if ( document.readyState === "complete" || (document.readyState !== "loading" && !document.documentElement.doScroll) ) {
callback();
} else {
//DOMContentLoaded 僅支援ie9+ 和移動端 <=ie8 使用 onreadystatechange 可以監聽dom是否載入完畢
document.addEventListener("DOMContentLoaded", callback);
}
使用 jQuery 或者是 Zepto 的方法,仍然在head標籤中新增如下js。
$(function(){
$('body').height($(window).height());
})
所以在我們的專案中結合彈性盒佈局和新增簡單的動態js計算螢幕的高度。就可以完美實現我們專案中需要的佈局。
body {
/*使用js動態計算就可以不使用vh單位*/
/*min-height: 100vh;*/
display: flex;
}
參考文章:
因為是一個