What is a CSS search box?
Strip away the styling and you have an input field and a button inside a form. CSS controls how it looks, how its states behave, how it lays out and how it responds on small screens.
That’s where the styling layer ends. Submitting the query, matching results and suggesting terms belong to the form action, the server and JavaScript.
Like any user interface component, a search box has a fixed anatomy. The form wraps everything and carries the action and the method. Inside it sit the text field where the query goes and the submit button, which is often just an icon. The magnifying glass on that button gets drawn with SVG, a background image or an icon font. Add the placeholder, the hint text visible while the field is empty, and that’s every part.
Each part is plain HTML until CSS gives it shape, which means the markup decisions in the next section limit every style choice after them.
You’ll usually find the box in the header or a navbar. Some sites put it at the top of the content area, and others hide it behind an icon that opens a fullscreen overlay.
A styled box with nothing behind its form action is only a picture of a search box.
Which HTML markup does a search box need?
Skip any of the pieces (a form with an action, a labeled input with a name, a submit button, a search landmark) and either the query doesn’t submit or assistive technology can’t find the box.
Here’s the full pattern using the native search element:
<search>
<form action="/search" method="get">
<label for="q">Search</label>
<input type="search" id="q" name="q" placeholder="Search articles">
<button type="submit">Search</button>
</form>
</search>
Input type search or text
Browser support isn’t the question here. type="search" has been Baseline Widely Available since January 29, 2018 (web-features data).
Functionally it matches a text field. Browsers are free to give it their own styling, and some add a clear (x) button (MDN).
Use type="search" for a real search query, as long as you’re willing to reset the WebKit defaults. Stick with type="text" when the design has to render identically everywhere with zero reset work, or when a shared component library already styles text inputs and you can’t touch it.
Many popular tutorials use type="text" and skip the reset. The semantic search field is worth the extra CSS, in my view.
Label, button and landmark
Tie a label to the input through for and id. Placeholder text is not a replacement for it (MDN). The input also needs a name attribute, because without one the field value is not submitted (MDN).
For the button, button type="submit" beats input type="submit", since only a button can hold an SVG or a pseudo-element. Speckyboy’s search box tutorial switched from an input to a button for exactly that reason.
The label, name and button rules are the same basics behind any accessible form pattern.
The HTML specification added the search element on March 24, 2023 (Scott O’Hara). Safari 17, Firefox 118, Chrome 118 and Edge 118 all shipped it between September 18 and October 13, 2023.
The web-features data lists it as Baseline 2023, and it reached Baseline Widely Available status on April 13, 2026.
The element wraps the form instead of replacing it, and it never holds the results themselves. When search runs entirely in JavaScript, the form and submit button are optional (MDN).
For browsers without support, put role="search" on the form, which exposes the same landmark through the ARIA search role.
Core styles for the input and the button
The base look comes down to border, border-radius, padding, font-size, background and box-shadow. Everything else is polish.
- A 1px solid
border in a mid-dark grey. border-radius at 999px gives a pill, and 4px to 8px gives a soft rectangle.- Vertical
padding sets the height. The icon side needs extra. - Set
font-size to 1rem after font: inherit, because form controls do not pass on page fonts by default. - Always set
background and color together, never one alone. - Keep
box-shadow soft and outer for lift. Inset only works for a pressed look.
.search-form input[type="search"] {
padding: 0.65rem 1rem;
font: inherit;
font-size: 1rem;
color: #1a1a1a;
background: #fff;
border: 1px solid #767676;
border-radius: 999px;
box-shadow: 0 1px 2px rgb(0 0 0 / 0.08);
}
Keep colors in CSS custom properties such as --search-border and --search-accent, so a dark theme swaps values instead of rewriting rules.
A box shadow generator shortens the trial and error on shadow values.
Hongkiat’s CSS3 search field tutorial stacks several box-shadows, inset ones included, to fake depth. It looks rich, but every theme change means editing each layer.
How to place a search icon inside the input
The usual approach is an inline SVG inside a submit button. Position that button absolutely over the right edge of a relatively positioned wrapper, then add right padding to the field so typed text stops before the icon.
| Method | Clickable icon | Failure mode | Pick when |
|---|
| Absolute button over the field | Yes | Text runs under the icon without right padding | Default for most sites |
| Flexbox siblings | Yes | Field and button need matching height and radius | Button sits beside the field |
| Background image | No | Icon can overlap typed text after blur | Placeholder-only fields |
| Icon font or SVG in the button | Yes | Font file adds a request, SVG needs a set size | Icon-only designs |
Layout choices
The absolute pattern comes down to position: relative on the wrapper and position: absolute on the button, plus right padding on the field so text doesn’t run under the icon.
MIT’s Sun Lab, Georgia Tech’s GTISC lab and Michigan State’s engineering site serve an identical search-box.css built this way, with inset: 0 0 0 auto, a square aspect-ratio on the button and padding-right: 40px on the field.
Flexbox is the other option. Put the field and button side by side as siblings under display: flex, with matched heights and radii so the join looks clean. CSS Grid is worth it only when the same row also holds a select or a filter.
Icon sources
A background image is fine for a purely decorative icon. The known catch is an icon that reappears over typed text once the field loses focus.
W3Schools’ search button example places a Font Awesome icon inside the button, and the cost is a font download for one glyph.
Inline SVG gets my vote. It needs no extra request and inherits currentColor. It also lives inside the button, which matters because a pseudo-element on an input never renders.
Keeping the SVG directly in the markup also lets CSS recolor the icon on hover and focus.
An icon-only button needs an accessible name, so add visually hidden text or aria-label="Search".
Hover, focus and placeholder states
Hover goes on the button, focus on the field, and :focus-within on the wrapper. Two more selectors handle the placeholder: ::placeholder for the hint text and :placeholder-shown for the empty field.
Hover and focus-within
Put :focus-within on the form wrapper so the border and shadow wrap the field and the button together. It has been available across browsers since January 2020 (MDN) and reached Baseline Widely Available status on July 15, 2022 (web-features data).
Hover styles belong on the button and stay small: a background shift, a slight lift. Bigger hover effects suit a gallery card and look noisy on a search button.
Touch screens have no hover, so no state should depend on it.
Keeping focus visible
W3C’s Understanding document for WCAG 1.4.11 sets a minimum of 3:1 between a field boundary or focus indicator and the colors next to it.
Two of its examples: a #767676 grey border on white passes, while a #FFF000 yellow star rating on white fails at 1.2:1.
Many tutorials, Kirupa’s among them, remove the default outline early with outline: none. That is fine only if a replacement follows, such as a 2px outline or a box-shadow ring in a dark accent, which gives keyboard users the visible indicator WCAG 2.4.7 Focus Visible asks for.
Check the result with a color contrast checker instead of judging by eye.
Placeholder text
Use ::placeholder for the hint text. The field itself, while that hint is showing, gets targeted with :placeholder-shown instead.
Set the color explicitly, because most browsers default to a translucent or light gray placeholder (MDN). Keep it lighter than typed text but still readable, since placeholder text with strong contrast can be mistaken for entered input (MDN).
Pair :not(:placeholder-shown) with a sibling selector to reveal a clear control only after typing.
How to expand a search box on focus
Start the wrapper narrow and widen it on :focus-within, with a transition on width doing the animation. No JavaScript is involved.
- Set the wrapper to a compact width, such as 12rem, with
max-width: 100%. - Keep the icon button absolutely positioned so it stays put while the field grows.
- Add
transition: width 0.3s ease to the wrapper. - Set the wider width, such as 20rem, on
:focus-within. - Turn the transition off for users who ask for reduced motion.
.search-form {
width: 12rem;
max-width: 100%;
transition: width 0.3s ease;
}
.search-form:focus-within {
width: 20rem;
}
@media (prefers-reduced-motion: reduce) {
.search-form {
transition: none;
}
}
MDN lists the reduced-motion query as available across browsers since January 2020, so there is no reason to skip step five.
An expanding field is a textbook micro-interaction: small, instant, tied to one action.
Trigger options
:focus-within is the default pick. It fires from a click, a tap or the keyboard, and it works on the wrapper. Plain :focus only makes sense when the field itself is the element changing size. Hover on the icon is mouse only, so keyboard and touch users never see the expansion.
Treat hover as a bonus for mouse users, never as the only trigger.
Where the expanding box breaks
MDN lists the any-hover media feature as available across browsers since December 2018, so hover-only styles can sit behind a capability check.
Android adds a wrinkle. Some versions emulate hover on a long press, which is why Michelle Barker’s write-up pairs (hover: hover) with (pointer: fine) to detect real hover.
- Animating
width forces layout on every frame, so neighbors in a flex navbar slide around. Reserve the expanded width, or let the field grow over its neighbors with absolute positioning. - Click-to-open and fullscreen overlays toggle state, so they need JavaScript.
Resetting the native search input appearance
Start with appearance: textfield on the field, which hands border and padding control back to you. The clear (x) that WebKit and Blink draw is a separate decision, so deal with it afterward by removing or restyling it.
What WebKit adds by default
WebKit styles a search input before any author CSS runs. That means an inset border and rounded corners, with strict typographic control (CSS-Tricks), and tight limits on which properties author CSS can change (CSS-Tricks). Once the field holds text, a clear (x) shows up too (MDN).
The normalize.css documentation names -webkit-appearance: textfield as the fix that keeps the benefits of search inputs. CSS-Tricks lists both none and textfield, and the choice matters, because MDN notes that some widgets disappear completely under appearance: none.
In practice that means textfield on the input and none only on the decoration pseudo-elements.
input[type="search"] {
-webkit-appearance: textfield;
appearance: textfield;
}
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-results-button,
input[type="search"]::-webkit-search-results-decoration {
-webkit-appearance: none;
appearance: none;
}
Search inputs are a textbook cross-browser compatibility problem: identical markup, different defaults per engine.
The clear button
MDN marks ::-webkit-search-cancel-button as non-standard, supported only in WebKit and Blink, and visible only when the field is not empty.
| Approach | Clear (x) button | Border and padding control |
|---|
| Leave defaults | Shown once text is typed | Restricted |
| appearance: textfield | Still shown | Normal |
| textfield plus hidden cancel button | Hidden, add a custom control | Normal |
Hiding the button removes a built-in way to clear the field, so pair the hide rule with a custom clear control. Restyling instead of hiding goes through the same pseudo-element, and engines outside WebKit and Blink ignore the rule.
One documented exception: an early normalize.css release noted that Safari, unlike Chrome, clips the cancel button when a search input has padding under textfield appearance.
That note dates from early releases, so retest padding in current Safari before relying on it.
How to make a search box responsive
Make the wrapper fluid and let the field take whatever space is left. Keep the input text at 16px or more, otherwise iOS Safari zooms in on focus.
Fluid width and navbar placement
Give the wrapper width: 100% and a max-width around 32rem.
Let the field take the leftover row space with flex: 1 and min-width: 0, so the button is never pushed out of the box.
On a phone the box usually becomes a full-width bar under the logo, or an icon that opens the field. Tablet and desktop get a fixed-width field pushed right with margin-left: auto. In a navbar, W3Schools’ topnav example floats the input right and stacks links and search vertically on narrow screens.
That stack is a plain media query breakpoint. Set it where the layout actually breaks, not at a device width.
iOS focus zoom
iOS Safari zooms into a focused field whose rendered text is below 16px (Telerik knowledge base, West Wind 2023). A Shopware theme vendor’s documentation adds that the page does not zoom back out after blur.
The 1rem field size holds only while the root font size stays at 16px. West Wind lists a smaller root size as a common reason the zoom comes back.
When the root is out of your hands, font-size: max(16px, 1rem) sets a floor.
Raising the font size keeps pinch zoom intact, though the field needs a layout check at the larger size.
The other route is locking zoom with the viewport tag. Telerik’s knowledge base proposes maximum-scale=1 and says manual zoom still works. A 2016 draft technique posted to a W3C mailing list, on the other hand, treats restricted scale as a failure of WCAG 1.4.4 Resize Text on touch devices, with user-scalable=no and maximum-scale=1.5 as failing examples.
The sources disagree on whether locking is harmless, and the W3C reading is the stricter one. Raise the font size and leave the viewport meta tag alone.
Where a CSS search box stops working
Looks end where behavior begins. Running the query and suggesting terms sit outside CSS, and a few of its tricks also stop at the browser engine or the input device.
Behavior that needs a script or a server
- Live filtering of a list on the page
- Suggestion dropdowns
- Result counts and match highlighting
- Searching without a page reload
Each item needs JavaScript for the interaction and data from somewhere. Slider Revolution’s roundup labels its functional animated example as HTML, CSS and JavaScript for exactly that reason.
The query still lands on a backend endpoint that returns results, and the search box only styles the way there.
To react when someone clears a search field, scripts listen for the search event, which MDN marks as non-standard.
Failure points on touch and small screens
WCAG 2.2 SC 2.5.8 sets a minimum pointer target of 24 by 24 CSS pixels, with spacing and equivalent-control exceptions (W3C).
An icon-only button drawn at 16 by 16 pixels with no padding fails unless the spacing exception applies. Size the button with padding or min-width and min-height, not the SVG.
Numbers to keep in mind
iOS Safari zooms into a focused field when the text is below 16px (Telerik, West Wind 2023). The icon button needs a pointer target of at least 24 by 24 CSS pixels (W3C, WCAG 2.2 SC 2.5.8). Text has to resize to 200% and still work, which a locked viewport scale breaks (W3C, WCAG 1.4.4).
The any-hover media feature has been available across browsers since December 2018 (MDN). Support for the cancel button pseudo-element, meanwhile, is limited to WebKit and Blink only (MDN).
CSS Search Box FAQ
How do I center a search box in CSS?
Make the parent a flex container with justify-content: center, or give the form a max-width and margin-inline: auto.
Both keep the box centered as the viewport narrows.
How wide should a search box be?
Wide enough for a typical query, which design systems put at about 27 characters. Queensland Government’s design system defaults to that width, and the University of Virginia’s sets it as the minimum.
In CSS, width: 27ch with max-width: 100% is a workable starting point.
Can a search box support dark mode without extra markup?
Yes. Keep colors in custom properties and redefine them inside @media (prefers-color-scheme: dark).
Recheck the border and focus ring against the dark surface, because a border that passes on white can fail on a dark background.
Does a search box need a visible submit button?
No. A form with one text field submits on Enter, and Slider Revolution’s roundup includes a placeholder-only box built with HTML and CSS alone.
Keep a visually hidden submit button in the markup so every user still has a submit control.
What to Test Before a CSS Search Box Goes Live
Before launch, check keyboard focus and current Safari, then put the page on a real iPhone.
- Tab to the field and confirm a visible focus ring
- Type, blur and clear in Safari with the reset applied
- Focus the field on an iPhone and watch for page zoom
Keyboard comes first because the test needs no device and the failure repeats on every page. The phone test comes last, as the slowest to run.
The trade-off is that the larger text that stops iOS zoom makes a compact header box bigger on phones.
MDN lists the cancel button pseudo-element as non-standard (verified October 2026), so the Safari step stays.
The keyboard and phone checks apply unchanged to the other fields in any CSS form.