No.140
MICRO CSS

Floating Label

入力欄にフォーカスするとラベルが上へ縮みながら移動するフローティングラベル。:placeholder-shown を使えばJavaScriptなしで入力済みの状態も保てます。

DEMO

@ を含む形式で入力してください

CODE

HTML
<div class="demo-stage fli-stage">
  <form class="fli-form" onsubmit="return false">
    <div class="fli-field">
      <input id="fli-name" class="fli-input" type="text" placeholder=" " autocomplete="off">
      <label for="fli-name" class="fli-label">お名前</label>
    </div>
    <div class="fli-field">
      <input id="fli-mail" class="fli-input" type="email" placeholder=" " autocomplete="off">
      <label for="fli-mail" class="fli-label">メールアドレス</label>
      <span class="fli-hint">@ を含む形式で入力してください</span>
    </div>
  </form>
</div>
CSS
.fli-stage { display:flex; align-items:center; justify-content:center; padding:2rem; background:#0B0B10; min-height:280px; }
.fli-form { width:100%; max-width:340px; display:flex; flex-direction:column; gap:1.4rem; }
.fli-field { position:relative; }
.fli-input {
  width:100%; box-sizing:border-box; padding:1.35rem .9rem .5rem;
  font-size:16px; color:#EDEDED; background:#15151B;
  border:1px solid rgba(255,255,255,.14); border-radius:10px; outline:none;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.fli-label {
  position:absolute; left:.9rem; top:.95rem; color:#8A8A96; font-size:.95rem;
  pointer-events:none; transform-origin:left top;
  transition: transform .22s cubic-bezier(.22,1,.36,1), color .22s ease;
}
.fli-input:focus { border-color:#E91B89; box-shadow:0 0 0 3px rgba(233,27,137,.22); }
.fli-input:focus + .fli-label,
.fli-input:not(:placeholder-shown) + .fli-label { transform:translateY(-.62rem) scale(.76); color:#E91B89; }
.fli-input:not(:focus):not(:placeholder-shown) + .fli-label { color:#9A9AA6; }
.fli-hint { display:block; margin-top:.35rem; font-size:.72rem; color:#F87171; opacity:0; transition: opacity .2s ease; }
.fli-input[type=email]:not(:placeholder-shown):not(:focus):invalid { border-color:#F87171; }
.fli-input[type=email]:not(:placeholder-shown):not(:focus):invalid ~ .fli-hint { opacity:1; }
@media (prefers-reduced-motion: reduce) {
  .fli-label, .fli-input, .fli-hint { transition-duration:.01ms; }
}

AI PROMPT

Claude Code Cursor v0
PROMPT
入力欄のラベルが、フォーカス時と入力済みの時に上へ縮んで移動するフローティングラベルをCSSだけで作って。input に placeholder=" "(半角スペース1つ)を入れ、:placeholder-shown が外れた状態=入力済みと判定するのがJavaScriptを使わない要点。ラベルは input の直後に置き、input:focus + label と input:not(:placeholder-shown) + label の両方で transform: translateY(-.62rem) scale(.76) にする(top や font-size を動かすとレイアウト再計算が走るので transform だけで動かすこと)。transform-origin は left top。input の上余白を広めに取り、縮んだラベルが入力文字と重ならないようにする。font-size は16px以上(iOSのフォーカス時自動ズームを防ぐ)。type=email はフォーカスが外れて入力済みかつ :invalid の時だけ枠を赤くし、ヒント文を表示する。label は for 属性で input と関連付け、アクセシブルネームを必ず持たせること。@media (prefers-reduced-motion: reduce) で transition を無効化する。

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

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

BOOKS · PR · AMAZON

📖 なかしまぁ先生のCSSアニメーション入門 📖 マイクロインタラクション ―UI/UXデザインの神が宿る細部 📖 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
→ EXPANDING SEARCH → CHECKBOX ANIMATION → TOGGLE SWITCH

Floating Label(フローティングラベル)とは

入力前はプレースホルダーのように欄の中に表示され、フォーカスや入力で欄の上端へ小さく移動するラベルです。Googleのマテリアルデザインで広まり、ラベルと入力例の両方を置く場所がないスマホのフォームで特に使われます。

当サイトの Expanding Search は検索欄そのものが横に伸びる演出で、本ページは入力欄の大きさを変えずにラベルだけを動かす別テーマです。項目名が入力後も見えるため、プレースホルダーだけのフォームで起きる「何の欄だったか分からない」を防げます。

実装の要点は :placeholder-shown による入力済み判定と、transform だけで動かすことの2点です。エラー表示はフォーカス中ではなく離れた時に出すと、入力途中で赤くなって急かされる感覚を避けられます。

よくある質問

なぜ placeholder に半角スペースを入れるのですか?

:placeholder-shown は placeholder が表示されている間だけ一致する疑似クラスです。placeholder が空文字だと一致しないため、見えない半角スペースを入れておき、「一致している=未入力」「一致しない=入力済み」の判定に使います。これでJavaScriptなしで入力済みのラベル位置を保てます。

ラベルの移動に top ではなく transform を使う理由は?

top や font-size を変えるとブラウザはレイアウトを再計算し、入力欄が多いフォームでは動きがカクつく原因になります。transform の translate と scale は合成処理だけで済むため滑らかです。transform-origin を left top にすると、縮んでも左端がそろいます。

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

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