徹底理解粘性定位 - position: sticky

粘性定位可以被認(rèn)為是相對(duì)定位(position: relative)和固定定位(position: fixed)的混合。元素在跨越特定閾值前為相對(duì)定位,之后為固定定位。例如:

.sticky-header {  position: sticky;  top: 10px; }

在 視口滾動(dòng)到元素 top 距離小于 10px 之前,元素為相對(duì)定位。之后,元素將固定在與頂部距離 10px 的位置,直到視口回滾到閾值以下。

粘性定位常作用在導(dǎo)航和概覽信息(標(biāo)題,表頭,操作欄,底部評(píng)論等)上。這樣,用戶在瀏覽詳細(xì)信息時(shí),也能看到信息的概覽和做一些操作,給用戶帶來便捷的使用體驗(yàn)。

粘性定位看著很簡(jiǎn)單,但也很容易出現(xiàn)不生效的情況。為幫助大家徹底理解粘性定位,本文會(huì)從 3 個(gè)方面來介紹:

  • 粘性定位的原理。
  • 不生效的情況。
  • 具體的例子。

原理

為便于理解粘性定位,這里引入四個(gè)元素:視口元素,容器元素,粘性約束元素 和 sticky 元素。它們的關(guān)系如下:


視口元素:顯示內(nèi)容的區(qū)域。會(huì)設(shè)置寬,高。一般會(huì)設(shè)置 overflow:hidden。
容器元素:離 sticky 元素最近的能滾動(dòng)的祖先元素。
粘性約束元素:粘性定位的父元素。有時(shí),也會(huì)出現(xiàn)粘性約束元素就是容器元素的情況。
sticky 元素:設(shè)置了 position: sticky; 的元素。

滾動(dòng)時(shí),sticky 元素設(shè)置的 left, right, top, bottom 的值相對(duì)的是容器元素。當(dāng)粘性約束元素滾出視口時(shí),sticky 元素也會(huì)滾出視口。

不生效的情況

情況1: 未指定 top, right, top 和 bottom 中的任何一個(gè)值

此時(shí),設(shè)置 position: sticky 相當(dāng)于設(shè)置 position: relative。

要生效,要指定 top, right, top 或 bottom 中的任何一個(gè)值。

情況2: 垂直滾動(dòng)時(shí),粘性約束元素高度小于等于 sticky 元素高度

不生效的原因:當(dāng)粘性約束元素滾出視口時(shí),sticky 元素也會(huì)滾出視口。粘性約束元素比 sticky 元素還小,sticky 元素沒有顯示固定定位狀態(tài)的機(jī)會(huì)。

同樣的,水平滾動(dòng)時(shí),粘性約束元素寬度小于等于 sticky 元素寬度時(shí),也不會(huì)生效。

情況3: 粘性約束元素和容器元素之間存在 overflow: hidden 的元素

該情況的示例代碼:

<div class="viewport">
  <div class="container"> <!-- 容器元素 -->
    <div style="overflow: hidden">
      <div> <!-- 粘性約束元素 -->
        <div class="stick-elem">...</div>  <!-- sticky 元素 -->
        ...
      </div>
    </div>
  </div>
</div>

要生效,要把 overflow: hidden 的元素移除。

具體的例子

例子1: 頁面滾動(dòng)

這個(gè)例子,我們來實(shí)現(xiàn)頁面滾動(dòng)到文章內(nèi)容時(shí),文章標(biāo)題吸頂?shù)男Ч?/p>

HTML 結(jié)構(gòu)如下:

<div class="header">網(wǎng)站頭部</div>
<!-- 粘性約束元素 -->
<div class="article">
  <!-- sticky 元素 -->
  <h2 class="title">徹底理解粘性定位 - position: sticky</h2>
  <div class="content">...</div>
</div>
<div class="footer">網(wǎng)站底部</div>

在這個(gè)例子中,視口元素和容器元素都是 body。sticky 元素是 .title,因此只要在 sticky 元素上設(shè)置如下樣式即可:

.title {
  position: sticky;
  top: 0;
  background-color: #fff;
}

例子2: 文章列表

這個(gè)例子,我們來實(shí)現(xiàn)一塊區(qū)域下有多篇文章,區(qū)域滾動(dòng)到文章內(nèi)容時(shí),對(duì)應(yīng)的標(biāo)題和操作按鈕吸頂?shù)男Ч?/p>

HTML 結(jié)構(gòu)如下:

<!-- 視口元素 -->
<div class="viewport">
  <!-- 容器元素 -->
  <div class="container">
    <!-- 文章:粘性約束元素 -->
    <div class="article">
      <div class="sticky-header">
        <h2>徹底理解粘性定位 - position: sticky</h2>
        <div class="options">
          <button>轉(zhuǎn)發(fā)</button>
          <button>點(diǎn)贊</button>
        </div>
      </div>
      <div class="article-content">...</div>
  </div>
  <!-- 文章 -->
  <div class="article">...</div>
  <div class="article">...</div>
</div>

在這個(gè)例子中,視口元素是 .viewport,容器元素是 .container。sticky 元素是 .sticky-header。核心樣式如下:

/* 視口元素 */
.viewport {
  width: 50%;
  overflow: hidden;
  height: 200px;
}
/* 容器元素 */
.container {
  overflow: auto;
  height: 100%;
}
/* 粘性約束元素 */
.article {
  margin-bottom: 10px;
}
/* sticky 元素 */
.sticky-header {
  position: sticky;
  top: 0;
  padding: 5px 0;
  background-color:#fff;
}

例子3: 甘特圖

最后,我們來做個(gè)復(fù)雜點(diǎn)的例子:甘特圖。如下圖所示:

需要實(shí)現(xiàn):

  • 左側(cè)事項(xiàng)菜單總在最左側(cè)。
  • 菜單的頭部和時(shí)間軸吸頂。
  • 時(shí)間軸的年總在月的最左邊。

實(shí)現(xiàn)代碼有點(diǎn)多,就不在這里貼了。獲取完整源碼,關(guān)注公眾號(hào): 前端GOGOGO,回復(fù): 粘性定位。

最后

粘性定位的瀏覽器兼容性也很好:95.76% 的瀏覽器支持[1]。大家可以放心的使用~

推薦閱讀:

  • position:sticky 粘性定位的幾種巧妙應(yīng)用[2]

參考資料

[1]95.76% 的瀏覽器支持: https://caniuse.com/css-sticky
[2]position:sticky 粘性定位的幾種巧妙應(yīng)用: https://segmentfault.com/a/1190000039858711

原文:https://jishuin.proginn.com/p/763bfbd62bc0

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容