CSSのみで、フォームの入力時にフロートする入力欄のラベルを実装する

フォームの入力欄のラベルが入力時にふわりとフロートして移動するのをCSSのみで実装するテクニック。
HTMLはinputとlabelで非常にシンプル、余計なspanなどは無い。ラベルのフロートはCSSで実装されており、コピペで簡単に使用できる。
https://coliss.com/articles/build-websites/operation/css/css-only-floating-input-labels.html

See the Pen CSS only floating input labels by Stanko (@stanko) on CodePen.

HTMLは至ってシンプル。

<div class="input-wrapper">
  <input autocomplete="off" class="input" type="text" id="name" placeholder="Name">
  <label class="label" for="name">名前</label>
</div>

入力欄をクリアするボタンは、SVGで実装されている。

<div class="input-wrapper">
  <input autocomplete="off" class="input" type="text" id="name" placeholder="Name">
  <label class="label" for="name">名前</label>
  <button class="clear" aria-label="Clear input">
    <svg viewBox="0 0 16 16" width="12" height="12">
      <path d="M 1 1 L 15 15 M 1 15 L 15 1" fill="none" stroke-width="2" stroke="currentColor" />
    </svg>
  </button>
</div>

CSSで実装する際のポイントは、疑似クラス:placeholder-shownを:not()で使用することで入力欄に値があるかどうかを調べることができる。
(※ :placeholder-shownはIEを除く、すべてのブラウザにサポートされています。)

/* 入力欄に値がない場合*/
input:placeholder-shown

/* 入力欄に値がある場合 */
input:not(:placeholder-shown)

入力時にラベルをフロートして再配置するCSSは下記の通り。

input:focus + label,
input:not(:placeholder-shown) + label {
  transform: translateY(-100%) scale(0.75);
}

クリアを除いた、CSSは下記の通り。

.input-wrapper {
  position: relative;
  margin-top: 30px;
  margin-inline: auto;
  max-width: 400px;
}

.input {
  font-size: 20px;
  width: 100%;
  padding: 8px 0;
  padding-right: 30px;
  color: #333;
  border: none;
  border-bottom: 1px solid #ddd;
  transition: border-color 250ms;
  background-color: transparent;
}
.input:focus {
  outline: none;
  border-bottom-color: #777;
}
.input::placeholder {
  color: transparent;
}
.input::-webkit-contacts-auto-fill-button {
  visibility: hidden;
  pointer-events: none;
  position: absolute;
}

.label {
  position: absolute;
  top: 8px;
  left: 0;
  color: #43454e;
  pointer-events: none;
  transform-origin: left center;
  transition: transform 250ms;
  font-family: sans-serif;
}

.input:focus + .label,
.input:not(:placeholder-shown) + .label {
  transform: translateY(-100%) scale(0.75);
}

.input:placeholder-shown + .label + .clear {
  display: none;
}

Safariでは、inputにplaceholder属性が明示的に定義されている場合にのみ:placeholder-shown疑似クラスが追加される。placeholderが必要ない場合は、CSSで非表示にしておく。

input::placeholder {
  color: transparent;
}
inserted by FC2 system