场景
在文章浏览页面需要实现一个贴在视口右侧的标签,点击标签,出现右侧的抽屉,显示文章的目录(toc)。如下图
fixed失效
起初,对于目录标签的元素,直接使用fixed定位即可解决问题。
但是,当在layout组件中使用了framer-motion后,由于包裹组件的元素应用了transform属性,fixed失效了😭😭😂
fixed失效原因
在许多情况下,position:fixed 将会失效。MDN 用一句话概括了这种情况:
当元素祖先的 transform 属性非 none 时,容器由视口改为该祖先。
具体可以查看fixed 定位失效 | 不受控制的 position:fixed。
实际测试中,不仅仅由于transform属性,还有其他属性也会导致堆叠上下文出现,子孙元素的fixed定位失效。
sticky来救场
由于场景是在滚动时,保持目录标签一直在视口不消失,而sticky正好是滚动场景下适用的属性,所以可以使用sticky来替代fixed。
sticky效果
sticky就像是position:relative和position:fixed的结合体,在为滚动出视口时,sticky元素乖乖不动,而滚动出视口后,sticky元素粘滞在了视口的某个位置(应该是滚动容器的某个位置,该位置也即未滚动出视口的位置)。
sticky如何设置
sticky元素的设置有一些限制条件:
- 祖先元素不能有任何的overflow:visible以外的overflow设置,否则没有粘滞效果。
- 上下滚动设置top后者bottom,水平滚动设置left或者right。
- 其他限制:参考杀了个回马枪,还是说说position:sticky吧。
因此,设置如下:
- 在滚动容器的元素和sticky元素的祖先元素上检查overflow属性的设置;
- 设置目录标签的元素position:sticky和top值。