Build faster with Premium Chakra UI Components 💎
Learn moreOctober 19, 2024
Floating labels conserve space in forms, particularly on mobile devices where screen space is limited.
To add a floating label to an input component in Chakra UI, create a styled
input field using the Field, Input, and Box components with React state
management for reliable cross-device compatibility.
"use client"
import type { InputProps } from "@chakra-ui/react"
import {
  Box,
  Field,
  Input,
  defineStyle,
  useControllableState,
} from "@chakra-ui/react"
import { useState } from "react"
const Demo = () => {
  return (
    <Field.Root>
      <FloatingLabelInput label="Email" />
      <Field.ErrorText>This field is required</Field.ErrorText>
    </Field.Root>
  )
}
interface FloatingLabelInputProps extends InputProps {
  label: React.ReactNode
  value?: string | undefined
  defaultValue?: string | undefined
  onValueChange?: ((value: string) => void) | undefined
}
const FloatingLabelInput = (props: FloatingLabelInputProps) => {
  const { label, onValueChange, value, defaultValue = "", ...rest } = props
  const [inputState, setInputState] = useControllableState({
    defaultValue,
    onChange: onValueChange,
    value,
  })
  const [focused, setFocused] = useState(false)
  const shouldFloat = inputState.length > 0 || focused
  return (
    <Box pos="relative" w="full">
      <Input
        {...rest}
        onFocus={(e) => {
          props.onFocus?.(e)
          setFocused(true)
        }}
        onBlur={(e) => {
          props.onBlur?.(e)
          setFocused(false)
        }}
        onChange={(e) => {
          props.onChange?.(e)
          setInputState(e.target.value)
        }}
        value={inputState}
        data-float={shouldFloat || undefined}
      />
      <Field.Label css={floatingStyles} data-float={shouldFloat || undefined}>
        {label}
      </Field.Label>
    </Box>
  )
}
const floatingStyles = defineStyle({
  pos: "absolute",
  bg: "bg",
  px: "0.5",
  top: "2.5",
  insetStart: "3",
  fontWeight: "normal",
  pointerEvents: "none",
  transition: "position",
  color: "fg.muted",
  "&[data-float]": {
    top: "-3",
    insetStart: "2",
    color: "fg",
  },
})
For more details on Chakra UI's input component, refer to the documentation.
This implementation uses:
data-float attribute: Applied conditionally for CSS-based styling&[data-float] for hardware-accelerated style
changesThe state approach ensures the label floats correctly on all devices, including mobile browsers where CSS-only solutions may fail due to autofill behavior.