GODRICH
#cssアニメーション#ボタン#ローディング#トランジション#スクロール#ダッシュボード#実用ui#デザイントレンド

プレスキット テンプレート付き プレスルームセクション9選

プレスルーム・メディアページのセクションテンプレートは、プレスリリース一覧・メディアキット・問い合わせ先といった要素をひとまとめにしたプレスキット テンプレート集です。LPにそのまま貼れるヒーローから購読フッターまで、9つのうち1つは実際にメールアドレスをクリップボードへコピーするボタンを備えています。

自動再生 · タイルを押すとその項目へ · すべて1つのzip

9つは人気順ではなく、記者・投資家がプレスルームを読み進める順番に並べました。まず第一印象を与え(ヒーロー)、最新情報を確認させ(プレスリリース一覧)、取材に使う資料を渡し(メディアキット)、すでに掲載された実績を見せ(掲載メディア)、規模を数字で裏付け(数字ハイライト)、担当者へすぐ連絡させ(問い合わせ)、ブランドの声を届け(創業者の言葉)、これまでの歩みを示した上で(沿革タイムライン)、次の情報を受け取らせます(フッター)。担当者の顔・メディアロゴの位置は、実際の画像ではなくすべてこのサイト共通の$subject-ink・$subject-blue・$subject-creamトークンだけで描いた図形のプレースホルダーです。ファイルだけ差し替えれば、レイアウトはそのまま残ります。プレスリリース 書き方 テンプレートのような文章の型はここには入っておらず、配っているのは画面のセクションだけです。発表が催しと結び付いているならイベントページのテンプレートが前の席を埋め、報道ではなく成果物を並べる場所はプロジェクト紹介のテンプレートです。

01プレスヒーロー

漂う円と固定の見出し

背景でぼかした円3つがtranslate+scaleでずっと漂う間、図形のワードマーク・見出し・サブ見出し・CTAボタン2つが1画面に収まります。

プレスヒーロー
新しいタブで開く

01 · プレスヒーロー — 計測 累積面積 30.411% · 動いたフレーム 18/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

transformopacityaria-pressed

購読ボタンは実際に切り替わる

右の「プレスリリース購読」ボタンはクリックのたびにaria-pressedが実際に切り替わり、アイコンが塗りつぶされます。

.ph__orb--1 { animation: ph-float-a 2s ease-in-out infinite; }
@keyframes ph-float-a {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%      { transform: translate($sp-10, -$sp-8) scale(1.5); }
}
.ph__sub-btn[aria-pressed="true"] {
  background: rgba(255, 247, 230, .12);
  border-color: $subject-cream;
}
.ph__sub-btn[aria-pressed="true"] .ph__sub-ic {
  opacity: 1;
  color: $color;
  transform: scale(1.15);
}

02プレスリリース一覧

プレスリリース テンプレート を分類で絞る

分類チップ(すべて・製品・パートナーシップ・受賞)をクリックすると、その分類ではない行がmax-height+opacity遷移で実際に折りたたまれます。

プレスリリース一覧
新しいタブで開く

02 · プレスリリース一覧 — 計測 累積面積 0.271% · 動いたフレーム 16/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

clickrl__filtersaria-pressed

アクセントバーのスキャン

各行左側のアクセントバーは常に順番に明るくなるスキャン動作を繰り返します(装飾)。

var root = document.querySelector('.rl');
var chips = root.querySelectorAll('.rl__chip');
var rows = root.querySelectorAll('.rl__row');
chips.forEach(function (chip) {
  chip.addEventListener('click', function () {
    root.classList.remove('is-demo');
    chips.forEach(function (c) { c.setAttribute('aria-pressed', 'false'); });
    chip.setAttribute('aria-pressed', 'true');
    var cat = chip.getAttribute('data-cat');
    rows.forEach(function (row) {
      var show = cat === 'all' || row.getAttribute('data-cat') === cat;
      row.classList.toggle('is-hidden', !show);
    });
  });
});

03メディアキット

選んだファイルだけ有効化

チェックボックス3つ(ロゴパック・ブランドガイド・製品スクリーンショット)を選ぶと「選択したファイルを受け取る」ボタンが実際に有効化され(disabled解除)、ラベルに個数が付きます。

メディアキット
新しいタブで開く

03 · メディアキット — 計測 累積面積 0.756% · 動いたフレーム 22/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

checkboxstroke-dashoffsetclick

クリックで描かれるチェック

クリックすると選んだ行にSVGチェックがstroke-dashoffsetで描かれます。

function updateLabel() {
  var checkedFiles = Array.prototype.filter.call(checks, function (c) { return c.checked; });
  btn.disabled = checkedFiles.length === 0;
  btn.lastChild.textContent = checkedFiles.length ? ' 選択したファイルを取得 (' + checkedFiles.length + ')' : ' 選択したファイルを取得';
}
checks.forEach(function (c) { c.addEventListener('change', updateLabel); });

btn.addEventListener('click', function () {
  var checkedFiles = Array.prototype.filter.call(checks, function (c) { return c.checked; });
  checkedFiles.forEach(function (c) { c.closest('.mk__row').classList.add('is-done'); });
  status.textContent = 'ファイル ' + checkedFiles.length + '件を取得しました。';
});

04掲載メディア

途切れなく流れるトラック

図形で描いたメディアマーク8個(実際のロゴではありません)をつないだトラックがtranslateX(-50%)で途切れなく流れます。

掲載メディア
新しいタブで開く

04 · 掲載メディア — 計測 累積面積 8.057% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

translateX(-50%)animation-play-statepointerenter

その場で止める

カーソルを乗せるか隣のボタンを押すと、その場で流れが止まります。

// トラック自体には gap を使わない — 項目ごとに margin-right で間隔を取る
.mb__track { display: flex; width: max-content; animation: mb-scroll 14s linear infinite; }
.mb__logo { flex: 0 0 auto; margin-right: $sp-6; }
@keyframes mb-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

05数字ハイライト

0から目標値まで上がる

カード3枚の大きな数字が、ページを開いた瞬間にrequestAnimationFrameで0から実際の目標値までeaseOut曲線で上がって止まります(1.2秒)。

数字ハイライト
新しいタブで開く

05 · 数字ハイライト — 計測 累積面積 2.675% · 動いたフレーム 21/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

requestAnimationFramecounteropacity

カード上のアクセントバー

カード上のアクセントバーは常に順番にスキャン動作を繰り返します。

var countStart = performance.now();
var countDuration = 1200;
function easeOut(t) { return 1 - Math.pow(1 - t, 3); }
function tick(now) {
  var t = Math.min(1, (now - countStart) / countDuration);
  var e = easeOut(t);
  nums.forEach(function (el) {
    var target = Number(el.getAttribute('data-target'));
    el.textContent = Math.round(target * e).toLocaleString('ko-KR');
  });
  if (t < 1) requestAnimationFrame(tick);
}
requestAnimationFrame(tick);

06メディア問い合わせ

実際にクリップボードへ

担当者名・肩書きの下のメールボタンを押すと、実際にnavigator.clipboard.writeText()が実行されます。

メディア問い合わせ
新しいタブで開く

06 · メディア問い合わせ — 計測 累積面積 3.774% · 動いたフレーム 6/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

clipboardstroke-dashoffsetclick

1.6秒後に元へ戻る

ボタンにはSVGチェックがstroke-dashoffsetで描かれてから、1.6秒後に元のラベルへ戻ります。

btn.addEventListener('click', function () {
  root.classList.remove('is-demo');
  var email = btn.getAttribute('data-email');
  var showCopied = function () {
    btn.classList.add('is-copied');
    hint.textContent = 'メールアドレスをコピーしました。';
    clearTimeout(revertTimer);
    revertTimer = setTimeout(function () { btn.classList.remove('is-copied'); }, 1600);
  };
  if (navigator.clipboard && navigator.clipboard.writeText) {
    navigator.clipboard.writeText(email).then(showCopied, showCopied);
  }
});

07創業者の言葉

ドット2個で切り替わる

創業者の引用文2つがドット2個で切り替わります。

創業者の言葉
新しいタブで開く

07 · 創業者の言葉 — 計測 累積面積 0.366% · 動いたフレーム 17/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

opacityclickaria-selected

引用符の装飾が揺れる

ドットをクリックするとその引用文へopacityで実際にクロスフェード転換し、大きな引用符の装飾がrotate+scaleで常に揺れます。

.fq__mark {
  position: absolute;
  top: $sp-1; left: 50%;
  transform: translateX(-50%);
  font: 800 56px/1 Georgia, serif;
  color: rgba(47, 109, 246, .32);
  animation: fq-wobble 2s $easing infinite;
}
@keyframes fq-wobble {
  0%, 100% { transform: translateX(-50%) rotate(0deg) scale(1); }
  50%      { transform: translateX(-50%) rotate(-10deg) scale(1.35); }
}
.fq__dot.is-active { background: $color; transform: scale(1.3); }

08沿革タイムライン

クリックした地点まで埋まる

横線上の沿革4地点(創立・シリーズA・海外進出・100万ユーザー)をクリックすると、その地点まで進捗バーがscaleXで実際に埋まります。

沿革タイムライン
新しいタブで開く

08 · 沿革タイムライン — 計測 累積面積 0.438% · 動いたフレーム 7/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

scaleXclickaria-current

説明文も一緒に変わる

上の説明文もその時点の内容に変わります。

stops.forEach(function (btn) {
  btn.addEventListener('click', function () {
    root.classList.remove('is-demo');
    var i = Number(btn.getAttribute('data-i'));
    root.setAttribute('data-active', String(i));
    root.querySelector('.mt__fill').style.transform = 'scaleX(' + ((i + 1) / 4) + ')';
    stops.forEach(function (s) { s.removeAttribute('aria-current'); });
    btn.setAttribute('aria-current', 'step');
    desc.textContent = milestoneNotes[i];
  });
});

09プレスフッター

正規表現で本当に検証する

メールアドレスを入れて購読ボタンを押すと、実際に正規表現で形式を検証します。

プレスフッター
新しいタブで開く

09 · プレスフッター — 計測 累積面積 0.578% · 動いたフレーム 15/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

submitstroke-dashoffsetclick

通過と失敗の合図

通過するとSVGチェックがopacityで現れ、失敗すると入力欄がtranslateXで左右に短く揺れます。

form.addEventListener('submit', function (e) {
  e.preventDefault();
  var ok = /^\S+@\S+\.\S+$/.test(input.value);
  if (ok) {
    form.classList.add('is-done');
    status.textContent = '購読完了 — 確認メールを送りました。';
  } else {
    input.classList.remove('is-shake');
    void input.offsetWidth;
    input.classList.add('is-shake');
    status.textContent = '正しいメールアドレスを入力してください。';
  }
});

どこで壊れるか — 落とし穴

不透明な背景が円を隠した

9つを作る中で実際に2度つまずきました。ひとつ目はメディア問い合わせ(06)です。最初はカード背景を不透明なクリーム色で塗っていましたが、背景に置いたドリフト円がz-index:-1のため、その不透明な背景の裏に完全に隠れてしまいました。見た目には何の問題もなさそうでしたが、実際に動くピクセルはほとんどなく、アニメーションと呼ぶには物足りない状態でした。カード背景をなくし、円が舞台の色の上に直接見えるようにしたことで解決しました。

box-sizing がないと

ふたつ目はプレスリリース一覧(02)とメディアキット(03)のレスポンシブでした。どちらもmax-heightで行を折りたたんだり開いたりしますが、box-sizingを指定しないとpaddingが指定した高さの上にそのまま加算され、実際のレンダー高さが大きくなります。幅320pxの画面ではこの差が積み重なり、気づかないうちに縦スクロールが発生していました。両方にbox-sizing: border-boxを加え、狭い画面用のパディングを減らして解決しました。

マーキーの間隔は margin-right

掲載メディア(04)のようにtranslateX(-50%)で無限スクロールするトラックにも、よくある落とし穴があります。項目同士の間隔をgapで取ると、2周目(2N個目)の継ぎ目だけgap ÷ 2分足りなくなり、一周するたびにわずかに跳ねます。このテンプレートは最初からmargin-rightで間隔を取ってこの問題を避けていて、7a6mw6ktで開くzipの中のコードも同じ方式のままです。上の二つの落とし穴を含めて、9つは表のとおり正確に動く最新の状態です。

数字の入った資料を画像だけで載せて検索に拾われないこの失敗は、ダッシュボードのグラフ操作で実データを扱うときに再び出会います。

アクセシビリティ

動きを止めても状態は残る

9つ全部がprefers-reduced-motion: reduceで装飾的な遷移とアニメーションを止めますが、状態そのものは残ります — 沿革の進捗バーは埋まったまま、フィルターした一覧は折りたたまれたまま固定され、数字ハイライトのカウントアップは情報なのでそのまま続きます。

ネイティブ操作と status

メディアキット(03)のチェックボックスはネイティブのinput[type="checkbox"]なので、Tab・Spaceキーでそのまま操作できます。メディア問い合わせ(06)とプレスフッター(09)の結果文はrole="status"(aria-live)なので、スクリーンリーダーがコピー・送信の結果をすぐに読み上げます。沿革タイムライン(08)はaria-current="step"で今見ている地点を伝え、創業者の言葉(07)のドットボタンはrole="group"とaria-selectedで状態を伝えます。

Clipboard API とフォールバック

クリップボードコピー(06)はMDN Clipboard APIの仕様に沿っていて、対応していない環境ではtextareaフォールバックに切り替わります。他の静的テンプレート素材はテンプレートカテゴリーに、このサイトが何を配っているかは紹介ページにまとめています。

FAQ

この プレスリリース テンプレート に実際の写真やロゴを使ってもいいですか?

はい、それが目的です。9つとも顔写真・ロゴの場所は図形のプレースホルダーなので、実際の画像やロゴに差し替えるだけで使えます。図形自体はdemo-tokens.scssの$subject-ink・$subject-blueの値を使っていて、舞台の背景色(イエロー・オレンジなど)は完全に別のトークンなので混ざる心配はありません。

React版はCSS版と動きが違いますか?

動作は同じです。選んだチップ・チェックボックスの状態・アクティブな引用文のような値はuseStateで持ち、変数3つ(duration・easing・color)はpropsで受け取ってCSS変数(--duration・--easing・--color)に渡します。数字ハイライト(05)のカウントアップはuseEffectの中で同じrequestAnimationFrameの処理をそのまま使います。

メディアキットのダウンロードは実際にファイルを受け取れますか?

チェックボックスの選択とボタンの有効化、完了表示はすべて実際の状態変化です。ただしデモ自体には接続された実ファイルがないため、クリックしても本当のダウンロードは始まりません。実際に使うときは各ファイル行に本物のhrefをつなぐだけで、チェック・カウントのロジックはそのまま再利用できます。記者ではなく顧客を説得する根拠が要るなら、信頼を作るLPパーツがその一式です。

解凍パスワードを入力してください

パスワードはこの記事の本文の中にあります。読み進めると出てきます。