首發於個人 Blogcss
不知什麼時候,曾經咱們認爲的東西便會被打破,若是咱們不堅持着去學習,那麼咱們終將會被社會所淘汰。因而我決定寫《後知後覺系列》來記錄一下我曾經跟不上的知識和關鍵點,內容不必定複雜,內容含量不必定高,也許別人已經寫過一個同樣的教程了,可是但願你能從個人筆記中獲取你認爲重要的東西,在紛繁複雜的工做中留下一個真正極客的世界,但願某一天這些東西都可以運用到工做當中。——XGHeavenhtml
記得先看一下目錄,找到你喜歡好奇的內容去針對性閱讀,畢竟我不是來寫教程的。git
最近公司在用 Regular 封裝一個表格組件,須要實現固定表頭的功能。這個是幾乎全部的組件庫都會實現的一個效果,因此實現方式有不少種:github
position: absolute
,同時 top: 0
。同時這種模式下,須要用戶指定每一列的寬度,保證自制的表頭和下面原生的表格一一對應起來。若是不指定的話,也能夠等待 dom 渲染完成以後,再測量寬度。好比 Ant Design 就是使用的這種方式。transform
屬性使得表頭進行偏移,從而實現 fixHeader 的問題,這種方式解決了第一個的問題,可是須要手動監聽 scroll 事件,在快速滾動的狀況下,可能會有必定的性能問題。並且不夠優雅。若是後面的表格內容中有 position: relative
的元素,會覆蓋到表頭。不論是哪一種方式,我總感受不是很完美,因而我就在思考,除了手動更新的方式,難道就沒有一些比較好的方式去作。而後我就去翻看了 github 的固定表頭的方式,頓時豁然開朗。因而就延伸出了這篇文章,position: sticky
屬性。api
Pay Attention:後面所講的內容就不怎麼和表格固定表頭相關,若是你對錶格固定表頭或者固定列有必定問題,能夠查看網易考拉的這篇文章 《一塊兒來聊聊table組件的固定列》。瀏覽器
當第一眼看到這個熟悉的時候,第一句話就是「我 CA」,這 TMD 是什麼鬼屬性,position 何時有了這個屬性。因而去看了 MDN 的介紹,能夠理解爲,這個屬性是實現固定頂部最簡單的實現方式。dom
他實際上是一種 position:relative
和 position: fixed
的結合體,必定要配合 top/right/bottom/left
的屬性一塊兒纔有做用,設置對應方向的最小值。當大於最小值的時候,他就像 relative
同樣,做爲文檔流的一部分,而且 top/right/bottom/left
屬性也會失效。不然當小於設置的值的時候表現的像 fixed
,只不過這個 fixed
再也不現對於窗口,而是相對於最近的可滾動塊級元素。ide
若是你看過其餘關於 sticky 的文章,大部分都會以黏貼的意思來解釋他,那麼很明顯,確實也是這個意思,若是你以爲看了其餘教程可以清楚的話,那麼能夠不用看我這篇了,若是你沒看懂的話,能夠來我這裏看看。性能
廢話少說,咱們先來看一下如何正確使用 sticky。學習
如下的代碼預覽請使用最新 Chrome 查看,或者支持
position: sticky
的瀏覽器查看。部分網站不支持 iframe,能夠去個人 Blog 查看
position: sticky
只相對於第一個有滾動的父級塊元素(scrolling mechanism,經過 overflow 設置爲 overflow/scroll/auto/overlay
的元素),而不是父級塊元素。
position: sticky
只有當設置對應的方向(top/right/bottom/left),纔會有做用,而且能夠互相疊加,能夠同時設置四個方向。
即便設置了 position: sticky
,也只能顯示在父級塊元素的內容區域,他沒法超出這個區域,除非你設置了負數的值。
position: sticky
並不會觸發 BFC,簡單來說就是計算高度的時候不會計算 float 元素。
當設置了 position: sticky
以後,內部的定位會相對於這個元素
雖然 position: sticky
表現的像 relative
或者 fixed
,因此也是能夠經過 z-index
設置他們的層級。當這個元素的後面的兄弟節點會覆蓋這個元素的時候,能夠經過 z-index
調節層級。
See the Pen position: sticky 經過 z-index 調節層級 by Bradley Xu (@xgheaven) on CodePen.
當你懂了這幾個以後,其實這個屬性就用起來就很簡單了。
no code no bb,直接上代碼。
See the Pen position sticky 通信錄 Demo by Bradley Xu ( @xgheaven) on CodePen.最多見的需求就是,當還在文檔流當中的時候,正常顯示,可是當固定住的時候,添加一些陰影或者修改高度等操做。要想實現這個效果,第一反應可能就是手動監聽 scroll
事件,判斷位置,這固然是沒有問題的,可是隨之而來的確實性能的損耗。
最好的方式是使用 IntersectionObserver,這是一個能夠監聽一個元素是否顯示在視窗以內的 API,具體內容見阮老師的《IntersectionObserver API 使用教程》。基本原理就是在一段滾動的頭部和尾部分別添加兩個崗哨,而後經過判斷這兩個崗哨的出現和消失的時機,來判斷元素是否已經被固定。
例子詳見此處
理想很豐滿,顯示很骨感,由於 thead/tbody 對 position 無愛,因此也就不支持 sticky 屬性,因此咱們仍是要單首創建一個頭部。
後來通過網友提醒,本身又去研究了一下,發現仍是有辦法作到固定表頭和列的。
首先針對 Firefox,它自己就支持 thead/tbody 的 position 屬性,因此能夠直接經過對 thead/tbody 設置 position 來實現。而對於 Chrome 瀏覽器來說,能夠經過設置 thead 內的 th 來實現。具體見 Demo.
See the Pen position sticky 經過設置 td 來實現固定表頭 by Bradley Xu (@xgheaven) on CodePen.
而後好像就沒有了,謝謝觀看水水的《後知後覺系列》