🚀

CSS Tips - :placeholder-shown 擬似クラスを使ってMaterial Designっぽい input を作ってみた

2021/01/10に公開

今回は :placeholder-shown という擬似クラスの使い方の紹介をしたいと思います.
動くサンプルも作ってみたので良かったら参考にしてください.

:placeholder-shown とは?

:placeholder-shown とは, CSS の擬似クラスのひとつで, 指定することで placeholder が表示されているときのみ有効になるスタイルを定義することができます.

input:not(:placeholder-shown) { ... } とすれば placeholder が表示されていないとき, つまり値が入力されているときのみ効くスタイルを定義することもできます.

上手く使いこなせば今まで JavaScript で実装していたことを CSS 完結で実装することができます.

サンプルプログラム

サンプルです.

https://runstant.com/phi/projects/10bd7a40

Material Design によくある input を作ってみました.
フォーカスするとラベルが小さくなりながら左上に寄るのがわかるかと思います.

ソースコードと解説

サンプルの html の内容は以下のようになっています.

index.html
    <label class='input'>
      <input type='text' placeholder="&nbsp;" />
      <span class='label'>nickname</span>
      <div class='border'></div>
    </label>

CSS は, 今回 LESS で書いてみました.

main.less
.input {
  font-size: 16px;
  position: relative;
  .label {
    position: absolute;
    left: 0;
    transform-origin: 0 0;
    transition: 256ms;
  }
  input {
    border: none;
    outline: none;
    background: none;
    border-bottom: 2px solid gray;
    padding-bottom: 8px;
    
    // フォーカスしたら移動アニメーション & 下線の色を変更
    &:focus {
      + span {
        color: blue;
        transform: translateY(-26px) scale(.75)
      }
      border-bottom: 2px solid blue;
    }
    // 入力済みだったら移動後の表示のままにする
    &:not(:placeholder-shown) {
      + span {
        transform: translateY(-26px) scale(.75)
      }
    }
  }
}

流れとしてはまず, html 側で placeholder に空文字を設定し, placeholder の代わりに label を input に重ねて表示しています.
そしてフォーカスしたタイミングで, そのラベルを左上基準でスケールダウンアニメーションさせることで Material Desgin のような UI を実現しています.

さいごに

JavaScript 同様 CSS も日々進化しています.
今まではコードで書いていた複雑な処理も CSS の機能を活用することでかなり楽に実現できるようになってきました!

grid に関連する CSS や, backdrop-filter なんかもそうですね.

サービスを運用するという観点だと, 見た目に関連する動きは極力 CSS で完結させたほうが良いと思っています.
コードで実装するとどうしてもバグが入ってしまったり, 関係ないところに影響したりといったリスクも増えてきてしまうからです.

今後も, コードで実現してたけど今なら CSS でサクッとできちゃうよーみたいな Tips も紹介していけたらと思います.

Discussion