폼·입력

[Floating Label] 입력하면 안내 문구가 위로 떠오르는 폼 필드

빈 칸엔 안내 문구가 가운데 있다가, 입력을 시작하면 위로 작게 올라가 자리를 비켜주는 폼 입력. JS 없이 CSS만으로 동작합니다.

ReactTypeScriptTailwind peerCSS :placeholder-shown
라이브 데모
새 탭에서 열기
데모 불러오는 중…

제작 과정

한 줄 요약 빈 칸일 땐 안내 문구가 입력란 안에 있다가, 글자를 넣으면 위로 작게 떠올라 자리를 비켜주는 입력 필드예요.

이럴 때 필요해요

입력란마다 위에 라벨을 따로 두면 폼이 길어지고, 그렇다고 placeholder만 쓰면 입력을 시작한 순간 "이 칸이 뭐였더라" 하고 안내가 사라져버려요. 떠오르는 라벨은 둘의 장점을 합칩니다 빈 칸엔 안내가 크게 보이고, 입력하면 위로 올라가 작게 남아 계속 무슨 칸인지 알려줘요. 회원가입문의결제 폼처럼 공간은 아끼되 안내는 유지하고 싶을 때 좋아요.

어떻게 동작하나

  1. 입력란의 placeholder공백 한 칸(" ")으로 둬요. 그러면 "비어 있다"는 상태를 CSS의 :placeholder-shown으로 감지할 수 있어요.

  2. 라벨은 입력란의 형제(peer)로 두고, 입력란 상태에 따라 위치를 바꿔요 비었고 포커스도 없으면 가운데, 포커스되거나 값이 있으면 위로 작게.

  3. 이 전환은 자바스크립트가 전혀 필요 없어요. peer-focuspeer-[:not(:placeholder-shown)] 규칙이 라벨을 위로 올리는데, 이 규칙들이 기본(가운데) 스타일보다 우선순위가 높아 자동으로 이겨요.

  4. 이메일 칸만 자바스크립트로 형식을 확인해서, 올바르면 초록 체크, 틀리면 빨간 안내를 보여줘요.

핵심은 이거예요

라벨을 올렸다 내렸다 하는 데 상태 관리(useState)가 필요 없어요 "빈 칸이냐"를 CSS가 :placeholder-shown으로 알아서 판단하고, 그에 맞춰 라벨 위치를 바꿉니다. 우리는 위/아래 두 스타일만 정의하면 끝.

놓치기 쉬운 것

  • placeholder를 빈 문자열이 아니라 공백 한 칸으로 둬야 :placeholder-shown이 의도대로 동작해요. (진짜 placeholder 글자는 placeholder:text-transparent로 숨김)

  • 포커스됐는데 아직 빈 칸일 때도 라벨이 올라가야 해요 떠오른 스타일을 peer-focus에도 걸어줘요.

  • textarea는 키가 커서 "가운데" 기준이 어색해요 라벨 기본 위치를 상단 쪽으로 따로 잡았어요.

  • 라벨엔 htmlFor를 꼭 연결해 접근성(클릭스크린리더)을 지켜요.

이런 곳에 써요

  • 회원가입로그인문의 폼의 입력 필드

  • 결제주소 입력처럼 칸이 많아 공간을 아껴야 하는 폼

  • Material Design 스타일의 입력 UI

소스 코드

· 데모 페이지에서 자동 추출
import type { Metadata } from "next";
import { FloatingLabelDemo } from "./-components/FloatingLabelDemo";

export const metadata: Metadata = {
  title: "Floating Label Input (데모)",
  description:
    "입력하면 라벨이 위로 떠오르는 폼 필드. JS 없이 CSS peer + :placeholder-shown 트릭으로 동작.",
  robots: { index: false, follow: false },
};

export default function Page() {
  return (
    <main className="flex min-h-[100dvh] items-center justify-center bg-gradient-to-br from-violet-50 via-white to-fuchsia-50/60">
      <FloatingLabelDemo />
    </main>
  );
}
13조회수

댓글