CSS: Sticky footers
問題
在網頁設計中,Sticky footers設計是最古老和最常見的效果之一,大多數人都曾經經歷過。它可以概括如下:如果頁面內容不夠長的時候,頁尾塊貼上在視窗底部;如果內容足夠長時,頁尾塊會被內容向下推送。
這種效果不僅是無處不在,很受歡迎,而且實現起來看上去也非常容易。但實際上實現起來要比預期花的時間更多。此外,在CSS2.1中的解決方案中幾乎都要給頁尾設定一個固定高度。這是很脆弱的,很少是可行的。實際上實現這個效果過於複雜,而且還需要增加特定的標記和一些Hack手段。在CSS2.1中受到一些限制,但使用現代CSS,我們能把這個效果做得更好,那要如何做呢?
如果你從未看過這樣的效果或者對這個問題的相關資料感興趣的話,這裡有一些受歡迎的文章,提供了許多Web開發人員的構思和解決方案:
- CSS Sticky Footer Layout
- Ryan Fait’s CSS Sticky Footer
- Sticky Footer
- Sticky CSS footers: The flexible way
- Modern Clean CSS “Sticky Footer”
最後兩個是最簡潔的實現方案,但仍然有其自己的侷限性。
固定高度的解決方案
我們在<body>
元素下使用一些常用的HTML標籤元素:
<header>
<h1>Site name</h1>
</header >
<main>
<p>Bacon Ipsum dolor sit amet...
<!-- Filler text from baconipsum.com --></p>
</main>
<footer>
<p>© 2015 No rights reserved.</p>
<p>Made with ♥ by an anonymous pastafarian.</p>
</footer>
給頁面寫一些基本樣式。看到的效果如下圖所示:
現在,我們來減少一些內容。你可以看看會發生什麼,如下圖所示:
太好了,問題出現了,但我們要如何解決這個問題呢?
如果我們假定頁尾文字不會溢位容器,我們可以為容器推算出其高度:
2行 * 行高 + 3 x 段落的margin + 垂直的padding = 2 x 1.5em + 3 x 1em + 1em = 7em
同樣,頁頭的高度是2.5em
。因此,通過使用視窗相對單位和calc()
,使用一行CSS程式碼,可以實現Sticky footers效果:
main {
min-height: calc(100vh - 2.5em - 7em);
/* Avoid padding/borders screwing up our height: */
box-sizing: border-box;
}
或者,我們可以使用一個容器將<header>
和<main>
元素包裹起來,這樣我們只需要計算頁尾的高度:
#wrapper {
min-height: calc(100vh - 7em);
}
這似乎略優於現有的固定高度的解決方案,主要是由於其簡單。然而,除了簡單的佈局,但這是不切合實際。它要求我們每次都要計算包裹頁尾文字容器的高度,這樣我們需要每次計算容器的min-height
。除非我們願意新增HTML容器來包裹我們的標題和內容,不過同意也要計算。當然,在這個時代,我們可以做得更好,對嗎?
Flexbox解決方案
解決這類問題,Flexbox是最完美的方案。我們只需要幾行CSS程式碼就可以完美的實現,而且不需要一些奇怪的計算或新增額外的HTML元素。首先,我們需要在<body>
元素上設定display:flex
。如果父元素(<body>
)的三個塊元素,使用Flexbox切換佈局,還需要設定flex-flow:column
,否則這三個塊會排成一行。如下圖所示:
body {
display: flex;
flex-flow: column;
}
在這一點上,我們的頁面看起來和之前一樣,因為每個元素所佔視窗高度是由其內容決定。如此一來,我們可以說還沒有真正的利用上Flexbox。
從實際出發,需要給<body>
設定min-height
值為100vh
,讓<body>
內容不足視窗高度時也能佔據整個視窗。雖然這樣做了,效果看起來,還是如下圖所示:
即使給<body>
指定了最小高度,但每個盒子的高度仍取決於其內容大小。
這裡我們需要在頁頭和頁尾設定高度,但其內容的高度自動伸縮的來適配剩餘空間。我們可以在<main>
上設定flex
值大於0
(常用的是1
):
body {
display: flex;
flex-flow: column;
min-height: 100vh;
}
main { flex: 1; }
flex
屬性是flex-grow
、flex-shrink
和flex-basis
三個屬性縮寫。任何元素設定了flex
大於0
,元素就會靈活的控制自己的尺寸,來適配容器的剩餘空間。例如,如果<main>
設定了flex:2
,<footer>
設定了flex:1
,那麼頁尾的高度是主內容高度的二分之一,同樣的,如果值設定的是4
和2
而不是2
和1
,他們效果是一樣的,因為他們的倍數比例值一樣。
就這樣,不需要更多的程式碼!就能實現如下圖所示的Sticky footers效果:
僅僅用了四行程式碼,是不是覺得Flexbox很強大,很完美呀。
原文:
https://www.w3cplus.com/css3/css-secrets/sticky-footers.html