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.