Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> CSS

Thu nhỏ header khi cuộn (Shrink Header on Scroll) với CSS và JavaScript

Header co lại khi cuộn xuống là pattern phổ biến. Cần CSS transition cho mượt và JS detect vị trí cuộn.

Ví dụ mã nguồn

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
  body {
    font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
    margin: 0px;
    padding: 0px;
    height: 150vh;
  }
  .header {
    position: fixed;
    top: 0;
    width: 100%;
    background-color: rgb(52, 21, 110);
    color: white;
    padding: 50px;
    font-size: 40px;
    transition: all 0.3s ease; /* Mượt cho padding, font-size */
    z-index: 1000;
  }
  .header.shrunk {
    padding: 15px 50px;
    font-size: 20px;
    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
  }
</style>
</head>
<body>
<div class="header" id="header">Header Text</div>
<p style="font-size: 35px; margin-top: 150px;">Lorem ipsum dolor sit amet...</p>
<script>
  const header = document.getElementById('header');
  window.addEventListener('scroll', () => {
    if (window.scrollY > 50) {
      header.classList.add('shrunk');
    } else {
      header.classList.remove('shrunk');
    }
  });
</script>
</body>
</html>

Cải tiến so với ví dụ gốc

  • Dùng class .shrunk thay vì inline style - tách logic, dễ maintain
  • transition: all 0.3s ease - Mượt cho cả padding, font-size, box-shadow
  • window.scrollY - Cách hiện đại thay vì document.body.scrollTop
  • Debounce/Throttle - Nên thêm cho hiệu năng (ví dụ dùng requestAnimationFrame)

Phiên bản tối ưu hiệu năng (Throttle)

let ticking = false;
window.addEventListener('scroll', () => {
  if (!ticking) {
    window.requestAnimationFrame(() => {
      header.classList.toggle('shrunk', window.scrollY > 50);
      ticking = false;
    });
    ticking = true;
  }
});

Mở rộng

  • Ẩn/hiện logo, navigation khi shrunk
  • Thay đổi background opacity (blur backdrop-filter)
  • Progress bar đọc bài viết ở đỉnh