若是問,CSS 中 position 屬性的取值有幾個?
大部分人的回答是,大概是下面這幾個吧?css
{
position: static;
position: relative;
position: absolute;
position: fixed;
}
額,其實,咱們還能夠有這 3 個取值:前端
{
/* 全局值 */
position: inherit;
position: initial;
position: unset;
}
沒了嗎?偶然發現其實還有一個處於實驗性的取值,position:sticky
(戳我查看MDN解釋):git
{
position: sticky;
}
臥槽,什麼來的?github
前端發展太快,新東西目接不暇,可是對於有趣的東西,仍是忍不住一探究竟。(只怪當初...)web
position:sticky
sticky 英文字面意思是粘,粘貼,因此姑且稱之爲粘性定位。下面就來了解下這個處於實驗性的取值的具體功能及實用場景。chrome
這是一個結合了 position:relative
和 position:fixed
兩種定位功能於一體的特殊定位,適用於一些特殊場景。瀏覽器
什麼是結合兩種定位功能於一體呢?網絡
元素先按照普通文檔流定位,而後相對於該元素在流中的 flow root(BFC)和 containing block(最近的塊級祖先元素)定位。佈局
然後,元素定位表現爲在跨越特定閾值前爲相對定位,以後爲固定定位。spa
這個特定閾值指的是 top, right, bottom 或 left 之一,換言之,指定 top, right, bottom 或 left 四個閾值其中之一,纔可以使粘性定位生效。不然其行爲與相對定位相同。
在講述具體示例以前,仍是頗有必要了解一下 position:sticky
的兼容性,嗯,不樂觀的兼容性。
看看 CANIUSE 下的截圖:
SHIT,這麼好的屬性支持性竟然這麼慘淡。
IOS 家族(SAFARI && IOS SAFARI)和 Firefox 很早開始就支持 position:sticky
了。而 Chrome53~55 則須要啓用實驗性網絡平臺功能才行。其中 webkit 內核的要添加上私有前綴 -webkit-
。
地址欄輸入 chrome://flags/
,找到 enable-experimental-web-platform-features
,選擇啓用:
因此下面的 CodePen 示例,須要上述幾個瀏覽器下觀看。
position:sticky
示例嗯,上面的文字描述估計仍是很難理解,看看下面這張 GIF 圖,想一想要實現的話,使用 JS + CSS 的方式該如何作:
按照常規作法,大概是監聽頁面 scroll 事件,判斷每一區塊距離視口頂部距離,超過了則設定該區塊 position:fixed
,反之去掉。
而使用 position:sticky
,則能夠很是方便的實現(請在 SAFARI 或者 CHROME53+ 下觀看):
嗯,看看上面的 CSS 代碼,只須要給每一個內容區塊加上
{
position: -webkit-sticky;
position: sticky;
top: 0;
}
就能夠輕鬆實現了。
簡單描述下生效過程,由於設定的閾值是 top:0
,這個值表示當元素距離頁面視口(Viewport,也就是fixed定位的參照)頂部距離大於 0px 時,元素以 relative 定位表現,而當元素距離頁面視口小於 0px 時,元素表現爲 fixed 定位,也就會固定在頂部。
不理解能夠再看看下面這兩張示意圖(top:20px 的狀況,取自開源項目fixed-sticky):
position:relative
;position:fixed
;position:sticky
實現頭部導航欄固定運用 position:sticky
實現導航欄固定,也是最多見的用法:
(請在 SAFARI 或者 CHROME53+ 下觀看):
同理,也能夠實現側邊導航欄的超出固定。
position:sticky
的生效是有必定的限制的,總結以下:
須指定 top, right, bottom 或 left 四個閾值其中之一,纔可以使粘性定位生效。不然其行爲與相對定位相同。
top
和 bottom
同時設置時,top
生效的優先級高,left
和 right
同時設置時,left
的優先級高。設定爲 position:sticky
元素的任意父節點的 overflow 屬性必須是 visible,不然 position:sticky
不會生效。這裏須要解釋一下:
position:sticky
元素的任意父節點定位設置爲 overflow:hidden
,則父容器沒法進行滾動,因此 position:sticky
元素也不會有滾動而後固定的狀況。position:sticky
元素的任意父節點定位設置爲 position:relative | absolute | fixed
,則元素相對父元素進行定位,而不會相對 viewprot 定位。達到設定的閥值。這個還算好理解,也就是設定了 position:sticky
的元素表現爲 relative
仍是 fixed
是根據元素是否達到設定了的閾值決定的。
上面從兼容性也看到了,狀況不容樂觀,可是用於某些佈局仍是能省不少力的,若是真的但願用上這個屬性,能夠採用一些開源庫來實現兼容。
推薦 fixed-sticky 。
系列 CSS 文章彙總在個人 Github 。
到此本文結束,若是還有什麼疑問或者建議,能夠多多交流,原創文章,文筆有限,才疏學淺,文中如有不正之處,萬望告知。