shadcn.io is not affiliated with official shadcn/ui
Floating Labels Sign In Login Block for React
A member sign-in page whose labels sit inside the fields and rise on focus, with text or when the browser fills them in, all in CSS, in one bordered group of two cells split by a hairline.
Installation
Overview
Save the room a label takes above a field, with this floating labels login block for React with Base UI. It's the sign-in of Sablebrook Credit Union: the page's two side rails run its full height and one band crosses the screen between two rules with a plus mark where each meets a rail, holding an icon tile, a heading, one sentence and one bordered group of two cells, an email Input and a Password Input, split by a single hairline like the grouped lists on a phone. Each label sits inside its cell as the field's placeholder would and rises to the top of the cell, smaller, when the field has focus, has text or has been filled in by the browser; it is a real Field label, and the movement is CSS alone, with no state in the script and no motion with reduced motion. Under the group are a "Keep me signed in" Checkbox, a "Forgot?" link and the Shine Button, the only colored control, then "Not a member yet?" Pressing Sign in with something missing rings the cell and writes the first problem under the group, so nothing moves. It's built from Field, Input, Password Input, Checkbox, Button, Shine Button and Guides, with a CSS entrance only. For banking, member and account sign-ins that want a compact, quiet form.
FAQ
What happens when I sign in, and what stays in the page?
Nothing leaves the page. Sign in waits under a spinner for less than a second, then shows "You're signed in" with the address you typed, and a polite status message says nothing was sent (and whether you asked to stay signed in); Sign out brings the form back with your email still filled in. Keep me signed in only changes that message here. To wire it for real, post the email, the password and the choice to your auth endpoint where the code says so, and let your session lifetime follow the choice.
How does the label float with CSS only?
Each field's placeholder is a single space, so the browser's :placeholder-shown state is true exactly when the field is empty. The cell asks whether it holds an empty field that is neither focused nor autofilled; only then is the label lowered to the middle at full size, and in every other state it rests in its raised place. The label comes after the field in the markup and is tied to it with for, so a screen reader reads it as the field's name, and a field never shows the space as a placeholder.
What happens when the browser fills the fields in?
The label stays raised, so it never sits on top of the filled text: the cell checks the :autofill state as well as the empty one, and the field gets the page's own background in place of the browser's tint. Password managers find the fields as usual: the email is type="email" with autocomplete="username" and the password autocomplete="current-password".
Is the small label readable?
The raised label is 12 pixels in the muted text color and turns to the full text color while its field has focus; both pass AA contrast on the page background in light and dark. It's never smaller than that, which is why the label changes its font size rather than being scaled down.
How are problems shown, and why is the button never disabled?
A disabled button can't explain itself. Here pressing Sign in with an empty or malformed email, or no password, rings the cell at fault, writes one sentence under the group for the first problem, tied to its field, and moves focus there; fixing it shows the next one. The line under the group always holds its height, so nothing shifts, and the page is checked with noValidate so the messages look the same in every browser.
Is it usable with a keyboard and a screen reader?
Tab runs through the email, the password, its show and hide toggle, Keep me signed in, Forgot and Sign in; Enter in either field signs in. Focus rings the whole cell. The checkbox is a real labelled control, the heading names the form, and after signing in focus moves to the result's heading while a polite status message says what happened.
Related
- Pro
Centered Sign In Login
Centered formA full-height sign-in page for a team chat app: the product's mark, Google and GitHub rows with lettermark tiles, an or rule, email and password checked on submit, and one Sign in button with a simulated wait and its result.
- Pro
Minimal Sign In Login
Centered formA bare sign-in page for a plain-text notes app: a heading, one sentence, an email and a password written on a hairline and one Sign in button, set at the start of the page with no card, providers or footer.
- Pro
Progress Line Sign In Login
Centered formA sign-in page where the band's top rule is the progress line: pressing Sign in locks the fields and a line fills across the rule in 800 ms, then a line in the foot's place says what happened and offers Try again.
- Pro
Full Viewport Sign In Login
Centered formA sign-in page that is the whole screen: a top row with the product's mark and a create-account link, the form centered between rows, a footer row of links and a faint dot grid, with a Caps Lock note under the password.
- Pro
Staggered Reveal Sign In Login
Split with a panelA sign-in page that opens one row at a time: a large heading at the start, the form behind a divider at the end, a valid email opens the password row, eight characters open Keep me signed in, and the button names the next step.
- Pro
Alert Banner Login
Centered formA full-height sign-in page for a database host with a maintenance notice pinned above the form: a quiet alert with the window in UTC, a Details popover and a Dismiss that never moves the form.