1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Reactを使った入力時にラベルをフロートで移動させる方法

Posted at

この記事はプログラミング学習者がアプリ開発中に躓いた内容を備忘録として記事におこしたものです。内容に不備などあればご指摘頂けると助かります。

今回はRails(API) x ReactでX(旧Twitter)のクローンサイトを作る際に本家のデザインの一部を模倣したので、備忘録を兼ねて記事に起こしたいと思います。

1. 記事の趣旨について

本家(X - 旧Twitter)を模倣する際、inputタグにフォーカスすることで起こるラベルのフロートを実装しました。
通常、inputタグに備わっているplaceholderで名前をつけておくとフォーカスされていない時はinputタグの対象が別できますが、フォーカスしてしまうとplaceholderは消えてしまうので、何のinputタグかを判別することができません。
ラベルをフロート(移動)させることで、入力内容とラベルが重なることを避けつつ、入力しているinputタグは何のラベルが付いているかを確認することができるようになりました。
ここではinputタグのplaceholderは使わずに他の要素で代用することで機能を実現しています。

下のGif画像はフロート化したラベルがついたinputタグにフォーカスした時の動画です。

インプットタグ ラベルフロート移動.gif

2. 実装したコード

FloatingInput.jsx
import React, { useState, useEffect } from "react";
import styled, { css } from "styled-components";

const InputBox = styled.div`
  position: relative; // InputとPlaceholderに対する親要素として指定
  font-size: 14px;
  padding-top: 20px;
  width: 75%;
`;

const Input = styled.input`
  width: 100%;
  height: 60px;
  margin-bottom: 10px;
  border-radius: 5px;
  background-color: black;
  color: white;
  border: solid 1px #3b3b3b;
  outline: none;
  padding-left: 12px;
  padding-top: 15px;
  padding-bottom: 0;
  font-size: 16px;
  &:focus {
    border: solid 2px #1d9bf0;
  }
`;

const PlaceHolder = styled.span`
  position: absolute; // 親要素のInputBoxに対して子要素として指定
  left: 10px;
  top: 70%;
  transform: translateY(-50%); // 上方向に移動させる
  color: #aaa;
  pointer-events: none; // カーソルフォーカス時にポインターに変わらないように
  background: black;
  font-size: 20px;
  transition: top 0.3s, font-size 0.3s, color 0.3s; // 要素の変わる速度
  ${({ $isActive }) =>
    $isActive &&
    css`
      top: 40px;
      font-size: 12px;
      color: #1d9bf0;
    `}
`;

export const FloatingInput = ({ label, value, onChange, type, name }) => {
  const [isFocused, setIsFocused] = useState(false);

  return (
    <InputBox>
      <Input
        type={type}
        value={value}
        name={name}
        onChange={onChange}
        onFocus={() => setIsFocused(true)}
        onBlur={() => setIsFocused(false)}
      />
      <PlaceHolder $isActive={isFocused || value}>{label}</PlaceHolder>
    </InputBox>
  );
};

機能実装する際に肝となるのは親要素のInputBoxコンポーネントと子要素であるPlaceholderコンポーネントです。
InputBoxにposition: relativeを置いて、親要素としての機能を追加します。
子要素のPlaceholderにposition: absoluteを置いて親要素の位置から子要素をどれくらい動かすかという移動機能を追加できます。
通常時は下記の位置設定になっており、親要素InpuBoxから移動した位置を記述しています。

left: 10px;
top: 70%;
transform: translateY(-50%);

そして、変数&isActiveがtrueになった場合、下記の状態に変更します。
top: 40px;の部分で移動させるように実装しています。

top: 40px;
font-size: 12px;
color: #1d9bf0;

3. 参考にしたサイト

コピペで簡単! CSSのみで、フォームの入力時にフロートする入力欄のラベルを実装するテクニック
placeholderを消さずにCSSで見出しに活用する方法

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?