css sticky定义

position:sticky 定义元素为粘性定位元素,根据正常文档流进行定位,然后相对它的临近祖先滚动的元素,基于 top , right , bottom , left 的值进行偏移。

sticky的元素会创建以一个新的层叠上下文,如果其临近的祖先元素存在 overflow 的值是 hidden , scrollautooverlay 值,都会导致 sticky 失效

实战例子

废话不多说,上代码

html

<div class="row content">
  <div class="col-lg-9">
  </div>
  <div class="d-none d-md-none d-lg-block col-lg-3 right-column">
    <div class="sticky">
      sticky
    </div>
  </div>
</div>

css

.content {
  padding: 100px 0 500px 0;
  height: 1200px;
}

.right-column {
  background-color: #044A56;
}

.sticky {
  position: sticky;
  top: 0;
  height: 50px;
  background-color: #2C6E5A;
  color: #FFF;
}

代码很简单,这样就实现了一个右侧滚动固定的功能

See the Pen sticky固定元素 by kelen (@imkelen) on CodePen.

失效场景以及定位

1. 检测浏览器是否支持

js检测方法

if (!(CSS && CSS.supports && CSS.supports("position", "sticky"))) {
  // 不支持做兼容处理
}

css检测方法

.sticky {
  position: fixed;
  top: 0px;
}

@supports (position:sticky) { 
  .sticky {
    position: sticky;
    top: 0;
  }
}

2. 检测父元素是否设置了 overflow 不为 visible 的属性,可以通过下面代码来检测

let parent = document.querySelector('.sticky').parentElement;

while (parent) {
  const hasOverflow = getComputedStyle(parent).overflow;
  if (hasOverflow !== 'visible') {
    console.log(hasOverflow, parent);
  }
  parent = parent.parentElement;
}

3. 检测父元素的高度是否大于 sticky 元素的高度

父元素如果是设置了flex布局,如果 sticky 元素设置了 align-self: stretch 属性,只要 sticky 元素大于父元素高度,则无法滚动,可以设置为 flex-start