【コピペOK】カンファレンス LP セクション テンプレート9選
カンファレンス LP セクションテンプレートは、ヒーロー・スケジュール・登壇者紹介のようなイベントランディングページ用ブロックを、LPにそのまま貼れる形でまとめたコード集です。9つのうち1つは、実際の目標時刻まで秒単位で減っていくカウントダウンを収めています。
自動再生 · タイルを押すとその項目へ · すべて1つのzip
9つは人気順ではなく、来場者がランディングページを読み進める順番に並べました。まず目を引き(ヒーロー)、日程を確認させ(タイムライン)、信頼を積み上げ(登壇者)、アクセス情報を渡し(会場)、購入を決めさせ(料金)、信頼をもう一度補強し(スポンサー)、残った疑問を消し(FAQ)、行動に移させ(申込CTA)、最後に今すぐ動くべき理由を刻みます(カウントダウン)。写真やロゴの場所はすべてこのサイト共通の$subject-ink・$subject-blue・$subject-creamトークンで作った図形のプレースホルダーなので、実際の写真とロゴに差し替えるだけで使えます。
01イベントヒーロー
背景で三つのぼかした円がずっと漂う中、図形だけのワードマーク・見出し・日付/会場のピル・CTAが一画面に収まります。右の「関心登録」ボタンはクリックのたびにaria-pressedが実際に切り替わり、アイコンが塗りつぶされます。
.eh__orb--1 { animation: eh-float-a 2s ease-in-out infinite; }
@keyframes eh-float-a {
0%, 100% { transform: translate(0, 0) scale(1); }
50% { transform: translate($sp-10, -$sp-8) scale(1.5); }
}
.eh__save[aria-pressed="true"] {
background: rgba(255, 247, 230, .12);
border-color: $subject-cream;
}
.eh__save[aria-pressed="true"] .eh__save-ic {
opacity: 1;
color: $color;
transform: scale(1.15);
}
02スケジュールタイムライン
縦線上の停車点(受付・基調講演・ネットワーキング・パネル)をクリックすると、その位置まで進捗バーがscaleYで実際に伸び、選んだ停車点の点だけがパルスリングで強調されます。
.tl__fill {
position: absolute; inset: 0;
transform: scaleY(.25);
transform-origin: top;
background: $color;
transition: transform $duration $easing;
}
.tl__stop[aria-current="step"] .tl__dot {
background: $color;
transform: scale(1.3);
box-shadow: 0 0 0 4px rgba(23, 20, 26, .14);
}
03登壇者グリッド
カード6枚が順番にわずかに傾いてから起き上がるように現れます。カードをクリックするとそのカードだけ一行の紹介文がmax-height遷移で開き、他は閉じたままです。
.sg.is-demo .sg__card { animation: sg-in 2s $easing infinite; }
@keyframes sg-in {
0% { opacity: .7; transform: translateY(6px) rotate(-1.5deg); }
18% { opacity: 1; transform: translateY(0) rotate(0deg); }
86% { opacity: 1; transform: translateY(0) rotate(0deg); }
100% { opacity: .7; transform: translateY(6px) rotate(-1.5deg); }
}
.sg__card.is-open .sg__bio { max-height: 60px; opacity: 1; }
04会場案内
地下鉄・バス・車のタブを押すと、その移動手段の説明だけが実際に切り替わり、下線インジケーターが選んだタブの下まで滑ります。地図プレースホルダーの上のピンは常に波紋を描き続けます。
tabs.forEach(function (t) {
t.addEventListener('click', function () {
tabs.forEach(function (o) { o.setAttribute('aria-selected', 'false'); });
t.setAttribute('aria-selected', 'true');
ind.style.transform = 'translateX(' + (Number(t.dataset.i) * 100) + '%)';
panels.forEach(function (p, i) {
p.style.opacity = String(i === Number(t.dataset.i) ? 1 : 0);
});
});
});
05チケット料金
中央のカードには「人気」バッジと控えめなグローが常に揺らめきます。上部のアーリーバード/正規料金スイッチを押すと、3枚のカードの価格がクロスフェードで一斉に切り替わります。
.tp__price-a, .tp__price-b {
position: absolute; inset: 0;
transition: opacity $duration $easing;
}
.tp__price-b { opacity: 0; }
.tp__switch[aria-checked="true"] ~ .tp__cards .tp__price-a { opacity: 0; }
.tp__switch[aria-checked="true"] ~ .tp__cards .tp__price-b { opacity: 1; }
.tp__card--pop { animation: tp-glow 2.4s ease-in-out infinite; }
06スポンサーロゴバー
ロゴ8個(すべて図形のプレースホルダーで実在のロゴではありません)をつなげたトラックが途切れなく流れ続けます。マウスを乗せるか一時停止ボタンをタップすると、その場で流れが止まります。
// トラック自体には gap を使わない — 項目ごとに margin-right で間隔を取る
.sb__track { display: flex; width: max-content; animation: sb-scroll 14s linear infinite; }
.sb__logo { flex: 0 0 auto; margin-right: $sp-6; }
@keyframes sb-scroll {
from { transform: translateX(0); }
to { transform: translateX(-50%); }
}
07イベントFAQ
質問3つのうち1つだけが開いています。クリックした質問の回答欄がgrid-template-rowsで実際に開き、他は閉じ、矢印も一緒に回転します。
.fq__a-wrap {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows $duration $easing;
}
.fq__item.is-open .fq__a-wrap { grid-template-rows: 1fr; }
.fq__a { min-height: 0; overflow: hidden; }
08申込CTA
メールアドレスを入れてボタンを押すと、実際に正規表現で形式を検証します。通過するとボタンにチェックが描かれて「登録完了」に変わり、形式が誤っていると入力欄が左右に短く揺れます。
form.addEventListener('submit', function (e) {
e.preventDefault();
var ok = /^\S+@\S+\.\S+$/.test(input.value);
if (ok) {
form.classList.add('is-done');
done.textContent = '登録完了 — 確認メールを送信しました。';
} else {
input.classList.remove('is-shake');
void input.offsetWidth;
input.classList.add('is-shake');
done.textContent = '正しいメールアドレスを入力してください。';
}
});
09カウントダウン
ページを開いた瞬間からちょうど7日4時間20分15秒後を目標時刻とし、1秒ごとに実際に数字が減っていきます。秒のカードは毎秒わずかに跳ね上がります。
var target = Date.now() + ((7 * 24 * 60 * 60) + (4 * 60 * 60) + (20 * 60) + 15) * 1000;
function tick() {
var diff = Math.max(0, target - Date.now());
var s = Math.floor(diff / 1000);
els.d.textContent = pad(Math.floor(s / 86400));
els.h.textContent = pad(Math.floor((s % 86400) / 3600));
els.m.textContent = pad(Math.floor((s % 3600) / 60));
els.s.textContent = pad(s % 60);
}
tick();
setInterval(tick, 1000);
どこで壊れるか — 落とし穴
9つを作る中で実際に踏んだ落とし穴は、画面サイズでした。480×300のキャンバスでは最初、ヒーローが縦の余白を取りすぎてキャンバス内にスクロールバーが出ました。パディングと行間を一段ずつ削ってようやく収まりました。本当に苦しんだのは幅320px・高さ200pxの狭い画面です。登壇者グリッド・会場案内・チケット料金・FAQ・申込CTAの5つが、この大きさで高さ260〜450pxまではみ出しました。2列に畳めば解決するわけではなく、登壇者グリッドはむしろ3列を保ったまま、役割説明のような二次情報だけを狭い画面で隠す形に直しました。
カウントダウンの秒カードは最初rotateX(0 → -90deg → 0)で丸ごと反転させていましたが、perspectiveを与えずに90度の地点を通過する瞬間、数字が完全に平らになってキャプチャ画面では線一本("--")のように写りました。3DフリップをやめてtranslateY+scaleで軽く跳ねる動きに変えたところ解決しました。スポンサーロゴバーのようにtranslateX(-50%)で無限スクロールするトラックは、項目間の間隔をgapではなくmargin-rightで取る必要があります。gapを使うと2周目(2N個目)の継ぎ目だけgap ÷ 2分足りなくなり、トラックが一周するたびにわずかに跳ねます。この二つを含めてレスポンシブとアニメーションを直したあと、5ngtcz6hで最新状態のzipを開くと、9つは上の説明どおりに動きます。
アクセシビリティ
9つ全部がprefers-reduced-motion: reduceで装飾的な遷移とアニメーションを止めつつ、状態そのものは残します — スケジュールの進捗バーは埋まったまま、FAQの回答は開いたまま固定され、カウントダウンの数字更新だけはそのまま続きます。会場案内(04)はrole="tablist"・role="tab"・aria-selectedを実際に備えたタブで、申込CTA(08)の結果文はrole="status"(aria-live)なのでスクリーンリーダーが送信結果をすぐに読み上げます。カウントダウン(09)はrole="timer"にaria-live="off"を与えて、毎秒更新される数字がスクリーンリーダーの邪魔をしないようにしました。タブとアコーディオンのキーボード操作はW3C ARIA Authoring Practicesの基準に沿っています。
他のCSSテンプレート素材はテンプレートカテゴリーに、このサイトが何を配っているかは紹介ページにまとめています。
FAQ
このテンプレートに実際のロゴや写真を使っても大丈夫ですか?
はい、それが目的です。9つとも写真・ロゴの場所は図形のプレースホルダーなので、実際の画像やロゴに差し替えるだけで使えます。色はdemo-tokens.scssの値をそのまま使ってもよく、ブランドカラーに変えてもレイアウトはそのまま保たれます。
React版はCSS版と動きが違いますか?
動作は同じです。選んだタブや開いたアコーディオンのような状態はuseStateで持ち、変数3つ(duration・easing・color)はpropsで受け取ってCSS変数(--duration・--easing・--color)に渡します。カウントダウンはuseEffectの中で同じsetIntervalの処理をそのまま使います。
カウントダウンは本当に動いていますか、それとも飾りですか?
実際に動いています。ページを開いた時点からちょうど7日4時間20分15秒後を目標にして1秒ごとに更新されます。目標時刻はtargetの値ひとつを実際のイベント日に変えるだけでそのまま使えます。自動再生のgifで見える秒カードの跳ねる動きは別の@keyframesによる装飾で、数字の更新とは独立して動きます。