Bootstrap

粘性定位元素position:sticky

这里我们不讨论position其他的:static,fixed,relative和absolute几个属性了,之讨论sticky的特性

sticky:元素根据正常文档流进行定位,然后相对它的最近滚动祖先(nearest scrolling ancestor)和containing block(最近块级祖先 nearest block-level ancestor),包括table-related元素,基于toprightbottom, 和 left的值进行偏移。偏移值不会影响任何其他元素的位置。

该值总是创建一个新的 Stacking context(层叠上下文)。注意,一个sticky元素会“固定”在离它最近的一个拥有“滚动机制”的祖先上(当该祖先的overflow 是 hiddenscrollauto, 或 overlay时),即便这个祖先不是真的滚动祖先。

overlay:行为与auto相同,但滚动条绘制在内容之上而不是占用空间。 仅在基于WebKit(例如,Safari)和基于Blink的(例如,Chrome或Opera)浏览器中受支持

粘性定位

粘性定位可以被认为是相对定位和固定定位的混合。元素在跨越特定阈值前为相对定位,跨越之后为固定定位。例如:

#one { position: sticky; top: 10px; }

在 viewport 视口滚动到元素 top 距离小于 10px 之前,元素为相对定位。之后,元素将固定定位在与顶部距离 10px 的位置,直到 viewport 视口回滚到阈值以下。

必要条件

  1. 须指定top,right,bottom,left四个阈值其中之一,才可使粘性定位生效。否则其行为与相对定位相同。
  2. sticky元素仅在拥有“滚动机制”的祖先元素中(不一定是直接父元素)生效(不能是overflow:hidden)

我们先来看一个普通的栗子:

HTML内容:

    <div class="box">
        <div class="top"></div>
        <div class="item">top 50px</div>
        <div class="space"></div>
        <div class="space"></div>
        <div class="space"></div>
        <div class="space"></div>
        <div class="space"></div>
        <div class="space"></div>
    </div>

CSS内容:

.box{
    width:400px;
    height:300px;
    border:1px solid #c00;
    overflow:auto;
    background:#ccc;
}
.top{
    height:200px;
    background:lightgreen;
}
.item{
    position:sticky;
    top:50px;
    background:greenyellow;
    color:#000;
    font-size:20px;
    text-align:center;
    width:100%;
    height:60px;
    line-height:60px;
    border:1px solid #000;
}
.space{
    width:100%;
    height:100px;
    background:khaki;
    border:1px solid #c00;
}

效果:

上面栗子中,我们的阈值时top:50px,具有滚动机制的祖先元素时item的直接父元素box。当item到达阈值50时,就定位到box内距离50的位置。

 

进阶:

粘性定位常用于定位字母列表的头部元素。标示 B 部分开始的头部元素在滚动 A 部分时,始终处于 A 的下方。而在开始滚动 B 部分时,B 的头部会固定在屏幕顶部,直到所有 B 的项均完成滚动后,才被 C 的头部替代。

HTML内容:

<div class="box1">
    <div class="box2">
        <dl>
          <dt>A</dt>
          <dd>Andrew W.K.</dd>
          <dd>Apparat</dd>
          <dd>Arcade Fire</dd>
          <dd>At The Drive-In</dd>
          <dd>Aziz Ansari</dd>
        </dl>
        <dl>
          <dt>C</dt>
          <dd>Chromeo</dd>
          <dd>Common</dd>
          <dd>Converge</dd>
          <dd>Crystal Castles</dd>
          <dd>Cursive</dd>
        </dl>
        <dl>
          <dt>E</dt>
          <dd>Explosions In The Sky</dd>
        </dl>
        <dl>
          <dt>T</dt>
          <dd>Ted Leo & The Pharmacists</dd>
          <dd>T-Pain</dd>
          <dd>Thrice</dd>
          <dd>TV On The Radio</dd>
          <dd>Two Gallants</dd>
        </dl>
      </div>
</div>

CSS内容:

* {
  box-sizing: border-box;
}
.box1{
    width:400px;
    height:200px;
    overflow:auto;
    border:1px solid
}
dl {
  margin: 0;
  padding: 24px 0 0 0;
}
dt {
  background: #B8C1C8;
  border-bottom: 1px solid #989EA4;
  border-top: 1px solid #717D85;
  color: #FFF;
  font: bold 18px/21px Helvetica, Arial, sans-serif;
  margin: 0;
  padding: 2px 0 0 12px;
  position: sticky;
  top: -1px;
}
dd {
  font: bold 20px/45px Helvetica, Arial, sans-serif;
  margin: 0;
  padding: 0 0 0 12px;
  white-space: nowrap;
}
dd + dd {
  border-top: 1px solid #CCC
}

效果:

我们这里出现了多个需要定位的元素,他们会依次覆盖上面的sticky定位元素。

并且这里我们嵌套了两层box,具有滚动的元素在外层的box,sticky作用的区域不一定时父级,而是祖先带有滚动机制的元素。

兼容:

position:sticky;
position:-webkit-sticky;

 

;