搜尋

純 CSS 視差滾動效果

這篇教學會運用 background-attachment 固定背景、sticky 黏貼定位以及 animation-timeline 控制動畫進度等方法,使用純粹的 CSS 製作視差滾動效果。

注意,這個效果目前僅支援 Chrome 和 Edge,其他部分瀏覽器或行動裝置瀏覽器可能不支援。

快速導覽:

CSS 教學 - CSS 視差滾動效果

background-attachment:fixed 固定背景視差滾動

使用 background-attachment: fixed 可以「固定」背景,當其他元素因捲軸捲動覆蓋背景時,就會出現簡單的視差滾動效果,雖然這個做法很簡單,但因為 fixed 屬性質會以 body 為參考依據,所以只能處理單一張或少量圖片,如果要進行多張圖片不同位置的視差滾動,或要進行位置或尺寸修改,就必須撰寫額外的 CSS 或透過 animation-timeline 或 JavaScript 輔助才能實現。

下方範例會使用一個寬度為 400px 的 div 模擬有捲軸的網頁,展示固定背景的視差滾動效果。

<!-- HTML 程式碼 -->
<div class="main">
  <div class="banner"></div>
  <div class="contain">CSS 教學會透過一系列的文章和許多由淺入深的範例,介紹 CSS 的相關知識,從 CSS 的基本概念、選擇器的應用一直到排版佈局、動畫效果都有完整介紹,希望對於網頁初學者、網頁設計師、甚至是網頁前端工程師,提供非常有幫助的知識內容。</div>
</div>

<!-- CSS 程式碼 -->
<style>
  div {box-sizing: border-box;}
  .main {
    width: 400px;
    height: 400px;
    border: 1px solid #000;
    overflow: scroll;   /* 模擬視窗,超過範圍出現捲軸 */
  }
  .banner {
    width: 100%;
    aspect-ratio: 3/2;   /* 元素保持 3:2 比例 */
    background-image: url("https://steam.oxxostudio.tw/image/index-css.jpg");
    background-size: 400px;         /* 背景寬度 */
    background-attachment: fixed;   /* 背景固定 */
  }
  .contain{
    padding: 10px;
    width: 100%;
    height: 500px;
  }
</style>

CSS 教學 - CSS 視差滾動效果 - background-attachment:fixed 固定背景視差滾動

position: sticky 黏貼定位視差滾動

position: sticky 黏貼定位是個很特別的排版樣式,同時具備了 relativefixed 的效果,當黏貼定位的元素指定了 top 之類的位置距離樣式,就會在元素抵達顯示畫面的該位置時,觸發為類似 fixed 的樣式,當元素的父元素底部碰觸到元素時,又會回復 relative 的行為*,對於使用「多種圖片」或「多層區塊」的單頁式網頁而言,是製作視差滾動相當方便的做法。

下方範例會使用一個寬度為 400px 的 div 模擬有捲軸的網頁,展示黏貼定位的視差滾動效果,當中運用 z-index 讓後方元素可以覆蓋前方。

<!-- HTML 程式碼 -->
<div class="main">
  <div class="parallax">
    <img class="img-a" src="https://steam.oxxostudio.tw/image/index-css.jpg">
    <img class="img-b" src="https://steam.oxxostudio.tw/download/css/function-filter-demo.png">
    <div class="note-1">CSS 教學會透過一系列的文章和許多由淺入深的範例,介紹 CSS 的相關知識,從 CSS 的基本概念、選擇器的應用一直到排版佈局、動畫效果都有完整介紹,希望對於網頁初學者、網頁設計師、甚至是網頁前端工程師,提供非常有幫助的知識內容。</div>
    <img class="img-c" src="https://steam.oxxostudio.tw/download/python/line-template-message-demo2.jpg">
    <div class="note-2">大家好,我是 OXXO,是個即將邁入中年的斜槓青年。如果大家有課程講師、研習授課、寫作、書籍出版、產品顧問、網站顧問...等需求,都可以與我聯繫,一起來做點又酷、又好玩、又有創意的東西吧!</div>
  </div>
  <div class="contain"></div>
</div>

<!-- CSS 程式碼 -->
<style>
  div {box-sizing: border-box;}
  .main {
    width: 400px;
    height: 500px;
    border: 1px solid #000;
    overflow: scroll;   /* 模擬視窗,超過範圍出現捲軸 */
  }
  .parallax {
    width: 100%;
    margin-bottom: 30px;
    text-align: center;
  }
  .parallax * {
    position: sticky;  /* 內容元素都是黏貼定位 */
    width: 100%;
  }
  .img-a {
    z-index: 1;
    top: 0;            /* 遇到 top 為 0 時黏貼 */
  }
  .img-b {
    width: 100px;
    z-index: 2;
    margin-top: -50px;
    top: 20px;         /* 遇到 top 為 20px 時黏貼 */
  }
  .note-1, .note-2{
    top: 0;            /* 遇到 top 為 0 時黏貼 */
    z-index: 3;
    padding: 10px;
    background: #fffc;
  }
  .img-c {
    z-index: 4;
    top: 0;           /* 遇到 top 為 0 時黏貼 */
  }
  .note-2{z-index: 5;}
  .contain{
    width: 100%;
    height: 500px;
  }
</style>

CSS 教學 - CSS 視差滾動效果 - position: sticky 黏貼定位視差滾動

animation-timeline 動畫時間軸視差滾動

animation-timeline 是一個可以運用「元素在可視範圍中的位置」或「捲軸位置」控制「動畫進度」的樣式,隨著瀏覽器支援度的提升,逐漸取代了使用 JavaScript 獲取位置或捲軸資訊的能力,使用方式需要先定義動畫內容,設定將元素改變過程的位置或尺寸,接著根據需求使用 view()scroll() 將動態的位置對應到元素的時間軸,就能產生非常漂亮的視差滾動效果,下方範例會定義三組動畫,並會根據捲軸下拉的程度,執行不同的動畫進度。

注意,目前除了 Chrome 與 Edge,其他瀏覽器可能不支援這個樣式屬性!

<!-- HTML 程式碼 -->
<div class="main">
  <div class="parallax">
    <div class="ball b1"><div></div><div></div><div></div><div></div><div></div></div>
    <div class="ball b2"><div></div><div></div><div></div><div></div><div></div></div>
    <div class="ball b3"><div></div><div></div><div></div><div></div><div></div></div>
    <h1>OXXO.STUDIO</h1>
  </div>
  <div class="contain"></div>
</div>

<!-- CSS 程式碼 -->
<style>
  div {position: relative;}
  .main {
    width: 400px;
    height: 400px;
    border: 1px solid #000;
    overflow: scroll;        /* 模擬視窗,超過範圍出現捲軸 */
  }
  .main > * {width: 100%;}
  .contain {height: 500px;}
  .parallax {
    height: 300px;
    background: #06a;
  }
  .parallax * {position: absolute;} /* 內容元素都是絕對定位 */

  .ball {
    top: 0;
    width: 100%;
    height: 100%;
  }
  .ball * {border-radius: 50%;}

  .b1 {
    animation: oxxo forwards;     /* 名稱 oxxo,動畫結束後保持在最後一格 */
    animation-range: 0 500px;     /* 捲軸下拉範圍 0~500px 對應動畫的 0%~100% */
    animation-timeline: scroll(); /* 捲軸控制動畫進度 */
  }
  .b1 * {
    width: 30px;
    height: 30px;
    background: #fff3;
  }
  .b1 div:nth-child(1){top:120px; left: 50px;}
  .b1 div:nth-child(2){top:70px; left: 150px;}
  .b1 div:nth-child(3){top:90px; left: 300px;}
  .b1 div:nth-child(4){top:170px; left: 200px;}
  .b1 div:nth-child(5){top:220px; left: 20px;}

  .b2 {
    animation: oxxo forwards;     /* 名稱 oxxo,動畫結束後保持在最後一格 */
    animation-range: 0 400px;     /* 捲軸下拉範圍 0~400px 對應動畫的 0%~100% */
    animation-timeline: scroll(); /* 捲軸控制動畫進度 */
  }
  .b2 * {
    width: 40px;
    height: 40px;
    background: #fff6;
  }
  .b2 div:nth-child(1){top:40px; left: 50px;}
  .b2 div:nth-child(2){top:80px; left: 150px;}
  .b2 div:nth-child(3){top:50px; left: 250px;}
  .b2 div:nth-child(4){top:220px; left: 250px;}
  .b2 div:nth-child(5){top:170px; left: 50px;}

  .b3 {
    animation: oxxo forwards;     /* 名稱 oxxo,動畫結束後保持在最後一格 */
    animation-range: 0 300px;     /* 捲軸下拉範圍 0~300px 對應動畫的 0%~100% */
    animation-timeline: scroll(); /* 捲軸控制動畫進度 */
  }
  .b3 * {
    width: 60px;
    height: 60px;
    background: #fff9;
  }
  .b3 div:nth-child(1){top:70px; left: 80px;}
  .b3 div:nth-child(2){top:60px; left: 200px;}
  .b3 div:nth-child(3){top:120px; left: 300px;}
  .b3 div:nth-child(4){top:220px; left: 180px;}
  .b3 div:nth-child(5){top:200px; left: 80px;}

  h1 {
    animation: oxxo forwards;     /* 名稱 oxxo,動畫結束後保持在最後一格 */
    animation-range: 0 500px;     /* 捲軸下拉範圍 0~500px 對應動畫的 0%~100% */
    animation-timeline: scroll(); /* 捲軸控制動畫進度 */
  }
  h1 {
    margin-top: 120px;
    width: 100%;
    color: white;
    text-align: center;
  }
  /* 動畫定義 */
  @keyframes oxxo {
    0% {top: 0;}
    100% {top: -200px;}
  }
</style>

CSS 教學 - CSS 視差滾動效果 - animation-timeline 動畫時間軸視差滾動

除了單純的控制元素位置,也可以搭配「sprite 圖片」,實作透過捲軸控制的動畫效果,下方範例會用一張 3D 地球的 sprite 圖片,搭配動畫速度 animation-timing-function: step-start;,就能在拖拉捲軸時,呈現地球轉動的動畫,此外在搭配上述的 position: sticky,就能做出更別致的視差滾動。

<!-- HTML 程式碼 -->
<div class="main">
  <div class="banner">
    <div class="earth"></div>
  </div>
  <div class="contain">
    <h2>STEAM 教育學習網</h2>
    STEAM 教育學習網秉持著 STEAM/STEM 的精神,透過一系列免費且高品質的教學與範例,讓所有人都能輕鬆跨入 STEAM 的學習領域。
    <h2>CSS 教學</h2>
    CSS 教學會透過一系列的文章和許多由淺入深的範例,介紹 CSS 的相關知識,從 CSS 的基本概念、選擇器的應用一直到排版佈局、動畫效果都有完整介紹,希望對於網頁初學者、網頁設計師、甚至是網頁前端工程師,提供非常有幫助的知識內容。
  </div>
</div>

<!-- CSS 程式碼 -->
<style>
  div {box-sizing: border-box;}
  .main {
    position: relative;
    width: 400px;
    height: 400px;
    border: 1px solid #000;
    overflow: scroll;        /* 模擬視窗,超過範圍出現捲軸 */
  }
  .banner {
    width: 100%;
    height: 300px;
    background: white;
  }
  .earth {
    position: sticky;        /* 黏貼定位,讓地球一開始固定不動 */
    margin: 0 auto;
    top: 100px;
    width: 87px;
    height: 87px;
    scale: 2;
    background: url("https://steam.oxxostudio.tw/download/css/animate-sprites.jpg");
    background-position: 0 0;
    animation: oxxo step-start;   /* 使用 step-start 讓進度一格格移動 */
    animation-timeline: scroll(); /* 根據捲軸滾動改變動畫進度 */
    animation-range: 0 300px;     /* 捲軸的 0~300px 對應動畫的 0~100% */
  }
  @keyframes oxxo {
    0.00% {background-position: 0 0;}
    3.34% {background-position: -100% 0;}
    6.67% {background-position: -200% 0;}
    10.01% {background-position: -300% 0;}
    13.35% {background-position: -400% 0;}
    16.68% {background-position: -500% 0;}
    20.02% {background-position: -600% 0;}
    23.36% {background-position: -700% 0;}
    26.69% {background-position: -800% 0;}
    30.03% {background-position: -900% 0;}
    33.37% {background-position: 0 -100%;}
    36.70% {background-position: -100% -100%;}
    40.04% {background-position: -200% -100%;}
    43.38% {background-position: -300% -100%;}
    46.71% {background-position: -400% -100%;}
    50.05% {background-position: -500% -100%;}
    53.39% {background-position: -600% -100%;}
    56.72% {background-position: -700% -100%;}
    60.06% {background-position: -800% -100%;}
    63.40% {background-position: -900% -100%;}
    66.73% {background-position: 0 -200%;}
    70.07% {background-position: -100% -200%;}
    73.41% {background-position: -200% -200%;}
    76.74% {background-position: -300% -200%;}
    80.08% {background-position: -400% -200%;}
    83.42% {background-position: -500% -200%;}
    86.75% {background-position: -600% -200%;}
    90.09% {background-position: -700% -200%;}
    93.43% {background-position: -800% -200%;}
    96.78% {background-position: -900% -200%;}
  }
  .contain {
    position: relative;
    z-index: 2;
    width: 100%;
    height: 400px;
    background: #252;
    padding: 20px;
    color: #fff;
  }
</style>

CSS 教學 - CSS 視差滾動效果 - animation-timeline 動畫時間軸搭配 sprite 圖片

如果搭配 CSS「3D 轉換」效果,也能透過捲軸位置讓畫面中的元素進行類似 3D 的轉動效果。

<!-- HTML 程式碼 -->
<div class="main">
  <div class="camera">
    <div class="space">
      <div class="a">oxxo</div>
      <div class="b">oxxo</div>
      <div class="c">oxxo</div>
    </div>
  </div>
  <div class="contain"></div>
</div>

<!-- CSS 程式碼 -->
<style>
  div {position: relative;}
  .main {
    width: 400px;
    height: 400px;
    border: 1px solid #000;
    overflow: scroll;        /* 模擬視窗,超過範圍出現捲軸 */
  }
  .contain {
    width: 100%;
    height: 500px;
    background: #fff;
  }
  .camera {
    z-index: 2;
    position: sticky;        /* 黏貼定位,讓位置固定 */
    top: 0px;
    width: 100%;
    height: 350px;
    perspective: 200px;           /* 透視距離 */
    perspective-origin: 50% 0%;   /* 透視中心 */
    animation: oxxo;              /* 對應動畫 */
    animation-timeline: scroll(); /* 根據捲軸滾動改變動畫進度 */
    animation-range: 0 200px;     /* 捲軸的 0~200px 對應動畫的 0~100% */
  }
  .space {
    width: 100%;
    transform-style: preserve-3d; /* 所有子元素位於同一個 3D 空間,使用座標系統位置排列 */
  }
  .a, .b, .c{
    position: absolute;
    top: 150px;
    left: 100px;
    width: 150px;
    height: 100px;
    color: white;
  }
  .a {
    transform: translateZ(10px);
    background: #09f;
  }
  .b {
    transform: rotateX(75deg);
    background: #f55;
  }
  .c {
    transform: rotateY(75deg);
    background: #f90;
  }
  @keyframes oxxo {
    0% {perspective-origin: 50% 0%;}
    100% {perspective-origin: 50% 150%;}
  }
</style>

CSS 教學 - CSS 視差滾動效果 - animation-timeline 動畫時間軸搭配 3D transform

小結

過去要製作精美的 CSS 視差滾動效果,不外乎都得依靠 JavaScript 來實現,但隨著瀏覽器的進步,純粹透過 CSS 也可以做出許多酷炫的視差滾動特效,如果有興趣不妨趕快試試看吧。

意見回饋

如果有任何建議或問題,可傳送「意見表單」給我,謝謝~

CSS 教學

基本介紹

認識 CSS 開始使用 CSS CSS 語法規則 CSS 命名原則 CSS 常用樣式屬性

CSS 選擇器

認識 CSS 選擇器 優先順序 ( 權重 ) 樣式繼承與聯集 使用巢狀結構語法 元素選擇器 ID 和 Class 選擇器 屬性選擇器 文件結構選擇器 虛擬類別選擇器 ( 結構 ) 虛擬類別選擇器 ( 類型 ) 虛擬類別選擇器 ( 輸入 ) 虛擬類別選擇器 ( 行為 ) 虛擬類別選擇器 ( 超連結 ) 虛擬類別選擇器 ( 邏輯 ) 虛擬類別選擇器 ( 其他 ) 虛擬元素選擇器 群組與組合選擇器

數值與單位

全域關鍵字與文字數值 長度與角度單位 位置名稱與時間單位 特殊樣式屬性 ( all、appearance)

規則與定義

變數 ( Variables ) 媒體查詢 ( @media ) 容器查詢 ( @container ) 自訂屬性值 ( @property ) 匯入樣式 ( @import ) 分層優先順序 ( @layer ) 定義字型 ( @font-face ) 計數規則 ( @counter-style ) 列印網頁 ( @page )

函式類型

數學計算 文字與清單計數 形狀與線段 路徑 ( path ) 生成內容與引號

顏色與濾鏡

顏色單位 色彩模型 漸層色 影像濾鏡 ( filter ) 背景濾鏡 ( backdrop-filter ) 混合模式 ( mix-blend-mode )

文字與段落

設定字型 ( font-family ) 使用外部字型 文字尺寸 文字樣式 ( 常用 ) 文字樣式 ( 其他實用 ) 文字樣式 ( 特殊用途 ) 文字換行 文字空白與 Tab 大小 文字行高與縮排 文字水平與垂直對齊 文字書寫方向 文字自動分欄

元素容器

容器顯示類型 ( display ) 元素 display 對照表 盒子模型 ( Box Model ) 寬度與高度 內邊距 ( padding ) 外邊界 ( margin ) 邊框 ( border ) 邊框圓角 ( border-radius ) 影像邊框 ( border-image ) 輪廓 ( outline ) 內容溢出與裁切 ( overflow ) 內容範圍 ( contain ) 可見性與透明度

背景與陰影

背景顏色 背景圖 ( 定位、尺寸 ) 背景圖 ( 固定、重複 ) 背景圖 ( 多重背景、混合 ) 背景縮寫 ( background ) 容器陰影 ( box-shadow )

清單與表格

清單樣式 清單計數器 表格基本樣式 表格邊框樣式 表格內容寬度與對齊

基本排版與定位

元素排版方式 浮動 ( float ) 浮動形狀 ( shape-* ) 定位 ( position ) 邏輯屬性 ( logical properties ) 水平置中技巧 垂直置中技巧

Flex 彈性排版

Flexbox 彈性盒子 Flex 對齊方式 Flex 彈性伸縮

Grid 網格排版

Grid 網格容器與格線 Grid 網格空間與命名 Grid 網格流向與間距 Grid 排列網格項目 Grid 項目對齊與順序

轉場與動畫

轉場 ( transition ) 轉場觸發事件 動畫 ( animation ) 自訂動畫路徑 ( offset ) 動畫觸發事件 多重動畫的權重與順序 動畫進度控制 ( timeline )

變形、裁切與遮罩

裁切路徑 ( clip-path ) 影像遮罩 ( mask ) 物件填滿方式與定位 轉換函式 ( transform ) 平移、旋轉與縮放 3D 轉換與透視

視窗與使用者行為

捲軸樣式 ( scrollbar ) 拉霸、滑桿樣式 ( slider ) 滑鼠游標圖示 ( cursor ) 滑鼠事件 ( pointer-events ) 使用者選取 ( user-select ) 捲動行為 ( scroll、overscroll ) 列印換頁 ( break-* )

範例效果

CSS 圓餅圖 CSS 跑馬燈 Google 載入動畫 漸層色的轉場與動畫 電子時鐘數字 不規則形狀動畫 3D 正多面體 超連結底線動畫效果 噁心黏黏球效果 CSS 視差滾動效果 捲軸控制放射形選單 捲軸改變文字背景色 CSS 頁面捲動進度條