Floating Label Input
A free form input whose label floats on focus or value.
- Automated axe check
- Reduced-motion tested
- SSR build verified
- CSS and React
- No runtime packages
Floating Label Input is a free form input component for Next.js, React and Tailwind that renders a real label which glides from the placeholder position to a docked caption when the field is focused or holds a value. It delivers the floating label react pattern with pure CSS, so there is no JavaScript state and no animated colours.
The label is a genuine label element bound by htmlFor and never substitutes a placeholder for accessible naming. Only a transform animates, a permanently reserved error row keeps layout shift at zero, the polite live region announces validation messages, and reduced-motion users receive the same final states instantly.
Sign-up form
Focus a field or type a value and the label glides up to a docked caption. The bottom field keeps a reserved error line, so toggling the message never shifts the layout.
We never share your email.
Install
Add the @te registry to your components.json once:
{
"registries": {
"@te": "https://templateempire.io/r/{name}.json"
}
}Then install the component:
npx shadcn@latest add @te/input-floating-labelUsage
import { FloatingLabelInput } from "@/components/ui/input-floating-label";
export default function Page() {
return (
<FloatingLabelInput
id="email"
label="Email address"
type="email"
/>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | required | Floating caption text rendered as a real label bound to the input. |
| id | string | required | Input id the label targets via htmlFor; must be unique on the page. |
| type | "text" | "email" | "password" | "search" | "tel" | "url" | "number" | "text" | Placeholder-capable textual input type that supports the placeholder-shown float. |
| error | string | undefined | Error message shown in the reserved live region and announced politely; sets aria-invalid. |
| className | string | undefined | Additional classes merged onto the wrapper element. |
| ...rest | InputHTMLAttributes | undefined | Remaining input attributes are spread onto the field; a consumer aria-describedby is preserved and merged with the error id. |
Customisation
Floating Label Input exposes one Tier 3 CSS custom property. Set --input-floating-error to the colour used for the error border, error label and error text. The default var(--destructive, var(--foreground)) stays vanilla-safe by falling back to the foreground colour when a theme has no destructive token.
.contact-form {
--input-floating-error: var(--destructive, var(--foreground));
}Frequently asked questions
- Is Floating Label Input free for commercial use?
- Yes. Floating Label Input is MIT licensed, so you can use it in personal and commercial projects without attribution.
- Is Floating Label Input accessible and performant?
- Yes. It renders a real label bound to the input, keeps a persistent polite live region for validation, marks the field aria-invalid on error, and merges any consumer aria-describedby with the error id. Only a transform animates, the reserved error row holds layout shift at zero, and reduced motion snaps every element to its final state.
- How do I change the error colour?
- Override --input-floating-error with a semantic colour token on :root or any ancestor. It drives the error border, the error label colour and the error message text together.
Related components
More free forms and inputs are on the way. Browse the full component library in the meantime.