<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ブログ一覧レイアウト(サイドバー固定)</title>
<style>
/* 全体リセット */
body {
margin: 0;
font-family: Arial, sans-serif;
}
/* ヘッダー */
header {
background: #333;
color: #fff;
padding: 20px;
}
header nav ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
gap: 15px;
}
header nav ul li a {
color: #fff;
text-decoration: none;
}
/* 2カラムレイアウト */
.container {
display: flex;
padding: 20px;
}
.content {
flex: 3;
margin-right: 20px;
}
.post {
background: #f0f0f0;
padding: 15px;
margin-bottom: 20px;
height: 200px;
}
/* サイドバーラッパーで元のレイアウトスペースを確保 */
.sidebar-wrapper {
flex: 1 0 auto;
/* ※ position: relative; としておくと、JSで計算した left 位置も問題なく使えます */
position: relative;
}
/* サイドバー自体 */
.sidebar {
background: #fff;
padding: 15px;
box-shadow: 2px 2px 5px rgba(0,0,0,0.1);
}
/* 固定時のサイドバー */
.sidebar.fixed {
position: fixed;
top: 0;
z-index: 100;
}
</style>
</head>
<body>
<!-- ヘッダー -->
<header>
<nav>
<ul>
<li><a href="#">メニュー1</a></li>
<li><a href="#">メニュー2</a></li>
<li><a href="#">メニュー3</a></li>
</ul>
</nav>
</header>
<!-- メインコンテンツ+サイドバー -->
<div class="container">
<div class="content">
<article class="post">ブログ記事1</article>
<article class="post">ブログ記事2</article>
<article class="post">ブログ記事3</article>
<article class="post">ブログ記事4</article>
<article class="post">ブログ記事5</article>
<article class="post">ブログ記事6</article>
<article class="post">ブログ記事7</article>
<article class="post">ブログ記事8</article>
<article class="post">ブログ記事9</article>
</div>
<!-- サイドバーラッパーでレイアウトスペースを確保 -->
<div class="sidebar-wrapper">
<aside class="sidebar">
<h2>カテゴリー</h2>
<ul>
<li><a href="#">カテゴリー1</a></li>
<li><a href="#">カテゴリー2</a></li>
<li><a href="#">カテゴリー3</a></li>
<li><a href="#">カテゴリー4</a></li>
</ul>
</aside>
</div>
</div>
<script>
// スクロール時にヘッダーの下端とサイドバーの固定をチェック
window.addEventListener('scroll', function() {
const header = document.querySelector('header');
const sidebar = document.querySelector('.sidebar');
const sidebarWrapper = document.querySelector('.sidebar-wrapper');
const headerBottom = header.getBoundingClientRect().bottom;
// ヘッダーが画面上から隠れたら(下端が0以下)サイドバーを固定
if (headerBottom <= 0) {
if (!sidebar.classList.contains('fixed')) {
// ラッパーの位置と幅を取得して、サイドバーの固定時の位置と幅として設定
const wrapperRect = sidebarWrapper.getBoundingClientRect();
sidebar.style.left = wrapperRect.left + 'px';
sidebar.style.width = wrapperRect.width + 'px';
sidebar.classList.add('fixed');
}
} else {
// ヘッダーが表示されている場合は固定を解除
if (sidebar.classList.contains('fixed')) {
sidebar.classList.remove('fixed');
sidebar.style.left = '';
sidebar.style.width = '';
}
}
});
</script>
</body>
</html>
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.