No.118
TRANSITION CSS

Starting Style Fade

@starting-style と transition-behavior: allow-discrete で、display:none から現れる要素をJavaScriptなしでフェードイン。

DEMO

@starting-style

display:none からでもフェードインします。JavaScript は使っていません。

CODE

HTML
<div class="demo-stage ssf-stage">
  <input type="checkbox" id="ssf-toggle" class="ssf-check">
  <label for="ssf-toggle" class="ssf-btn">TOGGLE PANEL</label>
  <div class="ssf-panel">
    <p class="ssf-title">@starting-style</p>
    <p class="ssf-text">display:none からでもフェードインします。JavaScript は使っていません。</p>
  </div>
</div>
CSS
.ssf-stage { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:1.4rem; padding:3rem; background:#0F0F12; min-height:280px; }
.ssf-check { position:absolute; opacity:0; width:0; height:0; }
.ssf-btn {
  padding:.85rem 2rem; border:1px solid rgba(233,27,137,.6); border-radius:999px;
  background:#15151A; color:#fff; cursor:pointer;
  font-family:'Oswald',sans-serif; font-size:.78rem; letter-spacing:.22em;
  transition: background .25s ease, border-color .25s ease;
}
.ssf-btn:hover { background:#1F1F26; border-color:#E91B89; }
.ssf-check:focus-visible + .ssf-btn { outline:2px solid #E91B89; outline-offset:3px; }
.ssf-panel {
  display:none; opacity:0; transform:translateY(14px) scale(.96);
  max-width:340px; padding:1.6rem 1.8rem; border-radius:12px;
  background:#17171C; border:1px solid rgba(255,255,255,.1);
  transition: opacity .35s ease, transform .35s cubic-bezier(.23,1,.32,1), display .35s allow-discrete;
}
.ssf-check:checked ~ .ssf-panel { display:block; opacity:1; transform:translateY(0) scale(1); }
@starting-style {
  .ssf-check:checked ~ .ssf-panel { opacity:0; transform:translateY(14px) scale(.96); }
}
.ssf-title { font-family:'JetBrains Mono',monospace; font-size:.9rem; color:#E91B89; margin-bottom:.6rem; }
.ssf-text { font-size:.85rem; line-height:1.8; color:#B9B9C2; }
@media (prefers-reduced-motion: reduce) {
  .ssf-panel { transition-duration:.01ms; }
}

AI PROMPT

Claude Code Cursor v0
PROMPT
display:none の要素を表示に切り替えるときにフェードインさせたい。JavaScriptは使わない。要点は3つ。1) 表示側のセレクタ(例 :checked ~ .panel や .is-open)に display:block と最終状態(opacity:1, transform:none)を書く。2) 元のセレクタの transition に display .35s allow-discrete を含める。allow-discrete を付けると display のような離散プロパティもトランジションの対象になり、消えるときは終了まで display が保持され、現れるときは即座に切り替わる。3) @starting-style { 表示側のセレクタ { opacity:0; transform: translateY(14px) scale(.96) } } を書く。これが「表示された瞬間の初期値」になり、ここからのトランジションが走る。@starting-style がないと display:none からの変化は開始値を持てず、フェードが起きずに突然現れる。非対応ブラウザでは即時表示になるだけでレイアウトは壊れない。

Acceptance criteria: works with prefers-reduced-motion (animation disabled), zero console errors, zero layout shift

AIエージェントでの実装ガイド → Claude Code でWebアニメーションを実装する

BOOKS · PR · AMAZON

📖 なかしまぁ先生のCSSアニメーション入門 📖 UIデザインの教科書 新版 マルチデバイス時代のインターフェース設計 📖 Fundamentals of Web Animation with GSAP

※当サイトはAmazonアソシエイトプログラムの参加者です。リンクから商品をご購入いただくと、当方に紹介料が発生します。

学びを止めない · AMAZONサブスク

📚 Kindle Unlimited — 技術書・デザイン書が読み放題。30日無料体験 → 🎧 Audible — 移動中に耳で学ぶオーディオブック。30日無料体験 → 📦 Amazon Prime — Prime Reading・配送特典つき。30日無料体験 → 🎵 Music Unlimited — 作業用BGMに。1億曲が聴き放題・30日無料体験 →

※当サイトはAmazonアソシエイトプログラムの参加者です。リンクから商品をご購入いただくと、当方に紹介料が発生します。

RELATED EFFECTS

↗ MORE
→ POPOVER API MENU → PAGE FADE TRANSITION → MODAL FADE

@starting-style(表示開始時のトランジション)とは

display:none から表示に切り替わる要素をアニメーションさせることは、長らくCSSだけでは不可能で、JavaScriptで一旦 display を変えてから次のフレームでクラスを付ける、という回りくどい手順が定番でした。@starting-style と transition-behavior: allow-discrete の組み合わせは、この定番ハックをCSSの標準機能で置き換えるものです。

当サイトの Page Fade Transition はページ遷移そのものの明転・暗転、Modal Fade はモーダルの開閉演出という別テーマです。本ページは「display が切り替わる要素すべてに効く土台の仕組み」を扱っており、モーダル・ドロワー・トースト・アコーディオンなど表示切り替えを伴う全ての実装で共通して使えます。

ポイントは @starting-style を「表示状態のセレクタ」に対して書くことです。元のセレクタに書いても効かないため、ここを間違えると無反応になります。

よくある質問

なぜ @starting-style が必要なのですか?

display:none の要素はレンダリングツリーに存在しないため、ブラウザは「変化前の値」を持てません。開始値が無いとトランジションは起動できず、突然表示されます。@starting-style は「その要素が初めて描画される瞬間に使う値」を宣言する仕組みで、これがあることで display:none → block の変化にもフェードを付けられます。

transition-behavior: allow-discrete は何のためにありますか?

display や content-visibility のように中間値を持たない離散プロパティは、既定ではトランジションの対象外です。allow-discrete を指定すると、表示に変わるときは即座に、非表示に変わるときはトランジション終了まで待ってから切り替わるようになります。これがないと閉じるときに要素が一瞬で消え、フェードアウトが見えません。

コードは無料で使えますか?

はい。Motion LabのコードスニペットとAIプロンプトは、クレジット表記なしで自由に使えます。コピーしてそのままプロジェクトに利用できます。