CSSでレスポンシブタイムラインを作成する方法【サンプルコード付き】
CSSだけでも、PCでは左右交互に表示され、スマートフォンなどの狭い画面では左寄せの1カラムに自動的に切り替わる、レスポンシブ対応のタイムラインを作成できます。実現の鍵となるのは、疑似要素(::after / ::before)で中心線やマーカーを描画することと、メディアクエリでレイアウトを切り替えることです。以下に実際のコード例を示します。
レスポンシブタイムラインのコード例
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
* {
box-sizing: border-box;
}
body {
background-color: #9037f5;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif
}
h2{
text-align: center;
}
.timeline {
position: relative;
max-width: 1200px;
margin: 0 auto;
}
.timeline::after {
content: " ";
position: absolute;
width: 6px;
background-color: rgb(253, 203, 255);
top: 0;
bottom: 0;
left: 50%;
margin-left: -3px;
}
/* イベントを囲むコンテナ */
.eventsContainer {
padding: 10px 40px;
position: relative;
background-color: inherit;
width: 50%;
}
.eventsContainer::after {
content: " ";
position: absolute;
width: 25px;
height: 25px;
right: -17px;
background-color: rgb(219, 255, 12);
border: 4px dashed rgb(255, 0, 0);
background-clip: content-box;
top: 15px;
z-index: 1;
}
.displayLeft {
left: 0;
}
.displayRight {
left: 50%;
}
.displayLeft::before {
content: " ";
height: 0;
position: absolute;
top: 22px;
width: 0;
z-index: 1;
right: 30px;
border: medium solid rgb(225, 246, 255);
border-width: 10px 0 10px 10px;
border-color: transparent transparent transparent white;
}
.displayRight::before {
content: " ";
height: 0;
position: absolute;
top: 22px;
width: 0;
z-index: 1;
left: 30px;
border: medium solid white;
border-width: 10px 10px 10px 0;
border-color: transparent white transparent transparent;
}
.displayRight::after {
left: -16px;
}
.event {
padding: 20px 30px;
background-color: white;
position: relative;
border-radius: 6px;
}
@media screen and (max-width: 600px) {
.timeline::after {
left: 31px;
}
.eventsContainer {
width: 100%;
padding-left: 70px;
padding-right: 25px;
}
.eventsContainer::before {
left: 60px;
border: medium solid white;
border-width: 10px 10px 10px 0;
border-color: transparent white transparent transparent;
}
.displayLeft::after, .displayRight::after {
left: 15px;
}
.displayRight {
left: 0%;
}
}
</style>
</head>
<body>
<div class="timeline">
<div class="eventsContainer displayLeft">
<div class="event">
<h2>2017</h2>
<h3>ドナルド・トランプが第45代アメリカ大統領に就任</h3>
</div>
</div>
<div class="eventsContainer displayRight">
<div class="event">
<h2>2016</h2>
<h3>リオデジャネイロで夏季オリンピック開催</h3>
</div>
</div>
<div class="eventsContainer displayLeft">
<div class="event">
<h2>2015</h2>
<h3>ネパールでマグニチュード7.8の地震が発生</h3>
</div>
</div>
</div>
</body>
</html>実行結果
上記のコードを実行すると、次のようなタイムラインが表示されます。

画面幅を600px以下に狭めると、タイムラインはすべて左側に揃った1カラムのレイアウトへと自動的に切り替わります。

コードのポイント解説
1. 中央の縦線は .timeline::after で描画
親要素 .timeline の ::after 疑似要素を使い、幅6pxの縦線を left: 50% の位置に絶対配置しています。margin-left: -3px で線の幅の半分だけずらすことで、コンテンツのど真ん中に一本のラインが引かれます。
2. イベントを左右に振り分ける
各イベントを包む .eventsContainer は width: 50% とし、.displayLeft で左側、.displayRight で右側(left: 50%)に配置します。これにより、イベントカードが中央の線を挟んで左右交互に並ぶレイアウトになります。
3. マーカーと矢印も疑似要素で作成
.eventsContainer::after は中央線上に置かれる丸いマーカーです。border を破線にし、background-clip: content-box を組み合わせることで、内側が塗りつぶされたドーナツ状のデザインになります。また、::before では border の幅の違いを利用した三角形テクニックを使い、カードから中央線へ向かう矢印を表現しています。
4. メディアクエリでモバイル対応
@media screen and (max-width: 600px) のブロック内では、縦線の位置を left: 31px へ移動し、.eventsContainer を width: 100% に変更します。さらに .displayRight も left: 0% に戻すことで、すべてのイベントが左寄せの1カラムになり、スマートフォンでも読みやすいレイアウトに切り替わります。
まとめ
このように、疑似要素とメディアクエリを組み合わせるだけで、JavaScriptに頼らないレスポンシブタイムラインを実装できます。線やマーカーの色、形状、余白などを調整すれば、サイトのデザインに合わせて自由にカスタマイズすることも可能です。ぜひ自分のプロジェクトにも取り入れてみてください。
-
CSSでレスポンシブなブログレイアウトを作成する方法【完全なコード例付き】
CSSを使ってレスポンシブなブログレイアウトを作成するには、viewportメタタグの設定と、デバイスの画面幅に応じて柔軟に調整されるレイアウト構造の定義がポイントになります。以下に、ナビゲーションバー・ブログ本文・サイドリンク・フッターを備えた、ブログサイトの完全なコード例を紹介します。 コード例 <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1" /> <
-
CSSでレスポンシブなカラムカードを作成する方法【コード例付きで解説】
CSSを使えば、画面サイズに応じてレイアウトが自動的に切り替わるレスポンシブなカラムカードを簡単に作成できます。本記事では、floatとcalc()、そしてメディアクエリを組み合わせた基本的な実装方法を、実際に動作するサンプルコードとともにわかりやすく解説します。 レスポンシブカラムカードの仕組み この手法のポイントは、主に以下の3つです。 calc(25% - 20px):4枚のカードを横並びにするため、各カードの幅を「全体の25%からマージン分を引いた値」として計算しています。 float: left:カードを左に回り込ませることで、横一列に並べています。 @mediaクエリ:画面幅が