Udemyセール!最大95%オフ!1,200円~Udemy公式サイト >

この記事にはプロモーションが含まれています。

【コピペOK】フォーム・ラベル・プレースホルダーアニメーション完全ガイド|4種類

【コピペOK】フォーム・ラベル・プレースホルダーアニメーション完全ガイド|4種類

ケケンタ

フォームのラベルアニメーションを実装したい……

ケケンタ

プレースホルダーが動的に変化する効果を作りたい……

今回はこのようなお悩みをお持ちの方へ向けて

Web制作において重要なUX要素
フォーム・ラベル・プレースホルダーアニメーション

をご紹介します。

4種類のラベル・プレースホルダーアニメーションを完全網羅した実装なので、いままさに「フォームの使いやすさを向上させたい!」という方は丸っとコピペしてどうぞご活用ください!

この記事で紹介するラベル・プレースホルダーアニメーション
  • フローティングラベル(ラベルが上に移動)
  • アンダーライン(下線のアニメーション)
  • フォーカス効果(フォーカス時の強調)
  • バリデーション(エラー表示のアニメーション)
ケケンタ

特にユーザビリティの向上モダンなフォームデザインには、ラベル・プレースホルダーアニメーションが非常に効果的です。この記事のコードをご活用いただきWeb制作の効率化に繋がれば何よりです。

なお、今回ご紹介するアニメーションはCSSとJavaScriptを組み合わせて実装するので、より高度なインタラクションを実現できます。

あわせて読みたい



ケケンタ

ケケンタのITブログでは、WebアプリPHPLaravel)やWeb制作WordPressコーディング)について情報を発信しています。
学習中の方や実務をされている方など多くの方にアクセスいただいていますので、ぜひほかの記事も参考にしてみてください!


運動不足、気になっていませんか?

もしプログラミング学習やお仕事で運動不足が気になっているなら

連続屈伸運動がおすすめです!

ボタンにカーソルを合わせるだけ
カウントダウンが始まるタイマーをご用意してみました!

ケケンタ

無理のない範囲で、ぜひ隙間時間に屈伸運動を取り入れてみて下さい!

タイマースタート

3:00

※運動不足だと連続3分で取り組んでもかなり息が切れます
(僕は加えて気分もちょっと悪くなりました……)
絶対にご無理の無い範囲でお取り組みください!



目次

ラベル・プレースホルダーアニメーションとは

ラベル・プレースホルダーアニメーションは、フォーム入力時にユーザーに視覚的なフィードバックを提供するアニメーション効果です。入力の状態を直感的に伝え、フォームの使いやすさを大幅に向上させる効果的な手法です。

効果的な使用場面

適している場面

  • ログインフォーム
  • お問い合わせフォーム
  • ユーザー登録フォーム
  • 検索フォーム
  • 設定画面のフォーム

避けるべき場面

  • シンプルな入力フィールド
  • アクセシビリティを重視する場面(代替手段が必要)
  • 高齢者向けサイト(認識しにくい場合がある)

実装方法の比較

アニメーション難易度視覚的インパクトパフォーマンスブラウザ対応
フローティングラベル⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
アンダーライン⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
フォーカス効果⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
バリデーション⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

フローティングラベル

① デモ

See the Pen フローティングラベル by ケケンタ (@lgshifbg-the-looper) on CodePen.

このフローティングラベルの特徴
  • ラベルが入力フィールドの上に移動
  • スムーズなアニメーション
  • モダンなデザイン
  • 高い視認性

② HTML

<div class="form-group">
  <div class="input-container">
    <input type="text" id="floating-input" class="floating-input" placeholder=" ">
    <label for="floating-input" class="floating-label">お名前</label>
  </div>
</div>

<div class="form-group">
  <div class="input-container">
    <input type="email" id="floating-email" class="floating-input" placeholder=" ">
    <label for="floating-email" class="floating-label">メールアドレス</label>
  </div>
</div>

<div class="form-group">
  <div class="input-container">
    <textarea id="floating-textarea" class="floating-input" placeholder=" " rows="4"></textarea>
    <label for="floating-textarea" class="floating-label">メッセージ</label>
  </div>
</div>

③ CSS

.form-group {
  margin-bottom: 20px;
}

.input-container {
  position: relative;
  width: 100%;
}

.floating-input {
  width: 100%;
  padding: 16px 12px 8px;
  border: 2px solid #e0e0e0;
  border-radius: 8px;
  font-size: 16px;
  background: transparent;
  transition: all 0.3s ease;
  outline: none;
}

.floating-input:focus {
  border-color: #667eea;
  box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}

.floating-label {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  background: white;
  padding: 0 4px;
  color: #666;
  font-size: 16px;
  transition: all 0.3s ease;
  pointer-events: none;
}

/* フォーカス時または値が入力されている時のラベル位置 */
.floating-input:focus + .floating-label,
.floating-input:not(:placeholder-shown) + .floating-label {
  top: 8px;
  font-size: 12px;
  color: #667eea;
  font-weight: 600;
}

/* textarea用の調整 */
.floating-input[rows] + .floating-label {
  top: 16px;
}

.floating-input[rows]:focus + .floating-label,
.floating-input[rows]:not(:placeholder-shown) + .floating-label {
  top: 8px;
}

④ JavaScript

document.addEventListener('DOMContentLoaded', function() {
  const inputs = document.querySelectorAll('.floating-input');

  inputs.forEach(input => {
    // 初期状態で値がある場合の処理
    if (input.value) {
      input.classList.add('has-value');
    }

    // 入力時の処理
    input.addEventListener('input', function() {
      if (this.value) {
        this.classList.add('has-value');
      } else {
        this.classList.remove('has-value');
      }
    });

    // フォーカス時の処理
    input.addEventListener('focus', function() {
      this.parentElement.classList.add('focused');
    });

    // ブラー時の処理
    input.addEventListener('blur', function() {
      this.parentElement.classList.remove('focused');
    });
  });
});

⑤ カスタマイズ例

/* カラーテーマ変更 */
.floating-input:focus {
  border-color: #ff6b6b;
  box-shadow: 0 0 0 3px rgba(255, 107, 107, 0.1);
}

.floating-input:focus + .floating-label {
  color: #ff6b6b;
}

/* アニメーション速度変更 */
.floating-input,
.floating-label {
  transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

/* バウンス効果 */
.floating-input:focus + .floating-label {
  animation: labelBounce 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}

@keyframes labelBounce {
  0%, 100% { transform: translateY(-50%) scale(1); }
  50% { transform: translateY(-50%) scale(1.1); }
}

アンダーライン

① デモ

See the Pen Untitled by ケケンタ (@lgshifbg-the-looper) on CodePen.

このアンダーラインの特徴
  • 下線がアニメーション
  • シンプルで洗練されたデザイン
  • マテリアルデザイン風
  • 視覚的インパクト大

② HTML

<div class="form-group">
  <div class="underline-container">
    <input type="text" id="underline-input" class="underline-input" placeholder="お名前">
    <div class="underline"></div>
  </div>
</div>

<div class="form-group">
  <div class="underline-container">
    <input type="email" id="underline-email" class="underline-input" placeholder="メールアドレス">
    <div class="underline"></div>
  </div>
</div>

<div class="form-group">
  <div class="underline-container">
    <textarea id="underline-textarea" class="underline-input" placeholder="メッセージ" rows="3"></textarea>
    <div class="underline"></div>
  </div>
</div>

③ CSS

.form-group {
  margin-bottom: 20px;
}

.underline-container {
  position: relative;
  width: 100%;
}

.underline-input {
  width: 100%;
  padding: 12px 0;
  border: none;
  border-bottom: 2px solid #e0e0e0;
  background: transparent;
  font-size: 16px;
  outline: none;
  transition: all 0.3s ease;
}

.underline-input:focus {
  border-bottom-color: transparent;
}

.underline {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 0;
  height: 2px;
  background: linear-gradient(90deg, #667eea, #764ba2);
  transition: width 0.3s ease;
}

.underline-input:focus ~ .underline {
  width: 100%;
}

/* プレースホルダーのスタイル */
.underline-input::placeholder {
  color: #999;
  transition: all 0.3s ease;
}

.underline-input:focus::placeholder {
  color: transparent;
}

④ JavaScript

document.addEventListener('DOMContentLoaded', function() {
  const inputs = document.querySelectorAll('.underline-input');

  inputs.forEach(input => {
    // フォーカス時の処理
    input.addEventListener('focus', function() {
      this.parentElement.classList.add('focused');
    });

    // ブラー時の処理
    input.addEventListener('blur', function() {
      this.parentElement.classList.remove('focused');
    });

    // 入力値の検証
    input.addEventListener('input', function() {
      if (this.value) {
        this.classList.add('has-value');
      } else {
        this.classList.remove('has-value');
      }
    });
  });
});

⑤ カスタマイズ例

/* カラーテーマ変更 */
.underline {
  background: linear-gradient(90deg, #ff6b6b, #4ecdc4);
}

/* アニメーション速度変更 */
.underline {
  transition: width 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

/* 波紋効果 */
.underline {
  background: linear-gradient(90deg, #667eea, #764ba2);
  box-shadow: 0 0 10px rgba(102, 126, 234, 0.3);
}

/* 段階的アニメーション */
.underline-input:focus ~ .underline {
  animation: underlineExpand 0.6s ease-out;
}

@keyframes underlineExpand {
  0% { width: 0; }
  50% { width: 50%; }
  100% { width: 100%; }
}

フォーカス効果

① デモ

See the Pen フォーカス効果 by ケケンタ (@lgshifbg-the-looper) on CodePen.

このフォーカス効果の特徴
  • フォーカス時の視覚的強調
  • 多様なエフェクト
  • ユーザビリティ向上
  • アクセシビリティ配慮

② HTML

<div class="form-group">
  <input type="text" id="focus-input" class="focus-input" placeholder="お名前">
</div>

<div class="form-group">
  <input type="email" id="focus-email" class="focus-input" placeholder="メールアドレス">
</div>

<div class="form-group">
  <textarea id="focus-textarea" class="focus-input" placeholder="メッセージ" rows="3"></textarea>
</div>

③ CSS

.form-group {
  margin-bottom: 20px;
}

.focus-input {
  width: 100%;
  padding: 12px 16px;
  border: 2px solid #e0e0e0;
  border-radius: 8px;
  font-size: 16px;
  background: white;
  transition: all 0.3s ease;
  outline: none;
  position: relative;
}

.focus-input:focus {
  border-color: #667eea;
  box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.1);
  transform: translateY(-2px);
}

/* プレースホルダーのアニメーション */
.focus-input::placeholder {
  color: #999;
  transition: all 0.3s ease;
}

.focus-input:focus::placeholder {
  color: #667eea;
  transform: translateX(10px);
}

/* 入力値がある時のスタイル */
.focus-input:not(:placeholder-shown) {
  border-color: #4caf50;
  background: #f8fff8;
}

/* エラー状態 */
.focus-input.error {
  border-color: #f44336;
  animation: shake 0.5s ease-in-out;
}

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-5px); }
  75% { transform: translateX(5px); }
}

④ JavaScript

document.addEventListener('DOMContentLoaded', function() {
  const inputs = document.querySelectorAll('.focus-input');

  inputs.forEach(input => {
    // フォーカス時の処理
    input.addEventListener('focus', function() {
      this.parentElement.classList.add('focused');
    });

    // ブラー時の処理
    input.addEventListener('blur', function() {
      this.parentElement.classList.remove('focused');
    });

    // 入力値の検証
    input.addEventListener('input', function() {
      if (this.value) {
        this.classList.add('has-value');
      } else {
        this.classList.remove('has-value');
      }
    });

    // エラー状態のシミュレーション
    input.addEventListener('blur', function() {
      if (this.type === 'email' && this.value && !isValidEmail(this.value)) {
        this.classList.add('error');
      } else {
        this.classList.remove('error');
      }
    });
  });

  // メールアドレスの簡易検証
  function isValidEmail(email) {
    return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
  }
});

⑤ カスタマイズ例

/* カラーテーマ変更 */
.focus-input:focus {
  border-color: #ff6b6b;
  box-shadow: 0 0 0 4px rgba(255, 107, 107, 0.1);
}

.focus-input:focus::placeholder {
  color: #ff6b6b;
}

/* スケール効果 */
.focus-input:focus {
  transform: scale(1.02);
}

/* 回転効果 */
.focus-input:focus {
  transform: rotate(1deg);
}

/* パルス効果 */
.focus-input:focus {
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% { box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.1); }
  50% { box-shadow: 0 0 0 8px rgba(102, 126, 234, 0.2); }
  100% { box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.1); }
}

バリデーション

① デモ

入力内容によってフォーム右側に「✕」や「✓」が表示されます。

See the Pen バリデーション by ケケンタ (@lgshifbg-the-looper) on CodePen.

このバリデーションの特徴
  • リアルタイムエラー表示
  • 視覚的フィードバック
  • ユーザーフレンドリー
  • 多様なエラーパターン

② HTML

<div class="form-group">
  <div class="validation-container">
    <input type="text" id="validation-name" class="validation-input" placeholder="お名前" required>
    <div class="validation-icon"></div>
    <div class="validation-message"></div>
  </div>
</div>

<div class="form-group">
  <div class="validation-container">
    <input type="email" id="validation-email" class="validation-input" placeholder="メールアドレス" required>
    <div class="validation-icon"></div>
    <div class="validation-message"></div>
  </div>
</div>

<div class="form-group">
  <div class="validation-container">
    <input type="password" id="validation-password" class="validation-input" placeholder="パスワード" required>
    <div class="validation-icon"></div>
    <div class="validation-message"></div>
  </div>
</div>

③ CSS

.form-group {
  margin-bottom: 20px;
}

.validation-container {
  position: relative;
  width: 100%;
}

.validation-input {
  width: 100%;
  padding: 12px 40px 12px 16px;
  border: 2px solid #e0e0e0;
  border-radius: 8px;
  font-size: 16px;
  background: white;
  transition: all 0.3s ease;
  outline: none;
}

.validation-input:focus {
  border-color: #667eea;
  box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}

/* バリデーションアイコン */
.validation-icon {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 20px;
  height: 20px;
  border-radius: 50%;
  transition: all 0.3s ease;
  opacity: 0;
}

/* 成功状態 */
.validation-input.valid {
  border-color: #4caf50;
  background: #f8fff8;
}

.validation-input.valid + .validation-icon {
  background: #4caf50;
  opacity: 1;
  animation: successPulse 0.6s ease;
}

.validation-input.valid + .validation-icon::before {
  content: '✓';
  color: white;
  font-size: 14px;
  font-weight: bold;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/* エラー状態 */
.validation-input.error {
  border-color: #f44336;
  background: #fff8f8;
  animation: errorShake 0.5s ease-in-out;
}

.validation-input.error + .validation-icon {
  background: #f44336;
  opacity: 1;
  animation: errorPulse 0.6s ease;
}

.validation-input.error + .validation-icon::before {
  content: '✕';
  color: white;
  font-size: 14px;
  font-weight: bold;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/* バリデーションメッセージ */
.validation-message {
  position: absolute;
  top: 100%;
  left: 0;
  font-size: 12px;
  margin-top: 4px;
  opacity: 0;
  transform: translateY(-10px);
  transition: all 0.3s ease;
}

.validation-input.error ~ .validation-message {
  opacity: 1;
  transform: translateY(0);
  color: #f44336;
}

/* アニメーション */
@keyframes successPulse {
  0% { transform: translateY(-50%) scale(0); }
  50% { transform: translateY(-50%) scale(1.2); }
  100% { transform: translateY(-50%) scale(1); }
}

@keyframes errorPulse {
  0% { transform: translateY(-50%) scale(0); }
  50% { transform: translateY(-50%) scale(1.2); }
  100% { transform: translateY(-50%) scale(1); }
}

@keyframes errorShake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-5px); }
  75% { transform: translateX(5px); }
}

④ JavaScript

document.addEventListener('DOMContentLoaded', function() {
  const inputs = document.querySelectorAll('.validation-input');

  inputs.forEach(input => {
    // リアルタイムバリデーション
    input.addEventListener('input', function() {
      validateField(this);
    });

    // ブラー時のバリデーション
    input.addEventListener('blur', function() {
      validateField(this);
    });

    // フォーカス時の処理
    input.addEventListener('focus', function() {
      this.parentElement.classList.add('focused');
    });
  });

  function validateField(field) {
    const message = field.parentElement.querySelector('.validation-message');
    let isValid = true;
    let errorMessage = '';

    // 必須チェック
    if (field.hasAttribute('required') && !field.value.trim()) {
      isValid = false;
      errorMessage = 'この項目は必須です';
    }

    // メールアドレスチェック
    if (field.type === 'email' && field.value) {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(field.value)) {
        isValid = false;
        errorMessage = '有効なメールアドレスを入力してください';
      }
    }

    // パスワードチェック
    if (field.type === 'password' && field.value) {
      if (field.value.length < 8) {
        isValid = false;
        errorMessage = 'パスワードは8文字以上で入力してください';
      }
    }

    // 名前チェック
    if (field.placeholder === 'お名前' && field.value) {
      if (field.value.length < 2) {
        isValid = false;
        errorMessage = '名前は2文字以上で入力してください';
      }
    }

    // クラスの更新
    field.classList.remove('valid', 'error');
    if (field.value) {
      field.classList.add(isValid ? 'valid' : 'error');
    }

    // メッセージの更新
    if (message) {
      message.textContent = errorMessage;
    }
  }
});

⑤ カスタマイズ例

/* カラーテーマ変更 */
.validation-input.valid {
  border-color: #00c853;
}

.validation-input.error {
  border-color: #d32f2f;
}

/* カスタムアイコン */
.validation-input.valid + .validation-icon::before {
  content: '🎉';
  font-size: 12px;
}

.validation-input.error + .validation-icon::before {
  content: '⚠️';
  font-size: 12px;
}

/* スライドイン効果 */
.validation-message {
  transform: translateX(-20px);
}

.validation-input.error ~ .validation-message {
  transform: translateX(0);
}

/* フェードイン効果 */
.validation-input.valid,
.validation-input.error {
  animation: fadeIn 0.3s ease;
}

@keyframes fadeIn {
  from { opacity: 0.7; }
  to { opacity: 1; }
}

まとめ

今回ご紹介したフォーム・ラベル・プレースホルダーアニメーションは、Webサイトのユーザビリティを向上させる重要な要素です。

実装のコツ

  • アクセシビリティを考慮したHTML構造
  • 適切なアニメーション時間(300ms〜500ms)
  • スムーズなイージング関数の使用
  • モバイルデバイスでの動作確認
  • エラー状態の明確な表示

避けるべきポイント

  • 過度に複雑なアニメーション
  • 長すぎるアニメーション時間
  • アクセシビリティを無視した実装
  • パフォーマンスを考慮しない実装
  • エラーメッセージの不明確な表示

おすすめの組み合わせ

  • シンプルなフォーム: フォーカス効果
  • モダンなフォーム: フローティングラベル
  • プレミアムフォーム: アンダーライン + バリデーション
  • ユーザビリティ重視: バリデーション + フォーカス効果
ケケンタ

特にユーザビリティの向上モダンなフォームデザインでは、ラベル・プレースホルダーアニメーションがユーザーエクスペリエンスを大きく左右します。この記事のコードをご活用いただき、より使いやすいWebサイトの制作に繋がれば何よりです!

あわせて読みたい

【コピペOK】フォーム・ラベル・プレースホルダーアニメーション完全ガイド|4種類のアイキャッチ画像

この記事が気に入ったら
フォローしてね!

この記事が良いと思ったらシェアしてね!

コメント

コメントする

CAPTCHA


目次