左右交互タイムライン
中央の縦線を挟んでカードが左右交互に並ぶ沿革タイムライン。それぞれが逆方向からふわっと現れ、狭い画面では片側寄せの1列表示に切り替わります。
ライブデモ
コード
HTML
<!-- 左右交互タイムライン: 中央の縦線を挟んでカードが左右へ交互に並ぶ -->
<section class="tla">
<div class="tla__card">
<p class="tla__eyebrow">COMPANY HISTORY</p>
<h2 class="tla__title">会社沿革</h2>
<div class="tla__scroll" tabindex="0" role="region" aria-label="会社の沿革(スクロールで続きを表示)">
<ol class="tla__list">
<li class="tla__item">
<div class="tla__content">
<time class="tla__date">2019年</time>
<h3 class="tla__heading">設立</h3>
<p class="tla__desc">東京の小さなオフィスで、3名のメンバーとともに創業しました。</p>
</div>
<span class="tla__dot" aria-hidden="true"></span>
</li>
<li class="tla__item">
<div class="tla__content">
<time class="tla__date">2020年</time>
<h3 class="tla__heading">初出資</h3>
<p class="tla__desc">エンジェル投資家より資金を調達し、開発体制を強化しました。</p>
</div>
<span class="tla__dot" aria-hidden="true"></span>
</li>
<li class="tla__item">
<div class="tla__content">
<time class="tla__date">2021年</time>
<h3 class="tla__heading">初の海外拠点</h3>
<p class="tla__desc">シンガポールに拠点を新設し、アジア市場への足がかりを築きました。</p>
</div>
<span class="tla__dot" aria-hidden="true"></span>
</li>
<li class="tla__item">
<div class="tla__content">
<time class="tla__date">2022年</time>
<h3 class="tla__heading">累計利用者50万人</h3>
<p class="tla__desc">サービス開始から3年で、利用者数が50万人を突破しました。</p>
</div>
<span class="tla__dot" aria-hidden="true"></span>
</li>
<li class="tla__item">
<div class="tla__content">
<time class="tla__date">2023年</time>
<h3 class="tla__heading">株式上場</h3>
<p class="tla__desc">東京証券取引所グロース市場に株式を上場しました。</p>
</div>
<span class="tla__dot" aria-hidden="true"></span>
</li>
<li class="tla__item">
<div class="tla__content">
<time class="tla__date">2024年</time>
<h3 class="tla__heading">新社屋へ移転</h3>
<p class="tla__desc">渋谷に新オフィスを構え、従業員数は200名を超えました。</p>
</div>
<span class="tla__dot" aria-hidden="true"></span>
</li>
</ol>
</div>
</div>
</section>
CSS
/* 左右交互タイムライン: 中央線を挟んでカードが左右交互に並ぶ沿革 */
* { box-sizing: border-box; }
body {
margin: 0;
min-height: 100vh;
display: grid;
place-items: center;
padding: 30px 16px;
font-family: "Segoe UI", "Hiragino Kaku Gothic ProN", "Yu Gothic UI", system-ui, sans-serif;
background: radial-gradient(130% 110% at 50% -10%, #241b3d 0%, #12101e 55%, #0c0a14 100%);
color: #f1eefb;
}
/* ルート: 全幅 */
.tla { width: 100%; display: grid; place-items: center; }
.tla__card {
width: min(680px, 100%);
background: rgba(255, 255, 255, .035);
border: 1px solid rgba(255, 255, 255, .09);
border-radius: 20px;
padding: 28px 26px 8px;
box-shadow: 0 30px 60px -30px rgba(0, 0, 0, .65);
}
.tla__eyebrow {
margin: 0 0 6px;
font-size: 11px;
font-weight: 700;
letter-spacing: .24em;
color: #d9a4ff;
text-align: center;
}
.tla__title {
margin: 0 0 22px;
font-size: clamp(19px, 3vw, 23px);
font-weight: 800;
text-align: center;
letter-spacing: -.01em;
}
.tla__scroll {
max-height: 380px;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: rgba(217, 164, 255, .4) transparent;
}
.tla__scroll::-webkit-scrollbar { width: 6px; }
.tla__scroll::-webkit-scrollbar-thumb { background: rgba(217, 164, 255, .35); border-radius: 999px; }
.tla__list {
position: relative;
list-style: none;
margin: 0;
padding: 4px 4px 22px;
}
/* 中央の縦線 */
.tla__list::before {
content: "";
position: absolute;
left: 50%; top: 4px; bottom: 10px;
width: 2px;
transform: translateX(-50%);
background: linear-gradient(180deg, #d9a4ff, #7c8bff 55%, rgba(124, 139, 255, .12));
border-radius: 2px;
}
.tla__item {
position: relative;
display: grid;
grid-template-columns: 1fr 36px 1fr;
column-gap: 16px;
align-items: start;
padding-bottom: 26px;
opacity: 0;
}
.tla__item:last-child { padding-bottom: 4px; }
.tla__dot {
grid-column: 2;
justify-self: center;
margin-top: 5px;
width: 12px; height: 12px;
border-radius: 50%;
background: linear-gradient(135deg, #d9a4ff, #7c8bff);
box-shadow: 0 0 0 4px rgba(217, 164, 255, .16);
}
.tla__content { min-width: 0; }
.tla__date {
display: block;
font-size: 11.5px;
font-weight: 700;
letter-spacing: .06em;
color: #b9a8e6;
margin-bottom: 4px;
}
.tla__heading { margin: 0 0 6px; font-size: 15px; font-weight: 800; color: #f6f2ff; }
.tla__desc { margin: 0; font-size: 13px; line-height: 1.7; color: #c3bde0; }
/* 奇数=左側、偶数=右側 */
.tla__item:nth-child(odd) .tla__content {
grid-column: 1;
text-align: right;
}
.tla__item:nth-child(even) .tla__content {
grid-column: 3;
text-align: left;
}
/* 交互に左右から出現 */
.tla__item:nth-child(odd) { animation: tlaInLeft .6s cubic-bezier(.22, 1, .36, 1) forwards; }
.tla__item:nth-child(even) { animation: tlaInRight .6s cubic-bezier(.22, 1, .36, 1) forwards; }
.tla__item:nth-child(1) { animation-delay: .05s; }
.tla__item:nth-child(2) { animation-delay: .16s; }
.tla__item:nth-child(3) { animation-delay: .27s; }
.tla__item:nth-child(4) { animation-delay: .38s; }
.tla__item:nth-child(5) { animation-delay: .49s; }
.tla__item:nth-child(6) { animation-delay: .60s; }
@keyframes tlaInLeft {
from { opacity: 0; transform: translateX(-22px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes tlaInRight {
from { opacity: 0; transform: translateX(22px); }
to { opacity: 1; transform: translateX(0); }
}
/* 狭幅: 線を左端へ寄せ、全カードを片側寄せの1列表示に */
@media (max-width: 560px) {
.tla__card { padding: 22px 16px 6px; border-radius: 16px; }
.tla__list { padding-left: 6px; }
.tla__list::before { left: 14px; transform: none; }
.tla__item {
grid-template-columns: 28px 1fr;
column-gap: 12px;
}
.tla__dot { grid-column: 1; justify-self: start; margin-left: 8px; }
.tla__item:nth-child(odd) .tla__content,
.tla__item:nth-child(even) .tla__content {
grid-column: 2;
text-align: left;
}
.tla__item:nth-child(even) { animation-name: tlaInLeft; }
}
@media (prefers-reduced-motion: reduce) {
.tla__item { animation: none !important; opacity: 1; transform: none; }
}
JavaScript
// 左右交互タイムライン: 演出はCSSの読み込み時アニメーションのみで完結(JS不要)
🤖 AIエージェント用プロンプト
このままコピーしてAIに貼り付け「追加する場所」だけ書き換えればOK
あなたは熟練のフロントエンドエンジニアです。私のWebサイトに「左右交互タイムライン」の効果を追加してください。
# 追加してほしい効果
左右交互タイムライン(タイムライン & 404)
中央の縦線を挟んでカードが左右交互に並ぶ沿革タイムライン。それぞれが逆方向からふわっと現れ、狭い画面では片側寄せの1列表示に切り替わります。
# 追加する場所
👉【ここに対象箇所を記入:例「トップのヒーローセクション」「お問い合わせボタン」「記事カードの一覧」など】
# 参考実装(この見た目・挙動を再現してください)
【HTML】
<!-- 左右交互タイムライン: 中央の縦線を挟んでカードが左右へ交互に並ぶ -->
<section class="tla">
<div class="tla__card">
<p class="tla__eyebrow">COMPANY HISTORY</p>
<h2 class="tla__title">会社沿革</h2>
<div class="tla__scroll" tabindex="0" role="region" aria-label="会社の沿革(スクロールで続きを表示)">
<ol class="tla__list">
<li class="tla__item">
<div class="tla__content">
<time class="tla__date">2019年</time>
<h3 class="tla__heading">設立</h3>
<p class="tla__desc">東京の小さなオフィスで、3名のメンバーとともに創業しました。</p>
</div>
<span class="tla__dot" aria-hidden="true"></span>
</li>
<li class="tla__item">
<div class="tla__content">
<time class="tla__date">2020年</time>
<h3 class="tla__heading">初出資</h3>
<p class="tla__desc">エンジェル投資家より資金を調達し、開発体制を強化しました。</p>
</div>
<span class="tla__dot" aria-hidden="true"></span>
</li>
<li class="tla__item">
<div class="tla__content">
<time class="tla__date">2021年</time>
<h3 class="tla__heading">初の海外拠点</h3>
<p class="tla__desc">シンガポールに拠点を新設し、アジア市場への足がかりを築きました。</p>
</div>
<span class="tla__dot" aria-hidden="true"></span>
</li>
<li class="tla__item">
<div class="tla__content">
<time class="tla__date">2022年</time>
<h3 class="tla__heading">累計利用者50万人</h3>
<p class="tla__desc">サービス開始から3年で、利用者数が50万人を突破しました。</p>
</div>
<span class="tla__dot" aria-hidden="true"></span>
</li>
<li class="tla__item">
<div class="tla__content">
<time class="tla__date">2023年</time>
<h3 class="tla__heading">株式上場</h3>
<p class="tla__desc">東京証券取引所グロース市場に株式を上場しました。</p>
</div>
<span class="tla__dot" aria-hidden="true"></span>
</li>
<li class="tla__item">
<div class="tla__content">
<time class="tla__date">2024年</time>
<h3 class="tla__heading">新社屋へ移転</h3>
<p class="tla__desc">渋谷に新オフィスを構え、従業員数は200名を超えました。</p>
</div>
<span class="tla__dot" aria-hidden="true"></span>
</li>
</ol>
</div>
</div>
</section>
【CSS】
/* 左右交互タイムライン: 中央線を挟んでカードが左右交互に並ぶ沿革 */
* { box-sizing: border-box; }
body {
margin: 0;
min-height: 100vh;
display: grid;
place-items: center;
padding: 30px 16px;
font-family: "Segoe UI", "Hiragino Kaku Gothic ProN", "Yu Gothic UI", system-ui, sans-serif;
background: radial-gradient(130% 110% at 50% -10%, #241b3d 0%, #12101e 55%, #0c0a14 100%);
color: #f1eefb;
}
/* ルート: 全幅 */
.tla { width: 100%; display: grid; place-items: center; }
.tla__card {
width: min(680px, 100%);
background: rgba(255, 255, 255, .035);
border: 1px solid rgba(255, 255, 255, .09);
border-radius: 20px;
padding: 28px 26px 8px;
box-shadow: 0 30px 60px -30px rgba(0, 0, 0, .65);
}
.tla__eyebrow {
margin: 0 0 6px;
font-size: 11px;
font-weight: 700;
letter-spacing: .24em;
color: #d9a4ff;
text-align: center;
}
.tla__title {
margin: 0 0 22px;
font-size: clamp(19px, 3vw, 23px);
font-weight: 800;
text-align: center;
letter-spacing: -.01em;
}
.tla__scroll {
max-height: 380px;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: rgba(217, 164, 255, .4) transparent;
}
.tla__scroll::-webkit-scrollbar { width: 6px; }
.tla__scroll::-webkit-scrollbar-thumb { background: rgba(217, 164, 255, .35); border-radius: 999px; }
.tla__list {
position: relative;
list-style: none;
margin: 0;
padding: 4px 4px 22px;
}
/* 中央の縦線 */
.tla__list::before {
content: "";
position: absolute;
left: 50%; top: 4px; bottom: 10px;
width: 2px;
transform: translateX(-50%);
background: linear-gradient(180deg, #d9a4ff, #7c8bff 55%, rgba(124, 139, 255, .12));
border-radius: 2px;
}
.tla__item {
position: relative;
display: grid;
grid-template-columns: 1fr 36px 1fr;
column-gap: 16px;
align-items: start;
padding-bottom: 26px;
opacity: 0;
}
.tla__item:last-child { padding-bottom: 4px; }
.tla__dot {
grid-column: 2;
justify-self: center;
margin-top: 5px;
width: 12px; height: 12px;
border-radius: 50%;
background: linear-gradient(135deg, #d9a4ff, #7c8bff);
box-shadow: 0 0 0 4px rgba(217, 164, 255, .16);
}
.tla__content { min-width: 0; }
.tla__date {
display: block;
font-size: 11.5px;
font-weight: 700;
letter-spacing: .06em;
color: #b9a8e6;
margin-bottom: 4px;
}
.tla__heading { margin: 0 0 6px; font-size: 15px; font-weight: 800; color: #f6f2ff; }
.tla__desc { margin: 0; font-size: 13px; line-height: 1.7; color: #c3bde0; }
/* 奇数=左側、偶数=右側 */
.tla__item:nth-child(odd) .tla__content {
grid-column: 1;
text-align: right;
}
.tla__item:nth-child(even) .tla__content {
grid-column: 3;
text-align: left;
}
/* 交互に左右から出現 */
.tla__item:nth-child(odd) { animation: tlaInLeft .6s cubic-bezier(.22, 1, .36, 1) forwards; }
.tla__item:nth-child(even) { animation: tlaInRight .6s cubic-bezier(.22, 1, .36, 1) forwards; }
.tla__item:nth-child(1) { animation-delay: .05s; }
.tla__item:nth-child(2) { animation-delay: .16s; }
.tla__item:nth-child(3) { animation-delay: .27s; }
.tla__item:nth-child(4) { animation-delay: .38s; }
.tla__item:nth-child(5) { animation-delay: .49s; }
.tla__item:nth-child(6) { animation-delay: .60s; }
@keyframes tlaInLeft {
from { opacity: 0; transform: translateX(-22px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes tlaInRight {
from { opacity: 0; transform: translateX(22px); }
to { opacity: 1; transform: translateX(0); }
}
/* 狭幅: 線を左端へ寄せ、全カードを片側寄せの1列表示に */
@media (max-width: 560px) {
.tla__card { padding: 22px 16px 6px; border-radius: 16px; }
.tla__list { padding-left: 6px; }
.tla__list::before { left: 14px; transform: none; }
.tla__item {
grid-template-columns: 28px 1fr;
column-gap: 12px;
}
.tla__dot { grid-column: 1; justify-self: start; margin-left: 8px; }
.tla__item:nth-child(odd) .tla__content,
.tla__item:nth-child(even) .tla__content {
grid-column: 2;
text-align: left;
}
.tla__item:nth-child(even) { animation-name: tlaInLeft; }
}
@media (prefers-reduced-motion: reduce) {
.tla__item { animation: none !important; opacity: 1; transform: none; }
}
【JavaScript】
// 左右交互タイムライン: 演出はCSSの読み込み時アニメーションのみで完結(JS不要)
# 外部ライブラリ
なし(追加ライブラリ不要)
# 守ってほしいこと
- 既存のHTML構造・レイアウト・デザインを壊さないこと。必要に応じてクラス名・色・サイズを私のサイトに合わせて調整してよい。
- クラス名やidが既存と衝突しないよう、必要なら接頭辞で名前空間を分けること。
- レスポンシブ対応と prefers-reduced-motion への配慮を入れること。
- 私のサイトのフレームワーク(React / Vue / 素のHTML など)に合わせて実装すること。不明な場合は素のHTML/CSS/JSで提示し、組み込み手順も説明すること。
- 変更後の確認手順も簡潔に教えてください。