粘性布局之粘底效果(position sticky, bottom 0)
经常在查资料时访问各种 CSDN 博客会发现,当 屏幕高度 < 左边栏的高度 < 内容的高度
时,滚动屏幕,左边栏会随着内容一同滚动,当滚动到左边栏底部时,左边栏会停止滚动,而内容会继续滚动。
这种设计的优势在于,用户既能够滚动左边栏,又不会在左边栏不够长时,造成页面左侧大片空白的尴尬,这种布局模式,叫做 粘性布局(sticky)
。
粘性布局在元素满足显示条件时,表现与普通布局没什么不同,但当元素随着页面滚动而无法显示时,会转为 fixed
布局效果,主流浏览器已经全部支持粘性布局(IE不支持)。
通俗一点讲,类似于 Excel 中的“冻结窗格”。
绝大多数网上的教程材料都用 position: sticky; top: 0;
这样的组合来举例,但为了实现 CSDN 左边栏效果,position: sticky; bottom: 0;
似乎不能和想象一样的起作用。
先说结论吧
- sticky 的确是无法直接粘底的……
- CSDN 使用 JS 动态计算实现,当计算到左边栏底部即将滚上屏幕时,立即对左边栏添加
position: fixed; bottom: 0;
样式,把左边栏定死,延时较为明显,快速上下滚动时能看到闪烁。 - 我使用
position: sticky;
实现,通过 JS 计算屏幕高度 - 左边栏高度
得到top
的值,快速滚动时没有闪烁。
发现的过程
- 发现
position: sticky; bottom: 0;
不起作用后,上网搜索也并未查到结果。 - F12 研究 CSDN 的实现方式,发现其依赖于滚动事件,如此实现避免不了延迟和过度计算的问题,决定再找方法。
- 既然 bottom 起不了效果,就尝试设置 top 为负值,果然能够控制元素向上移动,
- 但 top 的取值依赖于左边栏自身的高度,CSS 怎么拿到自身的高度呢?
- 想到 calc,就写出了
top: calc(100vh - height)
这样的句子…… 不管用。 - 摸索了半天 calc 的用法,发现确实是用不成了,calc 拿不到元素自身高度,只能写 JS 了。
- 最终通过 JS 完成了这样的需求。
1 | // 仿 CSDN 左侧栏吸底效果,设置 position 为 sticky,top 为屏幕高度减去左侧栏高度,比 CSDN 的实现更简洁。 |
如果你也想用这段代码,别忘了把 .column-left
替换成你的粘性元素的选择器,并在那个元素上添加 position: sticky;
样式~
另外一个小发现
Windows 环境,缩放 100% 下,当 top
的值为非整数像素值时,Chrome 会有元素内字体模糊的情况,Firefox 和 Edge 没有问题,所以有必要对 top 取整确保字体清晰。
粘性布局之粘底效果(position sticky, bottom 0)