CSS 固定頁首 (Sticky Header)

固定頁首讓導航列在捲動頁面時始終顯示在視窗頂部,方便使用者隨時存取導航連結。

position: fixed

最傳統的方式,讓元素固定在視窗位置:

.header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 60px;
  background: white;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  z-index: 100;
}

/* 重要:為內容留出空間 */
body {
  padding-top: 60px;
}

position: sticky

較新的方式,元素在捲動到指定位置時才固定:

.header {
  position: sticky;
  top: 0;
  background: white;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  z-index: 100;
}
使用 sticky 不需要為 body 加 padding-top,因為元素在固定前仍佔據空間。

sticky vs fixed 差別

特性position: fixedposition: sticky
脫離文件流否(固定前)
需要 padding-top
捲動行為始終固定到達位置才固定
瀏覽器支援全部現代瀏覽器

完整範例

基本固定導航

.navbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 60px;
  background: white;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
  z-index: 1000;
}

.navbar .logo {
  font-size: 20px;
  font-weight: bold;
}

.navbar .nav-links {
  display: flex;
  gap: 24px;
}

body {
  padding-top: 60px;
}

透明變實色

捲動時導航列從透明變成有背景:

.navbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 80px;
  background: transparent;
  transition: background-color 0.3s, box-shadow 0.3s;
  z-index: 1000;
}

.navbar.scrolled {
  background: white;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
// JavaScript 偵測捲動
window.addEventListener('scroll', function() {
  const navbar = document.querySelector('.navbar');
  if (window.scrollY > 50) {
    navbar.classList.add('scrolled');
  } else {
    navbar.classList.remove('scrolled');
  }
});

隱藏/顯示導航

向下捲動時隱藏,向上捲動時顯示:

.navbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 60px;
  background: white;
  transform: translateY(0);
  transition: transform 0.3s;
  z-index: 1000;
}

.navbar.hidden {
  transform: translateY(-100%);
}
let lastScroll = 0;

window.addEventListener('scroll', function() {
  const navbar = document.querySelector('.navbar');
  const currentScroll = window.scrollY;
  
  if (currentScroll > lastScroll && currentScroll > 100) {
    // 向下捲動
    navbar.classList.add('hidden');
  } else {
    // 向上捲動
    navbar.classList.remove('hidden');
  }
  
  lastScroll = currentScroll;
});

縮小導航

捲動時導航列高度縮小:

.navbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 80px;
  background: white;
  transition: height 0.3s;
  z-index: 1000;
}

.navbar.compact {
  height: 60px;
}

.navbar .logo {
  font-size: 24px;
  transition: font-size 0.3s;
}

.navbar.compact .logo {
  font-size: 18px;
}

全寬 vs 置中

/* 全寬 */
.navbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  padding: 0 24px;
}

/* 置中內容 */
.navbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}

.navbar-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

毛玻璃效果

.navbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 60px;
  background: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  z-index: 1000;
}

響應式考量

.navbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 60px;
  z-index: 1000;
}

/* 行動版可以考慮使用 sticky */
@media (max-width: 768px) {
  .navbar {
    position: sticky;
  }
  
  body {
    padding-top: 0;    /* sticky 不需要 padding */
  }
}

注意事項

  • fixed 元素會脫離文件流,記得為內容加上對應的 padding-top
  • z-index 要足夠大,確保在其他元素上方
  • 考慮加上 box-shadow 增加層次感
  • 背景色要設定,否則內容會透出來