这里我们不讨论position其他的:static,fixed,relative和absolute几个属性了,之讨论sticky的特性
sticky:
元素根据正常文档流进行定位,然后相对它的最近滚动祖先(nearest scrolling ancestor)和containing block(最近块级祖先 nearest block-level ancestor),包括table-related元素,基于top
, right
, bottom
, 和 left
的值进行偏移。偏移值不会影响任何其他元素的位置。
该值总是创建一个新的 Stacking context(层叠上下文)。注意,一个sticky元素会“固定”在离它最近的一个拥有“滚动机制”的祖先上(当该祖先的overflow
是 hidden
, scroll
, auto
, 或 overlay
时),即便这个祖先不是真的滚动祖先。
overlay:行
为与auto
相同,但滚动条绘制在内容之上而不是占用空间。 仅在基于WebKit(例如,Safari)和基于Blink的(例如,Chrome或Opera)浏览器中受支持
粘性定位
粘性定位可以被认为是相对定位和固定定位的混合。元素在跨越特定阈值前为相对定位,跨越之后为固定定位。例如:
#one { position: sticky; top: 10px; }
在 viewport 视口滚动到元素 top 距离小于 10px 之前,元素为相对定位。之后,元素将固定定位在与顶部距离 10px 的位置,直到 viewport 视口回滚到阈值以下。
必要条件
- 须指定top,right,bottom,left四个阈值其中之一,才可使粘性定位生效。否则其行为与相对定位相同。
- 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;