首发于个人 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.
而后好像就没有了,谢谢观看水水的《后知后觉系列》