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

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

【コピペOK】バリデーションアニメーション|6種類【Web制作】

【コピペOK】バリデーションアニメーション|6種類【Web制作】

ケケンタ

バリデーションアニメーションを実装したい……

ケケンタ

入力エラーをより分かりやすく表示したい……

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

Web制作において必須のUI要素
バリデーションアニメーション

をご紹介します。

6種類のアニメーション効果を完全網羅した実装なので、いままさに「バリデーションアニメーションを実装しないといけない!」という方は丸っとコピペしてどうぞご活用ください!

この記事で紹介するバリデーションアニメーション
  • シェイク効果(揺れる効果)
  • パルス効果(脈動効果)
  • スライド効果(スライドイン)
  • フェード効果(フェードイン)
  • カラー変化効果(色の変化)
  • アイコン表示効果
ケケンタ

特にフォームログイン画面には、バリデーションアニメーションが非常に効果的です。この記事のコードをご活用いただきWeb制作の効率化に繋がれば何よりです。

なお、今回ご紹介するアニメーションはCSSとJavaScriptで実装できるので、基本的なコーディング知識があれば安心してご利用いただけます。

あわせて読みたい

Webアニメーションの引き出しを増やすのにおすすめの書籍

created by Rinker
¥1,399 (2025/08/11 08:44:57時点 Amazon調べ-詳細)




ケケンタ

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


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

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

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

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

ケケンタ

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

タイマースタート

3:00

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



目次

バリデーションアニメーションとは

バリデーションアニメーションは、ユーザーの入力が正しくない場合に表示される視覚的なフィードバックを提供するアニメーション効果です。エラーの内容を分かりやすく伝え、ユーザビリティを向上させる効果的な手法です。

効果的な使用場面

適している場面

  • フォーム入力フィールド
  • ログイン・サインアップ画面
  • パスワード入力
  • メールアドレス入力
  • 必須項目の入力チェック

避けるべき場面

  • 過度に派手なアニメーション
  • パフォーマンスを重視する場面
  • アクセシビリティを重視する場面

実装方法の比較

アニメーション難易度視覚的インパクトパフォーマンスブラウザ対応
シェイク効果⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
パルス効果⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
スライド効果⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
フェード効果⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
カラー変化効果⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
アイコン表示効果⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

シェイク効果

入力エラー時に要素が揺れるアニメーションです。

① デモ

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

このシェイク効果の特徴
  • 視覚的インパクトが高い
  • エラーを明確に示す
  • 注目を集める効果

② HTML

<div class="form-container">
  <div class="input-group">
    <input type="text" id="shake-input" class="shake-input" placeholder="お名前を入力">
    <div class="error-message" id="shake-error">お名前を入力してください</div>
  </div>

  <div class="input-group">
    <input type="email" id="shake-email" class="shake-input" placeholder="メールアドレスを入力">
    <div class="error-message" id="shake-email-error">正しいメールアドレスを入力してください</div>
  </div>

  <div class="input-group">
    <input type="password" id="shake-password" class="shake-input" placeholder="パスワードを入力">
    <div class="error-message" id="shake-password-error">パスワードは8文字以上で入力してください</div>
  </div>

  <button type="button" id="shake-submit" class="submit-btn">送信</button>
</div>

③ CSS

/* フォームコンテナ */
.form-container {
  max-width: 500px;
  margin: 0 auto;
  padding: 40px 20px;
  font-family: 'Arial', sans-serif;
}

.input-group {
  position: relative;
  margin-bottom: 30px;
}

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

.shake-input:focus {
  border-color: #667eea;
}

.shake-input.error {
  border-color: #ff6b6b;
  animation: shake 0.5s ease-in-out;
}

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
  20%, 40%, 60%, 80% { transform: translateX(5px); }
}

.error-message {
  color: #ff6b6b;
  font-size: 14px;
  margin-top: 8px;
  opacity: 0;
  transform: translateY(-10px);
  transition: all 0.3s ease;
}

.error-message.show {
  opacity: 1;
  transform: translateY(0);
}

.submit-btn {
  width: 100%;
  padding: 16px;
  background: #667eea;
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 16px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.submit-btn:hover {
  background: #5a6fd8;
}

④ JavaScript

document.addEventListener('DOMContentLoaded', function() {
  const shakeInputs = document.querySelectorAll('.shake-input');
  const submitBtn = document.getElementById('shake-submit');

  // バリデーション関数
  function validateInput(input) {
    const value = input.value.trim();
    const errorElement = input.parentElement.querySelector('.error-message');

    // 入力値の検証
    if (!value) {
      showError(input, errorElement);
      return false;
    }

    // メールアドレスの検証
    if (input.type === 'email') {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(value)) {
        showError(input, errorElement);
        return false;
      }
    }

    // パスワードの検証
    if (input.type === 'password') {
      if (value.length < 8) {
        showError(input, errorElement);
        return false;
      }
    }

    hideError(input, errorElement);
    return true;
  }

  // エラー表示
  function showError(input, errorElement) {
    input.classList.add('error');
    errorElement.classList.add('show');
  }

  // エラー非表示
  function hideError(input, errorElement) {
    input.classList.remove('error');
    errorElement.classList.remove('show');
  }

  // 入力時の検証
  shakeInputs.forEach(input => {
    input.addEventListener('blur', function() {
      validateInput(this);
    });

    input.addEventListener('input', function() {
      if (this.classList.contains('error')) {
        validateInput(this);
      }
    });
  });

  // 送信ボタンクリック時の検証
  submitBtn.addEventListener('click', function() {
    let isValid = true;

    shakeInputs.forEach(input => {
      if (!validateInput(input)) {
        isValid = false;
      }
    });

    if (isValid) {
      alert('送信しました!');
    }
  });
});

⑤ カスタマイズ例

/* シェイク速度の調整 */
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  10%, 30%, 50%, 70%, 90% { transform: translateX(-10px); }
  20%, 40%, 60%, 80% { transform: translateX(10px); }
}

/* シェイク強度の調整 */
.shake-input.error {
  animation: shake 0.8s ease-in-out;
}

/* エラー色の変更 */
.shake-input.error {
  border-color: #ff4757;
}

パルス効果

入力エラー時に脈動するアニメーションです。

① デモ

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

このパルス効果の特徴
  • 動的な表現
  • 視覚的インパクト
  • 注目を集める効果

② HTML

<div class="form-container">
  <div class="input-group">
    <input type="text" id="pulse-input" class="pulse-input" placeholder="お名前を入力">
    <div class="error-message" id="pulse-error">お名前を入力してください</div>
  </div>

  <div class="input-group">
    <input type="email" id="pulse-email" class="pulse-input" placeholder="メールアドレスを入力">
    <div class="error-message" id="pulse-email-error">正しいメールアドレスを入力してください</div>
  </div>

  <div class="input-group">
    <input type="password" id="pulse-password" class="pulse-input" placeholder="パスワードを入力">
    <div class="error-message" id="pulse-password-error">パスワードは8文字以上で入力してください</div>
  </div>

  <button type="button" id="pulse-submit" class="submit-btn">送信</button>
</div>

③ CSS

/* フォームコンテナ */
.form-container {
  max-width: 500px;
  margin: 0 auto;
  padding: 40px 20px;
  font-family: 'Arial', sans-serif;
}

.input-group {
  position: relative;
  margin-bottom: 30px;
}

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

.pulse-input:focus {
  border-color: #667eea;
}

.pulse-input.error {
  border-color: #ff6b6b;
  animation: pulse 2s ease-in-out infinite;
}

@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(255, 107, 107, 0.4);
  }
  70% {
    box-shadow: 0 0 0 10px rgba(255, 107, 107, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(255, 107, 107, 0);
  }
}

.error-message {
  color: #ff6b6b;
  font-size: 14px;
  margin-top: 8px;
  opacity: 0;
  transform: translateY(-10px);
  transition: all 0.3s ease;
}

.error-message.show {
  opacity: 1;
  transform: translateY(0);
}

.submit-btn {
  width: 100%;
  padding: 16px;
  background: #667eea;
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 16px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.submit-btn:hover {
  background: #5a6fd8;
}

④ JavaScript

document.addEventListener('DOMContentLoaded', function() {
  const pulseInputs = document.querySelectorAll('.pulse-input');
  const submitBtn = document.getElementById('pulse-submit');

  // バリデーション関数
  function validateInput(input) {
    const value = input.value.trim();
    const errorElement = input.parentElement.querySelector('.error-message');

    // 入力値の検証
    if (!value) {
      showError(input, errorElement);
      return false;
    }

    // メールアドレスの検証
    if (input.type === 'email') {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(value)) {
        showError(input, errorElement);
        return false;
      }
    }

    // パスワードの検証
    if (input.type === 'password') {
      if (value.length < 8) {
        showError(input, errorElement);
        return false;
      }
    }

    hideError(input, errorElement);
    return true;
  }

  // エラー表示
  function showError(input, errorElement) {
    input.classList.add('error');
    errorElement.classList.add('show');
  }

  // エラー非表示
  function hideError(input, errorElement) {
    input.classList.remove('error');
    errorElement.classList.remove('show');
  }

  // 入力時の検証
  pulseInputs.forEach(input => {
    input.addEventListener('blur', function() {
      validateInput(this);
    });

    input.addEventListener('input', function() {
      if (this.classList.contains('error')) {
        validateInput(this);
      }
    });
  });

  // 送信ボタンクリック時の検証
  submitBtn.addEventListener('click', function() {
    let isValid = true;

    pulseInputs.forEach(input => {
      if (!validateInput(input)) {
        isValid = false;
      }
    });

    if (isValid) {
      alert('送信しました!');
    }
  });
});

⑤ カスタマイズ例

/* パルス速度の調整 */
.pulse-input.error {
  animation: pulse 1s ease-in-out infinite;
}

/* パルス色の変更 */
@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(255, 71, 87, 0.4);
  }
  70% {
    box-shadow: 0 0 0 10px rgba(255, 71, 87, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(255, 71, 87, 0);
  }
}

/* パルス強度の調整 */
@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(255, 107, 107, 0.6);
  }
  70% {
    box-shadow: 0 0 0 15px rgba(255, 107, 107, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(255, 107, 107, 0);
  }
}

スライド効果

エラーメッセージがスライドインするアニメーションです。

① デモ

See the Pen バリデーションスライド効果 by ケケンタ (@lgshifbg-the-looper) on CodePen.

このスライド効果の特徴
  • スムーズな表示
  • 視覚的フィードバック
  • 洗練された表現

② HTML

<div class="form-container">
  <div class="input-group">
    <input type="text" id="slide-input" class="slide-input" placeholder="お名前を入力">
    <div class="error-message" id="slide-error">お名前を入力してください</div>
  </div>

  <div class="input-group">
    <input type="email" id="slide-email" class="slide-input" placeholder="メールアドレスを入力">
    <div class="error-message" id="slide-email-error">正しいメールアドレスを入力してください</div>
  </div>

  <div class="input-group">
    <input type="password" id="slide-password" class="slide-input" placeholder="パスワードを入力">
    <div class="error-message" id="slide-password-error">パスワードは8文字以上で入力してください</div>
  </div>

  <button type="button" id="slide-submit" class="submit-btn">送信</button>
</div>

③ CSS

/* フォームコンテナ */
.form-container {
  max-width: 500px;
  margin: 0 auto;
  padding: 40px 20px;
  font-family: 'Arial', sans-serif;
}

.input-group {
  position: relative;
  margin-bottom: 30px;
}

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

.slide-input:focus {
  border-color: #667eea;
}

.slide-input.error {
  border-color: #ff6b6b;
}

.error-message {
  color: #ff6b6b;
  font-size: 14px;
  margin-top: 8px;
  opacity: 0;
  transform: translateX(-20px);
  transition: all 0.4s ease;
  overflow: hidden;
  max-height: 0;
}

.error-message.show {
  opacity: 1;
  transform: translateX(0);
  max-height: 50px;
}

.submit-btn {
  width: 100%;
  padding: 16px;
  background: #667eea;
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 16px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.submit-btn:hover {
  background: #5a6fd8;
}

④ JavaScript

document.addEventListener('DOMContentLoaded', function() {
  const slideInputs = document.querySelectorAll('.slide-input');
  const submitBtn = document.getElementById('slide-submit');

  // バリデーション関数
  function validateInput(input) {
    const value = input.value.trim();
    const errorElement = input.parentElement.querySelector('.error-message');

    // 入力値の検証
    if (!value) {
      showError(input, errorElement);
      return false;
    }

    // メールアドレスの検証
    if (input.type === 'email') {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(value)) {
        showError(input, errorElement);
        return false;
      }
    }

    // パスワードの検証
    if (input.type === 'password') {
      if (value.length < 8) {
        showError(input, errorElement);
        return false;
      }
    }

    hideError(input, errorElement);
    return true;
  }

  // エラー表示
  function showError(input, errorElement) {
    input.classList.add('error');
    errorElement.classList.add('show');
  }

  // エラー非表示
  function hideError(input, errorElement) {
    input.classList.remove('error');
    errorElement.classList.remove('show');
  }

  // 入力時の検証
  slideInputs.forEach(input => {
    input.addEventListener('blur', function() {
      validateInput(this);
    });

    input.addEventListener('input', function() {
      if (this.classList.contains('error')) {
        validateInput(this);
      }
    });
  });

  // 送信ボタンクリック時の検証
  submitBtn.addEventListener('click', function() {
    let isValid = true;

    slideInputs.forEach(input => {
      if (!validateInput(input)) {
        isValid = false;
      }
    });

    if (isValid) {
      alert('送信しました!');
    }
  });
});

⑤ カスタマイズ例

/* スライド速度の調整 */
.error-message {
  transition: all 0.6s ease;
}

/* スライド方向の変更 */
.error-message {
  transform: translateY(-20px);
}

.error-message.show {
  transform: translateY(0);
}

/* スライド強度の調整 */
.error-message {
  transform: translateX(-30px);
}

.error-message.show {
  transform: translateX(0);
}

フェード効果

エラーメッセージがフェードインするアニメーションです。

① デモ

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

このフェード効果の特徴
  • シンプルで分かりやすい
  • アクセシビリティが高い
  • モダンな印象

② HTML

<div class="form-container">
  <div class="input-group">
    <input type="text" id="fade-input" class="fade-input" placeholder="お名前を入力">
    <div class="error-message" id="fade-error">お名前を入力してください</div>
  </div>

  <div class="input-group">
    <input type="email" id="fade-email" class="fade-input" placeholder="メールアドレスを入力">
    <div class="error-message" id="fade-email-error">正しいメールアドレスを入力してください</div>
  </div>

  <div class="input-group">
    <input type="password" id="fade-password" class="fade-input" placeholder="パスワードを入力">
    <div class="error-message" id="fade-password-error">パスワードは8文字以上で入力してください</div>
  </div>

  <button type="button" id="fade-submit" class="submit-btn">送信</button>
</div>

③ CSS

/* フォームコンテナ */
.form-container {
  max-width: 500px;
  margin: 0 auto;
  padding: 40px 20px;
  font-family: 'Arial', sans-serif;
}

.input-group {
  position: relative;
  margin-bottom: 30px;
}

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

.fade-input:focus {
  border-color: #667eea;
}

.fade-input.error {
  border-color: #ff6b6b;
}

.error-message {
  color: #ff6b6b;
  font-size: 14px;
  margin-top: 8px;
  opacity: 0;
  visibility: hidden;
  transition: all 0.3s ease;
}

.error-message.show {
  opacity: 1;
  visibility: visible;
}

.submit-btn {
  width: 100%;
  padding: 16px;
  background: #667eea;
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 16px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.submit-btn:hover {
  background: #5a6fd8;
}

④ JavaScript

document.addEventListener('DOMContentLoaded', function() {
  const fadeInputs = document.querySelectorAll('.fade-input');
  const submitBtn = document.getElementById('fade-submit');

  // バリデーション関数
  function validateInput(input) {
    const value = input.value.trim();
    const errorElement = input.parentElement.querySelector('.error-message');

    // 入力値の検証
    if (!value) {
      showError(input, errorElement);
      return false;
    }

    // メールアドレスの検証
    if (input.type === 'email') {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(value)) {
        showError(input, errorElement);
        return false;
      }
    }

    // パスワードの検証
    if (input.type === 'password') {
      if (value.length < 8) {
        showError(input, errorElement);
        return false;
      }
    }

    hideError(input, errorElement);
    return true;
  }

  // エラー表示
  function showError(input, errorElement) {
    input.classList.add('error');
    errorElement.classList.add('show');
  }

  // エラー非表示
  function hideError(input, errorElement) {
    input.classList.remove('error');
    errorElement.classList.remove('show');
  }

  // 入力時の検証
  fadeInputs.forEach(input => {
    input.addEventListener('blur', function() {
      validateInput(this);
    });

    input.addEventListener('input', function() {
      if (this.classList.contains('error')) {
        validateInput(this);
      }
    });
  });

  // 送信ボタンクリック時の検証
  submitBtn.addEventListener('click', function() {
    let isValid = true;

    fadeInputs.forEach(input => {
      if (!validateInput(input)) {
        isValid = false;
      }
    });

    if (isValid) {
      alert('送信しました!');
    }
  });
});

⑤ カスタマイズ例

/* フェード速度の調整 */
.error-message {
  transition: all 0.5s ease;
}

/* フェード強度の調整 */
.error-message {
  opacity: 0;
  transform: scale(0.9);
}

.error-message.show {
  opacity: 1;
  transform: scale(1);
}

/* フェード方向の変更 */
.error-message {
  opacity: 0;
  transform: translateY(10px);
}

.error-message.show {
  opacity: 1;
  transform: translateY(0);
}

カラー変化効果

エラー時に色が変化するアニメーションです。

① デモ

See the Pen バリデーションカラー変化効果 by ケケンタ (@lgshifbg-the-looper) on CodePen.

このカラー変化効果の特徴
  • 直感的な状態表示
  • 視覚的フィードバック
  • カラフルな表現

② HTML

<div class="form-container">
  <div class="input-group">
    <input type="text" id="color-input" class="color-input" placeholder="お名前を入力">
    <div class="error-message" id="color-error">お名前を入力してください</div>
  </div>

  <div class="input-group">
    <input type="email" id="color-email" class="color-input" placeholder="メールアドレスを入力">
    <div class="error-message" id="color-email-error">正しいメールアドレスを入力してください</div>
  </div>

  <div class="input-group">
    <input type="password" id="color-password" class="color-input" placeholder="パスワードを入力">
    <div class="error-message" id="color-password-error">パスワードは8文字以上で入力してください</div>
  </div>

  <button type="button" id="color-submit" class="submit-btn">送信</button>
</div>

③ CSS

/* フォームコンテナ */
.form-container {
  max-width: 500px;
  margin: 0 auto;
  padding: 40px 20px;
  font-family: 'Arial', sans-serif;
}

.input-group {
  position: relative;
  margin-bottom: 30px;
}

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

.color-input:focus {
  border-color: #667eea;
  background: rgba(102, 126, 234, 0.05);
}

.color-input.error {
  border-color: #ff6b6b;
  background: rgba(255, 107, 107, 0.05);
  color: #ff6b6b;
}

.color-input.success {
  border-color: #51cf66;
  background: rgba(81, 207, 102, 0.05);
  color: #51cf66;
}

.error-message {
  color: #ff6b6b;
  font-size: 14px;
  margin-top: 8px;
  opacity: 0;
  transform: translateY(-10px);
  transition: all 0.3s ease;
}

.error-message.show {
  opacity: 1;
  transform: translateY(0);
}

.submit-btn {
  width: 100%;
  padding: 16px;
  background: #667eea;
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 16px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.submit-btn:hover {
  background: #5a6fd8;
}

④ JavaScript

document.addEventListener('DOMContentLoaded', function() {
  const colorInputs = document.querySelectorAll('.color-input');
  const submitBtn = document.getElementById('color-submit');

  // バリデーション関数
  function validateInput(input) {
    const value = input.value.trim();
    const errorElement = input.parentElement.querySelector('.error-message');

    // 入力値の検証
    if (!value) {
      showError(input, errorElement);
      return false;
    }

    // メールアドレスの検証
    if (input.type === 'email') {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(value)) {
        showError(input, errorElement);
        return false;
      }
    }

    // パスワードの検証
    if (input.type === 'password') {
      if (value.length < 8) {
        showError(input, errorElement);
        return false;
      }
    }

    showSuccess(input, errorElement);
    return true;
  }

  // エラー表示
  function showError(input, errorElement) {
    input.classList.remove('success');
    input.classList.add('error');
    errorElement.classList.add('show');
  }

  // 成功表示
  function showSuccess(input, errorElement) {
    input.classList.remove('error');
    input.classList.add('success');
    errorElement.classList.remove('show');
  }

  // 入力時の検証
  colorInputs.forEach(input => {
    input.addEventListener('blur', function() {
      validateInput(this);
    });

    input.addEventListener('input', function() {
      if (this.classList.contains('error') || this.classList.contains('success')) {
        validateInput(this);
      }
    });
  });

  // 送信ボタンクリック時の検証
  submitBtn.addEventListener('click', function() {
    let isValid = true;

    colorInputs.forEach(input => {
      if (!validateInput(input)) {
        isValid = false;
      }
    });

    if (isValid) {
      alert('送信しました!');
    }
  });
});

⑤ カスタマイズ例

/* カラー変化速度の調整 */
.color-input {
  transition: all 0.5s ease;
}

/* エラー色の変更 */
.color-input.error {
  border-color: #ff4757;
  background: rgba(255, 71, 87, 0.05);
  color: #ff4757;
}

/* 成功色の変更 */
.color-input.success {
  border-color: #2ed573;
  background: rgba(46, 213, 115, 0.05);
  color: #2ed573;
}

アイコン表示効果

エラー時にアイコンが表示されるアニメーションです。

① デモ

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

このアイコン表示効果の特徴
  • 右端配置で直感的な位置
  • 円形の囲みでモダンな見た目
  • テキストアイコンで軽量で分かりやすい
  • 背景色とシャドウの動的変化

② HTML

<div class="form-container">
  <div class="input-group">
    <input type="text" id="icon-input" class="icon-input" placeholder="お名前を入力">
    <div class="icon-wrapper">
      <span class="error-icon">✕</span>
      <span class="success-icon">✓</span>
    </div>
    <div class="error-message" id="icon-error">お名前を入力してください</div>
  </div>

  <div class="input-group">
    <input type="email" id="icon-email" class="icon-input" placeholder="メールアドレスを入力">
    <div class="icon-wrapper">
      <span class="error-icon">✕</span>
      <span class="success-icon">✓</span>
    </div>
    <div class="error-message" id="icon-email-error">正しいメールアドレスを入力してください</div>
  </div>

  <div class="input-group">
    <input type="password" id="icon-password" class="icon-input" placeholder="パスワードを入力">
    <div class="icon-wrapper">
      <span class="error-icon">✕</span>
      <span class="success-icon">✓</span>
    </div>
    <div class="error-message" id="icon-password-error">パスワードは8文字以上で入力してください</div>
  </div>

  <button type="button" id="icon-submit" class="submit-btn">送信</button>
</div>

③ CSS

/* フォームコンテナ */
.form-container {
  max-width: 500px;
  margin: 0 auto;
  padding: 40px 20px;
  font-family: 'Arial', sans-serif;
}

.input-group {
  position: relative;
  margin-bottom: 30px;
  display: flex;
  align-items: center;
}

.icon-wrapper {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(10px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
}

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

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

.icon-input.error {
  border-color: #ff6b6b;
  box-shadow: 0 0 0 3px rgba(255, 107, 107, 0.1);
}

.icon-input.success {
  border-color: #51cf66;
  box-shadow: 0 0 0 3px rgba(81, 207, 102, 0.1);
}

.error-icon,
.success-icon {
  font-size: 18px;
  font-weight: bold;
  opacity: 0;
  visibility: hidden;
  transform: scale(0.1) rotate(-180deg);
  transition: all 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
}

.error-icon.show {
  opacity: 1;
  visibility: visible;
  transform: scale(1) rotate(0deg);
  color: white;
}

.icon-wrapper.error {
  background: #ff6b6b;
  box-shadow: 0 2px 8px rgba(255, 107, 107, 0.3);
}

.success-icon.show {
  opacity: 1;
  visibility: visible;
  transform: scale(1) rotate(0deg);
  color: white;
}

.icon-wrapper.success {
  background: #51cf66;
  box-shadow: 0 2px 8px rgba(81, 207, 102, 0.3);
}

.error-message {
  position: absolute;
  left: 0;
  top: 100%;
  color: #ff6b6b;
  font-size: 14px;
  margin-top: 8px;
  opacity: 0;
  transform: translateY(-10px);
  transition: all 0.3s ease;
}

.error-message.show {
  opacity: 1;
  transform: translateY(0);
}

.submit-btn {
  width: 100%;
  padding: 16px;
  background: #667eea;
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 16px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.submit-btn:hover {
  background: #5a6fd8;
}

④ JavaScript

document.addEventListener('DOMContentLoaded', function() {
  const iconInputs = document.querySelectorAll('.icon-input');
  const submitBtn = document.getElementById('icon-submit');

  // バリデーション関数
  function validateInput(input) {
    const value = input.value.trim();
    const errorElement = input.parentElement.querySelector('.error-message');
    const errorIcon = input.parentElement.querySelector('.error-icon');
    const successIcon = input.parentElement.querySelector('.success-icon');

    // 入力値の検証
    if (!value) {
      showError(input, errorElement, errorIcon, successIcon);
      return false;
    }

    // メールアドレスの検証
    if (input.type === 'email') {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(value)) {
        showError(input, errorElement, errorIcon, successIcon);
        return false;
      }
    }

    // パスワードの検証
    if (input.type === 'password') {
      if (value.length < 8) {
        showError(input, errorElement, errorIcon, successIcon);
        return false;
      }
    }

    showSuccess(input, errorElement, errorIcon, successIcon);
    return true;
  }

  // エラー表示
  function showError(input, errorElement, errorIcon, successIcon) {
    const iconWrapper = input.parentElement.querySelector('.icon-wrapper');
    input.classList.remove('success');
    input.classList.add('error');
    iconWrapper.classList.remove('success');
    iconWrapper.classList.add('error');
    errorElement.classList.add('show');
    errorIcon.classList.add('show');
    successIcon.classList.remove('show');
  }

  // 成功表示
  function showSuccess(input, errorElement, errorIcon, successIcon) {
    const iconWrapper = input.parentElement.querySelector('.icon-wrapper');
    input.classList.remove('error');
    input.classList.add('success');
    iconWrapper.classList.remove('error');
    iconWrapper.classList.add('success');
    errorElement.classList.remove('show');
    errorIcon.classList.remove('show');
    successIcon.classList.add('show');
  }

  // 入力時の検証
  iconInputs.forEach(input => {
    input.addEventListener('blur', function() {
      validateInput(this);
    });

    input.addEventListener('input', function() {
      if (this.classList.contains('error') || this.classList.contains('success')) {
        validateInput(this);
      }
    });
  });

  // 送信ボタンクリック時の検証
  submitBtn.addEventListener('click', function() {
    let isValid = true;

    iconInputs.forEach(input => {
      if (!validateInput(input)) {
        isValid = false;
      }
    });

    if (isValid) {
      alert('送信しました!');
    }
  });
});

⑤ カスタマイズ例

/* アイコン表示速度の調整 */
.error-icon,
.success-icon {
  transition: all 0.5s ease;
}

/* アイコンサイズの調整 */
.error-icon,
.success-icon {
  font-size: 20px;
}

/* アイコン表示強度の調整 */
.error-icon.show,
.success-icon.show {
  transform: scale(1.1) rotate(0deg);
}

/* アイコンの初期表示サイズ調整 */
.error-icon,
.success-icon {
  transform: scale(0.1) rotate(-180deg);
}

まとめ

今回ご紹介した6種類のバリデーションアニメーションは、それぞれ異なる特徴と用途があります。

用途別おすすめ

  • フォーム入力: シェイク効果・パルス効果
  • ログイン画面: カラー変化効果・アイコン表示効果
  • 重要度の高いエラー: シェイク効果・パルス効果
  • 軽微なエラー: フェード効果・スライド効果

実装のポイント

  1. アクセシビリティを重視: エラー状態を明確に表示
  2. パフォーマンスを考慮: 軽量なアニメーション
  3. ブラウザ対応: 幅広いブラウザで動作するように
  4. ユーザビリティ: 直感的な操作を可能に
ケケンタ

バリデーションアニメーションは、ユーザビリティとアクセシビリティを向上させる重要な要素です。この記事のコードを参考に、プロジェクトに最適なアニメーションを実装してください!

あわせて読みたい

もっと効率的にWeb制作を学びたい方へ

Web制作の学習は楽しいものですが、一人で進めていると「これで合っているのかな?」と不安になることもありますよね。

僕も独学でWeb制作を学んできましたが、今思うと「もっと早く知りたかった」と思うことがたくさんあります。

特に以下のような方は、一度プログラミングスクールの利用を検討してみることをおすすめします。

  • 学習の方向性に迷いがある方
  • 効率的にスキルを身につけたい方
  • 転職や副業でWeb制作を活用したい方
  • 挫折経験がある方

忍者CODEなら、業界最安値で24時間サポート付きの学習環境が整っています。

ご興味のある方は、こちらの記事で詳しくご紹介しています。

関連記事

アニメーション基礎知識

スクロールアニメーション

メニュー・ナビゲーション


どれを読むか迷ったときのおすすめ‼/

タブ


どれを読むか迷ったときのおすすめ‼/

フォーム・UI要素

ボタンホバーアニメーション


どれを読むか迷ったときのおすすめ‼/

スライダー

特殊効果

【コピペOK】バリデーションアニメーション|6種類【Web制作】のアイキャッチ画像

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

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

コメント

コメントする

CAPTCHA


目次