---
title: Floating Input
description: "Astro text fields with a label that moves when focused or filled."
seo:
    title: "Floating Input for Astro — examples and usage"
---

```astro
---
import { FloatingInput } from "@/components/ui/floating-input"
---

<div class="flex w-full max-w-sm flex-col gap-6 py-2">
  <FloatingInput id="floating-email" name="email" type="email" label="Email" />
  <FloatingInput
    id="floating-name"
    name="name"
    type="text"
    label="Name"
    value="Ada Lovelace"
  />
</div>
```

## Installation

```bash
bunx --bun shadcn@latest add @gnosticai/floating-input
```

The command also installs [Input](/components/input), [Textarea](/components/textarea),
and [Label](/components/label).

## Usage

```ts
import { FloatingInput } from "@/components/ui/floating-input"
```

```astro
<FloatingInput id="email" name="email" type="email" label="Email" />
```

Set `id`. The label uses that id. Omit `placeholder` when the label is the
only hint. The component then uses a space, and that placeholder stays invisible.

## Size

`md` is the default. `size="sm"` makes the field shorter.

```astro
---
import { FloatingInput } from "@/components/ui/floating-input"
---

<div class="w-full max-w-sm py-2">
  <FloatingInput
    id="floating-phone"
    name="phone"
    type="tel"
    label="Phone"
    size="sm"
  />
</div>
```

## Description and error

`description` adds helper text. `error` adds a validation message and marks
the control invalid.

```astro
---
import { FloatingInput } from "@/components/ui/floating-input"
---

<div class="w-full max-w-sm py-2">
  <FloatingInput
    id="floating-username"
    name="username"
    type="text"
    label="Username"
    description="This name is public."
    error="Enter a username."
  />
</div>
```

## Textarea

`FloatingTextarea` uses the same label. The empty label sits on the first line.

```astro
---
import { FloatingTextarea } from "@/components/ui/floating-input"
---

<div class="w-full max-w-sm py-2">
  <FloatingTextarea
    id="floating-message"
    name="message"
    label="Message"
    rows={4}
  />
</div>
```

## Input and label classes

Use the slot classes when you build the field from `Input` and `Label`.
Place the label after the input. Keep helper text outside that wrapper.
The empty label uses half the height of the wrapper.

```astro
---
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import {
  floatingInputRootClass,
  floatingInputVariants,
  floatingLabelVariants,
} from "@/components/ui/floating-input"
---

<div class={floatingInputRootClass}>
  <Input id="city" class={floatingInputVariants()} placeholder=" " />
  <Label class={floatingLabelVariants()} for="city">City</Label>
</div>
```

```astro
---
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import {
  floatingInputRootClass,
  floatingInputVariants,
  floatingLabelVariants,
} from "@/components/ui/floating-input"
---

<div class="w-full max-w-sm py-2">
  <div class={floatingInputRootClass}>
    <Input
      id="floating-city"
      name="city"
      class={floatingInputVariants()}
      placeholder=" "
    />
    <Label class={floatingLabelVariants()} for="floating-city">
      City
    </Label>
  </div>
</div>
```

## Notes

- `class` styles the wrapper. Use it for width.
- `size` sets the field height. It accepts `sm` and `md`.
- The label follows the control so the empty, focus, and filled states work.
- Pass `error` to show a message and set `aria-invalid`.
- Pass `description` for helper text. The control references that text.

## API Reference

Read the [installed source](/r/floating-input.json) for the complete prop types.

## When to use Floating Input

Provide both `id` and `label`. FloatingInput composes an Input and a linked label, with optional description and error text. The placeholder supports the floating-label layout; it is not the accessible name.

## Keyboard and behavior

The native input keeps normal keyboard and form behavior. Keep the visible label clear even after typing. Error text should explain the correction and remain associated with the field.

## Theme and layout

Test browser autofill, long labels, and zoom with the selected size. The floating label sits over the field surface, so custom backgrounds must match the surrounding input design.

## Related choices

Use [Input](/components/input) and [Field](/components/field) when a fixed label above the control is clearer.
