CSSの疑似クラス「:has()」がモダンブラウザで使えるようになり、今までJavaScriptを使わないと実装できなかったようなものでも、CSSだけで実現できる幅が広がりました。

そんなCSSの「:has()」を使って、お問い合わせページなどでよく見かける、利用規約など個人情報の同意チェックボックスのチェックの有無で送信ボタンの活性(押せる状態)と非活性(押せない状態)を切り替える動作を、JavaScriptを使わずに実装する実験をしてみたので紹介してみます。

:has()を使ってCSSだけで同意チェックボタンを実装

まずは、JavaScriptを使わずにCSSの疑似要素「:has()」を使って、同意チェックボックスのチェック有無によって、ボタンの活性/非活性を切り替える動作サンプルです。

See the Pen
CSS only Agree Check
by BLACKFLAG (@BlackFlag)
on CodePen.

チェックボックスにチェックが入ると「送信する」ボタンが活性化になり、チェックが入っていない状態は非活性になります。

この動作について、まずHTMLからですが、formタグと同意する際のチェックボックスに加えて、送信ボタンはinputの[type=button]で設置します。
※本来は同意チェック後は確認画面に遷移する「確認する」ボタンになると思いますが、サンプルでは分かりやすく「送信する」にしています。

<form>
  <p><label><input type="checkbox"> 同意する</label></p>
  <input type="button" value="送信する" onClick="submit();">
</form>

このHTMLに対して、デフォルトではinputボタンを非活性(押せない状態)にして、チェックボックスにチェックが入った場合のみ活性化(押せる状態)になるように、CSSを指定します。

form {
  margin: 50px;
  text-align: center;

  input[type=button] {
    background: #ddd;
    border: #aaa solid 1px;
    border-radius: 10px;
    color: #aaa;
    padding: 10px 80px;
    pointer-events: none;
    transition: background-color .3s, color .5s;
    
    &:focus {
      visibility: hidden;
    }
  }
  
  &:has(input:checked) input[type=button] {
    background: #fff;
    border: #000 solid 1px;
    color: #333;
    cursor: pointer;
    pointer-events: auto;

    &:focus {
      visibility: visible;
    }
  }
  
  @media (hover: hover) {
    &:has(input:checked) input[type=button]:hover {
      background: #000;
      color: #fff;
    }
  }
}

チェックボックスのチェックの有無に関しては、formタグに対して疑似要素:has()を使い、「form:has(input:checked) input[type=button] { ~ }」で、form内にチェックの入ったinput要素がある場合を判別して、「input[type=button]」ボタン要素に対して、見た目ふくめた指定を切り替えています。

CSSではinput系のクリック動作等を無効にするdisabled属性の操作はできないので、クリックおよびタップ動作を無効化に関しては「pointer-events: none;」で指定をしています。

「pointer-events: none;」のみだと、キーボード操作等でボタンにフォーカスした状態だと押下することができてしまうので、非活性時にフォーカスした際には「visibility: hidden;」でフォーカス状態を外すようになっています。

疑似クラス「:has()」の対象ブラウザについては以下です。

「pointer-events」プロパティの対象ブラウザについては以下で、基本的なモダンブラウザで使用可能です。

CSSでdisabled属性の切り替えができないことで、少々強引な方法での実装になっているので、Firefoxだと非活性ボタンの状態でフォーカスが先を辿れなくなるといった、アクセシビリティの観点で課題が少しあるので、あくまで実験サンプルになります。

同意チェックボタン動作など、疑似クラス「:has()」を使うとJavaScript不要で様々な動作を実現することができるようになり可能性が広がりそうです。
※必要な場面では無理せずJavaScriptを使用しましょう。

「:has()」を使ってCSSだけで同意チェックボタンを実装する際のご参考までに。。。