
CSSの機能が盛りだくさんになってきました。
EFOの判定もJavascriptを使わなくてもほぼできるようになってきて、
HTML+CSSで、標準的な入力フォームのバリデートチェックが可能になっています。
コツを覚えると、非常に簡易にフロントコーダーレベルでも堅牢なお問い合わせフォームなどが作れるようになります。
最近仕事で作ったバリデートお問い合わせフォームを紹介したいと思います。
できるだけ、コピペで使えるようにコードを書いておいたので、どんどん使ってみてください。
ちなみに、自分用備忘録も兼ねています。
お問い合わせフォームのデモ
ソースコード
HTML
<form name="demo">
  <ul class="inputs">
    <li>
      <div class="group">
        <p class="name">お問い合わせの種類</p>
        <select name="genre" required>
          <option value="">* 選択してください。</option>
          <option value="1">サイトに関する質問</option>
          <option value="2">サービスに関する質問</option>
          <option value="3">その他</option>
        </select>
      </div>
    </li>
    <li>
      <div class="group">
        <p class="name">名前</p>
        <input type="text" name="name" required/>
      </div>
    </li>
    <li>
      <div class="group">
        <p class="name">メールアドレス</p>
        <input type="email" name="mail" required/>
      </div>
    </li>
    <li class="rows">
      <div class="group">
        <p class="name">内容</p>
        <textarea name="comment" required></textarea>
      </div>
    </li>
  </ul>
  <div class="button">
    <button class="button-link" type="button" name="save">送信する</button>
  </div>
</form>
CSS
#single-content p{
  margin:0!important;
}
form[name="demo"]{
  --color-1 : red;
  --color-2 : blue;
  --size-border-radius: 5px;
  --size-height : 40px;
  
  display:block;
  width:700px;
  max-width:100%;
  padding:0 20px;
  margin:0 auto;
}
form[name="demo"],
form[name="demo"] *{
  white-space:normal!important;
}
form[name="demo"] ul,
form[name="demo"] li{
  margin:0!important;
  padding:0!important;
  list-style:none;
}
form[name="demo"]:invalid .button button[name="save"]{
  background-color:var(--color-1);
  pointer-events:none;
}
form[name="demo"] button.sended[name="save"]{
  background-color:#AAA;
  pointer-events:none;
}
form[name="demo"] .inputs{
  display:flex;
  flex-direction:column;
  gap:10px;
}
form[name="demo"] li.spacer{
  height:10px;
}
form[name="demo"] .group{
  display:flex;
  gap:0;
  width:100%;
}
form[name="demo"] .group > p{
  margin:0;
  background-color:var(--color-2);
  color:white;
  font-size:0.9em;
  display:flex;
  align-items:center;
  justify-content:center;
  white-space:nowrap;
  width:150px;
  min-width:150px;
  height:var(--size-height);
}
form[name="demo"] .group > input,
form[name="demo"] .group > textarea,
form[name="demo"] .group > select,
form[name="demo"] .group > label{
  border-style:solid;
  border-color:var(--color-2);
  border-width:1px 1px 1px 0;
  padding:10px;
  flex:1;
  outline:none;
  width:100%;
  height:var(--size-height);
  background-color:white;
}
form[name="demo"] .group > textarea{
  width:100%;
  height:200px;
  border-left-width:1px;
  border-bottom-left-radius:10px!important;
}
/**
 * Required対応
 */
form[name="demo"] .rows .group.checkbox-required:not(:has(input[type="checkbox"]:checked)) > p,
form[name="demo"] .group:has(input:invalid,select:invalid,textarea:invalid) p{
  background-color:var(--color-1);
}
form[name="demo"] .rows .group.checkbox-required:not(:has(input[type="checkbox"]:checked)) > .flex-column,
form[name="demo"] .group:has(input:invalid,select:invalid,textarea:invalid) input,
form[name="demo"] .group:has(input:invalid,select:invalid,textarea:invalid) select,
form[name="demo"] .group:has(input:invalid,select:invalid,textarea:invalid) textarea{
  border-color:var(--color-1);
}
form[name="demo"] .group *:first-child{
  border-radius:var(--size-border-radius) 0 0 var(--size-border-radius);
}
form[name="demo"] .group *:last-child{
  border-radius:0 var(--size-border-radius) var(--size-border-radius) 0;
}
form[name="demo"] .group .flex-column{
  min-height:50px;
}
form[name="demo"] .group-flex2{
  display:flex;
  gap:10px;
}
form[name="demo"] .group-flex2 > *{
  width:calc(50% - 5px);
}
/**
 * Checkbox (label)
 */
form[name="demo"] label.check{
  --size : 20px;
  display:flex;
  gap:10px;
  align-items:center;
  justify-content:start;
  padding:5px 10px;
  cursor:pointer;
  position:relative;
}
form[name="demo"] label.check:hover{
  color:var(--color-1);
}
form[name="demo"] label.check::before{
  content:"";
  display:inline-block;
  border:1px solid black;
  width:var(--size);
  min-width:var(--size);
  height:var(--size);
  min-height:var(--size);
}
form[name="demo"] label.check:hover::before{
  border-color:var(--color-1)
}
form[name="demo"] label.check:has(input[type="checkbox"]:checked)::after{
  content:"";
  display:block;
  position:absolute;
  width:var(--size);
  min-width:var(--size);
  height:var(--size);
  min-height:var(--size);
  background-color:black;
  clip-path:polygon(10% 30%, 50% 60%, 100% 0, 50% 80%, 10% 30%);
}
form[name="demo"] label.check input{
  display:none;
}
/**
 * 送信ボタン
 */
form[name="demo"]:invalid .button{
  display:none;
}
form[name="demo"] .button{
  height:80px;
  display:flex;
  align-items:center;
  justify-content:center;
}
form[name="demo"] .button button{
  background-color:var(--color-2);
  color:white;
  padding:10px;
  width:200px;
  text-align:center;
  border:0;
  border-radius:var(--size-border-radius);
  cursor:pointer;
}
form[name="demo"] .button button:hover{
  background-color:var(--color-1);
}
@media(max-width:768px){
  form[name="demo"] .group-flex2{
    flex-direction:column;
  }
  form[name="demo"] .group-flex2 .group{
    width:100%;
  }
  form[name="demo"] .rows .flex-column{
    display:flex;
  }
  form[name="demo"] .group > p{
    font-size:0.8em;
  }
}
@media(max-width:500px){
  form[name="demo"] .group{
    flex-direction:column;
  }
  form[name="demo"] .inputs{
    gap:20px;
  }
  form[name="demo"] .group *:first-child{
    border-radius:var(--size-border-radius) var(--size-border-radius) 0 0;
    border-width: 1px 1px 0 1px;
  }
  form[name="demo"] .group *:last-child{
    border-radius:0 0 var(--size-border-radius) var(--size-border-radius);
    border-width: 1px;
  }
  form[name="demo"] .rows .group{
    height:220px;
  }
}
解説
cssの"要素:invalid"セレクタを使うと、form内でのバリデーションチェック判定をCSSで分岐させる事ができます。
今回は、入力必須項目やメールアドレスなどのバリデート、フォーム内の全ての項目で、入力ミス(漏れ)がなくなれば、送信ボタンを表示する機能を設けています。
他にも、ラジオボタンや、チェックボックスなどの判定もできるので、規定チェックがされていない場合も、invalid判定でうまく機能します。
少し難易度が上がるのは、複数のチェックボックスで、○個以上の項目チェックが必須の場合は、javascriptを使って個数算出をするか、かなり深いCSSを記述するか(今回は説明しません)ですね。
デザインは他にも色々と使えると思うので、今回のソースはあくまでサンプルとして流用してください。
あとがき
結構、わかりやすい入力フォームが作れるでしょ?
ホームページではこの
おもてなしができる事が、CV(成果)率のアップに深く繋がります。
逆にここで手を抜くと、機会損失という事ですね。
それにしても、JS使わずにここまでできてしまうなんて、いい時代になったな〜。
 
0 件のコメント:
コメントを投稿