成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

純CSS實現電梯導航!

開發 前端
通常要實現這樣一個交互肯定少不了JS,常規的做法是監聽滾動事件,也可以用IntersectionObserver監聽元素的滾動位置狀態。

我們經常會在博客、文檔中看到類似這樣的側邊導航目錄,例如:

這種導航也被稱為“電梯導航”(當然可能還有其他叫法,知道是這個交互就行)。它會隨著內容的滾動而自動切換當前選中態,點擊任意目錄也會自動滾動到對應標題,就像這樣。

通常要實現這樣一個交互肯定少不了JS,常規的做法是監聽滾動事件,也可以用IntersectionObserver監聽元素的滾動位置狀態,下面有一篇關于用IntersectionObserver的實現。

嘗試使用JS IntersectionObserver讓標題和導航聯動:https://www.zhangxinxu.com/wordpress/2020/12/js-intersectionobserver-nav 。

大家可能也發現了,這個交互最大的特點就是滾動,是不是也可以聯想到 CSS滾動驅動動畫呢?經過一番嘗試,發現純 CSS也能完美實現,而且實現更加簡單(不到10行),下面是我復刻的效果。

是不是非常神奇?CSS 還能實現這樣的效果?一起看看吧!

一、CSS 滾動錨定

這個導航主要有兩個交互:

  • 點擊導航會自動滾動到頁面對應位置。
  • 頁面滾動會自動切換導航選中態。

第一條比較容易,我們可以直接用a標簽的能力實現錨定跳轉。假設HTML結構如下:

<nav>
  <a>一、標題一</a>
  <a>二、標題二</a>
  <a>三、標題三</a>
  <a>四、標題四</a>
  <a>五、標題五</a>
  <a>六、標題六</a>
</nav>
<h1>CSS 電梯導航</h1>
<div class="content">
  <h2>一、標題一</h2>
  <section>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
  </section>
</div>
<div class="content">
  <h2>二、標題二</h2>
  <section>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
  </section>
</div>
<div class="content">
  <h2>三、標題三</h2>
  <section>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
  </section>
</div>
<div class="content">
  <h2>四、標題四</h2>
  <section>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
  </section>
</div>
<div class="content">
  <h2>五、標題五</h2>
  <section>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
  </section>
</div>
<div class="content">
  <h2>六、標題六</h2>
  <section>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
  </section>
</div>

然后簡單修飾一下。

body{
  padding: 0 15px;
}
h2{
  margin: 0;
  padding: .8em 0;
  scroll-margin: 20px;
}
nav{
  position: fixed;
  top: 15px;
  right: 15px;
  background: #fff;
  padding: 10px 0;
  border-radius: 4px;
  overflow: hidden;
}
nav>a{
  position: relative;
  display: block;
  line-height: 2;
  padding: 0 15px;
  font-size: 14px;
  color: #191919;
  text-decoration: none;
}
nav>a:hover{
  background-color: #d5d5d54a;
}
section{
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
section span{
  width: 30%;
  height: 100px;
  border-radius: 4px;
  background-color: #E4CCFF;
}

效果如下:

然后我們只需要給a標簽添加href屬性,頁面相對應的地方指定相同的id,就像這樣。

<nav>
  <a href="#t1">一、標題一</a>
  <a href="#t2">二、標題二</a>
	...
</nav>
<div class="content">
  <h2 id="t1">一、標題一</h2>
  <section>
    ...
  </section>
</div>
<div class="content">
  <h2 id="t2">二、標題二</h2>
  <section>
    ...
  </section>
</div>

這樣點擊a標簽會自動錨點到對應位置,效果如下:

這樣就能跳轉了,如果你覺得有點生硬,可以加入滾動動畫。

body{
  /**/
  scroll-behavior: smooth;
}

這樣就平滑多了。

這樣就實現了滾動錨定效果,還算比較容易。

下面來看如何實現滾動聯動效果。

二、CSS 滾動驅動動畫

我們可以想一下,如果是IntersectionObserver該如何做呢?沒錯,就是監聽每一塊區域的出現時機,然后改變導航的狀態。

剛好CSS滾動驅動動畫中的view-timeline可以實現類似的效果。它可以「監測到元素在可視區」的情況。

不過,單獨依靠view-timeline還不行,因為默認情況下,CSS 滾動驅動作用范圍只能影響到子元素,而我們的dom結構明顯是分離的。

<nav>
  <a href="#t1">一、標題一</a>
  <a href="#t2">二、標題二</a>
	...
</nav>

<div class="content">
  <h2 id="t1">一、標題一</h2>
  <section>
    ...
  </section>
</div>
<div class="content">
  <h2 id="t2">二、標題二</h2>
  <section>
    ...
  </section>
</div>

為了解決這個問題,我們需要用到 CSS 時間線范圍,也就是 timeline-scope。

https://developer.mozilla.org/en-US/docs/Web/CSS/timeline-scope

這里簡單介紹一下,假設有這樣一個結構。

<div class="content">
  <div class="box animation"></div>
</div>

<div class="scroller">
  <div class="long-element"></div>
</div>

這是兩個元素,右邊的是滾動容器,左邊的是一個可以旋轉的矩形。

我們想實現滾動右邊區域時,左邊矩形跟著旋轉,如何實現呢?

可以給他們共同的父級,比如body定義一個timeline-scope。

body{
  timeline-scope: --myScroller;
}

然后,滾動容器的滾動和矩形的動畫就可以通過這個變量關聯起來了。

.scroller {
  overflow: scroll;
  scroll-timeline-name: --myScroller;
  background: deeppink;
}
.animation {
  animation: rotate-appear;
  animation-timeline: --myScroller;
}

效果如下:

這樣就實現任意元素間的滾動聯動。

回到這里,我們要做的事情其實很簡單,給父級(body)定義多個timeline-scope,然后給內容區域和導航區域都綁定一個相同CSS變量,具體做法如下:

<body style="timeline-scope: --t1,--t2,--t3,--t4,--t5,--t6;">
  <nav>
    <a href="#t1" style="--s: --t1">一、標題一</a>
    <a href="#t2" style="--s: --t2;">二、標題二</a>
    <a href="#t3" style="--s: --t3">三、標題三</a>
    <a href="#t4" style="--s: --t4">四、標題四</a>
    <a href="#t5" style="--s: --t5">五、標題五</a>
    <a href="#t6" style="--s: --t6">六、標題六</a>
  </nav>
  <h1>CSS 電梯導航</h1>
  <div class="content" style="--s: --t1">
    <h2 id="t1">一、標題一</h2>
    <section>
      ...
    </section>
  </div>
  <div class="content" style="--s: --t2">
    <h2 id="t2">二、標題二</h2>
    <section>
      ...
    </section>
  </div>
  <div class="content" style="--s: --t3">
    <h2 id="t3">三、標題三</h2>
    <section>
      ...
    </section>
  </div>
  <div class="content" style="--s: --t4">
    <h2 id="t4">四、標題四</h2>
    <section>
      ...
    </section>
  </div>
  <div class="content" style="--s: --t5">
    <h2 id="t5">五、標題五</h2>
    <section>
      ...
    </section>
  </div>
  <div class="content" style="--s: --t6">
    <h2 id="t6">六、標題六</h2>
    <section>
      ...
    </section>
  </div>

然后給內容區域添加view-timeline-name,導航標簽添加 animation-timeline,讓這兩者關聯起來,也就是內容滾動時,導航的動畫跟著執行,這里的動畫很簡單,就是改變導航鏈接的文字顏色和邊框顏色,關鍵實現如下:

.content{
  view-timeline-name: var(--s);
}
nav>a{
  /**/
  animation: active;
  animation-timeline: var(--s);
}
@keyframes active {
  0%,100% {
    color: #6f00ff;
    border-color: #6f00ff;
  }
}

效果如下:

這樣滾動聯動效果基本就出來了,不過還是有些小問題,接著優化。

三、CSS 滾動視區范圍

前面的實現其實還個小問題,右邊的導航會同時選中多個。

很明顯是因為左側的內容同時出現了這兩部分區域。

如果每一塊內容高度更少,那同時選中的就更多了,就像這樣。

而我們需要的肯定是同一時刻只選中一個導航,你可以自己定義規則,比如后面的優先于前面的。

那CSS該如何實現這樣的效果呢?

其實,這里需要換一種思維,上面的實現之所以會同時出現多個選中,是因為視區范圍太大,是整個屏幕,所以可以同時匹配到多個內容區域。

因此,我們可以手動的減少視區范圍,一直減少成一條線,這樣無論怎樣滾動,都只會匹配一個區域。

在這里,我們可以通過view-timeline-inset來手動改變視區范圍,默認是0。

比如我們希望以滾動區域中間為分割線,只要滾動到達這個點,就高亮當前導航,可以這樣實現。

.content{
  view-timeline-name: var(--s);
  view-timeline-inset: 50%; /*完整寫法是 50% 50%*/
}

為了方便演示,我在滾動區域中間加了一條紅色的線,便于觀察。

可以很清楚的發現,只要越過這條線,導航馬上觸發高亮選中。

當然你也可以自己調整這個臨界線,比如下面的表示在距離滾動區域底部30%的地方做判斷。

.content{
  view-timeline-name: var(--s);
  view-timeline-inset: 70% 30%; 
}

這樣就實現了我們想要的效果了,你也可以訪問以下在線鏈接查看實際效果(chrome 116+)。

  • CSS 電梯導航 (codepen.io)[1]
  • CSS 電梯導航 (juejin.cn)[2]

四、兼容性和總結

看似這么多,其實核心代碼就這幾行。

body{
  timeline-scope: --t1,--t2,--t3,--t4,--t5,--t6;
}
.content{
  view-timeline-name: var(--s);
  view-timeline-inset: 50%;
}
nav>a{
  animation: active;
  animation-timeline: var(--s);
}
@keyframes active {
  0%,100% {
    color: #6f00ff;
    border-color: #6f00ff;
  }
}

包括在HTML中的幾行自定義變量,是不是還不到 10 行?相比 JS實現,代碼更簡單,性能也更好,無需初始化,也不用等待 dom 加載,擴展性也強。

唯一的缺點可能是兼容性不足,由于依賴timeline-scope,所以必須Chrome 116+,完整兼容性如下:

下面總結一下

  • 滾動錨定可以借助a標簽和#id實現自動滾動跳轉。
  • scroll-behavior: smooth可以實現平滑滾動。
  • 默認情況下,CSS 滾動驅動作用范圍只能影響到子元素,但是通過timeline-scope,可以讓任意元素都可以受到滾動驅動的影響。
  • 利用timeline-scope,我們可以將每個內容的位置狀態和每個導航的選中狀態聯動起來。
  • 右邊的導航會同時選中多個是因為左邊的滾動視區太大了,可以同時包含多個內容區域。
  • 可以用view-timeline-inset來手動改變視區范圍,縮小成一條線,這樣無論怎樣滾動,都只會匹配一個區域
  • 兼容性還不足,目前是Chrome 116+。

總的來說,CSS滾動驅動動畫不愧是2023年度最強特性,可以做的事情太多了,很多 JS才能實現的交互都可以取代了,而且做的更好,至于兼容性,還是留給時間吧。

[1]CSS 電梯導航 (codepen.io): https://codepen.io/xboxyan/pen/zYVBEWq。

[2]CSS 電梯導航 (juejin.cn): https://code.juejin.cn/pen/7396195867155562508。

責任編輯:姜華 來源: 前端偵探
相關推薦

2021-10-19 22:23:47

CSSBeautiful按鈕

2022-02-21 07:02:16

CSSbeautiful按鈕

2013-04-08 14:07:28

CSS

2022-08-10 16:08:38

鴻蒙CSS

2020-11-04 13:55:06

CSS密室逃脫前端

2021-01-19 12:16:10

CSS前端UI

2022-08-29 17:39:53

應用開發css動畫

2017-04-27 14:05:59

CSS動畫前端

2023-10-23 08:48:04

CSS寬度標題

2021-01-25 06:37:06

Css前端CSS 特效

2015-04-24 10:05:15

HTML+CSS阿童木頭像

2024-05-09 00:00:00

CSS標簽JavaScript

2010-09-13 14:32:39

CSS橫向導航

2010-09-13 14:17:42

CSS縱向導航菜單

2022-08-04 06:57:54

CSS拼圖游戲

2024-07-31 20:38:18

2023-04-17 09:08:27

CSS計時器

2021-02-09 07:26:38

前端css技術熱點

2021-08-23 06:25:57

CSS 技巧animation

2023-07-03 08:51:41

選擇器detailssummary
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日日草天天干 | 日日夜夜视频 | 91精品国产91久久久久福利 | 色偷偷噜噜噜亚洲男人 | 欧美一区在线视频 | 日本一区二区三区四区 | 国产日韩欧美在线观看 | 欧美日韩视频在线第一区 | 国产蜜臀 | 精品久久国产老人久久综合 | 涩涩鲁亚洲精品一区二区 | 中文字幕av色 | 日日碰狠狠躁久久躁96avv | 久久久精品一区二区三区 | 欧美阿v | 国产精品一级在线观看 | 羞羞视频网站免费观看 | 91porn国产成人福利 | 国产高清一区二区三区 | 视频在线一区二区 | 成人一区在线观看 | 精品国产乱码久久久久久闺蜜 | 久久精品国产亚洲a | 午夜视频一区二区 | 亚洲一区二区视频在线播放 | 成人一区二区三区视频 | 成年免费在线观看 | 欧美一区二区三区久久精品 | 欧美区日韩区 | 国产精品视频观看 | 国产精品精品视频一区二区三区 | 亚洲国产精品一区二区三区 | 久草欧美 | 日韩在线视频网址 | 免费黄色特级片 | 久久中文字幕一区 | 毛片免费在线 | 国产日韩欧美激情 | 中文字幕日韩欧美一区二区三区 | 国产免费福利在线 | 成人三级av|