本文へスキップ
HELLO!
HIGASHIYUKI®.COM
0   /   100
ヒーロー

見出しの字間が詰まりながら現れる

デモ

仕様

用途
ヒーロー
動作
DOM
種類
レシピ
動作確認
three 0.186.0・gsap 3.15.0
公開日

しくみと調整

字間を広く薄く置いた見出しが、字間を詰めながらはっきり現れます。letterSpacing を em のままトゥイーンし、字間は末尾の文字の後ろにも付くので、同じ量を padding-left にも入れて中央をそろえます。

字間は 0.5em から 0.04em へ 2.4 秒の expo.out で詰め、不透明度はそれより短い 1.2 秒で先に上げきります。小見出しは 0.14em の字間の英大文字ラベルです。

字間が変わると行の幅も変わるので、white-space: nowrap で 1 行に収め、詰まる途中で折り返しが変わって跳ねないようにします。

詰める速さや開始の字間を変えると、映画のタイトルのような重さの違いが出ます。動きを減らす設定では、詰まりきった状態のまま見せます。ブランドサイトのヒーローや、章の扉に向いています。

コード

HTML
<section class="wide-title">
  <p class="wide-title__eyebrow">Introducing</p>
  <h2 class="wide-title__heading">物語は、次の章へ。</h2>
</section>

CSS
.wide-title {
  --bg: #111111;
  --ink: #eeece6;
  --mute: #a8a6a0;
  display: grid;
  place-items: center;
  align-content: center; /* これが無いと、2 段の行が高さいっぱいに伸びて間に大きな隙間ができる */
  min-height: 100vh;
  padding: 96px 6vw;
  overflow-x: hidden; /* 出始めは字間が広く、狭い画面では見出しが画面幅を超えるため */
  background: var(--bg);
  color: var(--ink);
  text-align: center;
}

.wide-title__eyebrow {
  margin: 0 0 32px;
  padding-left: 0.14em; /* 字間ぶんを左にも入れて中央をそろえる */
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--mute);
}

.wide-title__heading {
  margin: 0;
  font-size: clamp(32px, 6vw, 72px);
  font-weight: 800;
  line-height: 1;
  white-space: nowrap;
}

JavaScript
import { gsap } from "gsap";

const WIDE = "0.5em"; // 出始めの字間
const TIGHT = "0.04em"; // 落ち着いたときの字間
const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;

document.querySelectorAll(".wide-title").forEach((section) => {
  const heading = section.querySelector(".wide-title__heading");
  const eyebrow = section.querySelector(".wide-title__eyebrow");

  // 字間は末尾の文字の後ろにも付くので、同じ値を padding-left にも入れて中央をそろえる
  const reveal = gsap
    .timeline({ paused: true })
    .fromTo(
      heading,
      { letterSpacing: WIDE, paddingLeft: WIDE, opacity: 0 },
      { letterSpacing: TIGHT, paddingLeft: TIGHT, opacity: 1, duration: 2.4, ease: "expo.out" }
    )
    .fromTo(eyebrow, { opacity: 0, y: 12 }, { opacity: 1, y: 0, duration: 0.8, ease: "power2.out", force3D: false }, 0.7);

  // 動きを減らす設定では、出きった状態のまま置く
  if (reduceMotion) {
    reveal.progress(1);
    return;
  }

  // 画面に入ったら 1 回だけ流す
  const io = new IntersectionObserver(
    (entries, self) => {
      for (const entry of entries) {
        if (!entry.isIntersecting) continue;
        self.unobserve(entry.target);
        reveal.play();
      }
    },
    { rootMargin: "0px 0px -15%" }
  );
  io.observe(section);
});

インタラクションデザインについて、
お気軽にご相談ください。

ここに並べているのは、Web サイトの中で動く UI のサンプルです。新しく作るサイトに組み込むことも、いま公開中のサイトに、ボタンやヒーロー、スクロールの演出だけを足すこともできます。設計から実装までの進め方はWeb サイト制作、端末ごとの見え方や表示速度の考え方はレスポンシブウェブサイトのページにまとめています。映像として作る動きをお探しの場合はモーショングラフィックスをご覧ください。