- 在做吸顶导航时,常常会用到
position:fixed
,以便让导航栏一直固定在页面上方。
// 常用的position:fixed 相关css
.nav {
width: 100%;
height: 80px;
position: fixed;
left: 0;
top: 0;
}
- 然而盒子使用
position:fixed
有个问题:在窗口很窄,而盒子宽度比较大时,会看不到盒子中被遮挡的内容。即使拖动了滚动条,也看不到盒子后面的内容 - 原因:
position:fixed
是相对于视口viewport
定位的,在设置了left:0
后,盒子左边与视口的距离就永远是0,即使拖动滚动条,盒子也会一起右移,因此始终看不到被遮挡的部分 - 想解决这个问题,其实需要把
position:fixed
的定位改成相对父元素定位, 一听相对父元素定位, 这不就是子绝父相干的事情吗! - 但是子绝父相就做不到吸顶导航了,当父元素高度较高,滚动条往下拖的话,子元素就看不到了
- 其实,还有一个定位属性
position: sticky
就可以做到这一点! - 看一下mdn的解释:元素根据正常文档流进行定位,然后相对它的最近滚动祖先(nearest scrolling ancestor)和 containing block(最近块级祖先 nearest block-level ancestor),包括 table-related 元素,基于 top、right、bottom 和 left 的值进行偏移。偏移值不会影响任何其他元素的位置。 该值总是创建一个新的层叠上下文(stacking context)。注意,一个 sticky 元素会“固定”在离它最近的一个拥有“滚动机制”的祖先上(当该祖先的 overflow 是 hidden、scroll、auto 或 overlay 时),即便这个祖先不是最近的真实可滚动祖先。
- 说人话版本:
position: sticky
相当于相对定位和固定定位的混合。比如,我把上面的定位改成如下:
.nav {
width: 100%;
height: 80px;
position: sticky;
left: 0;
top: 0;
}
- 那么,在最少指定了top, right, bottom 或 left 四个阈值其中之一时,
position: sticky
才能生效,否则他就和postions:relative
一样。那么生效是什么样的?以top:0
举例。当视口viewport
的顶部与nav
距离大于0之前,nav
就是普通的postions:relative
;当视口viewport
的顶部与nav
距离小于0时,nav
就变成了position: fixed
,会固定在距离顶部0px的位置 - 需要注意的是,
position: sticky
不能超出父级容器的区域,当滚动到父级容器已经没有地方给他固定了,那么position: sticky
就会开始跟随父级一起滚动了 - 那么,回到我们的目标,我们为什么设置了
left: 0;
,再拖动横向滚动条时,导航栏会跟着滚动呢?原因就是position: sticky
不能超出父级容器的区域!我们设置了width: 100%;
后,其宽度已然是父级的100%,当我们拖动滚动条,position: sticky
受限于父级已经没有位置给他固定了,只能跟着父级一起滚动了