Auto mode (default)
The search bar renders automatically on every page via the wp_body_open hook. No theme changes required. Configure the trigger type, position, and aesthetic from Settings → Fast Fuzzy Search.
Shortcode mode
Set the mode to Shortcode in settings, then place the search bar exactly where you want it:
[fast_fuzzy_search]
Place this in any template file, widget area, or block editor shortcode block. The shortcode accepts attributes to override the global settings — see the shortcode reference for details.
Tip: Use shortcode mode if your theme does not fire wp_body_open or if you want the search in a specific location such as the header or sidebar.
The plugin uses fast_fuzzy_search_locate_template() which resolves templates in this order:
- Child theme —
/wp-content/themes/your-child-theme/template-parts/...
- Parent theme —
/wp-content/themes/your-parent-theme/template-parts/...
- Plugin —
/wp-content/plugins/fast-fuzzy-search/template-parts/...
To override a template, copy it from the plugin’s template-parts/ folder into your theme at the same relative path.
Available template files
| File |
Purpose |
Child-theme path |
input-field.php |
Full search input with results panel |
template-parts/input-field.php |
icon-button.php |
Floating search icon trigger |
template-parts/icon-button.php |
button.php |
Text + icon button trigger |
template-parts/button.php |
input-button.php |
Search field with inline trigger behaviour |
template-parts/input-button.php |
search-panel.php |
Overlay panel wrapper shown by icon/button triggers |
template-parts/search-panel.php |
Developer note: The fast_fuzzy_search_get_template_part( $slug, $name, $args ) function works like WordPress get_template_part(). The $args array is extracted into the template scope. Use $args[’is_inline’] to detect whether the template is rendered inside the overlay panel or on its own.
File cascade
The plugin enqueues two stylesheets in order:
css/style.css — Block layout, position variants, BEM base, scrollbar, transitions, keyboard-shortcuts footer, empty state, trigger buttons. The design tokens (colours, spacing, radii) live in a comment block at the top of this file — no separate _tokens.css file is needed.
css/{aesthetic}.css — The active theme’s visual overrides, scoped under .fast-fuzzy-search--{aesthetic}
All themes live in a flat css/ directory — no subdirectories. Free themes: minimal-light.css, minimal-dark.css. Pro themes: material-light.css, material-dark.css, glassmorphic.css, brutal.css, custom.css.
BEM naming convention
| Pattern |
Example |
Purpose |
.fast-fuzzy-search |
.fast-fuzzy-search |
Root component block |
.fast-fuzzy-search__element |
.fast-fuzzy-search__field |
Child element (input, icon, results, chip, etc.) |
.fast-fuzzy-search--modifier |
.fast-fuzzy-search--bottom-center |
Block-level modifier (position, aesthetic, state) |
.fast-fuzzy-search__element--modifier |
.fast-fuzzy-search__panel-close--minimal-light |
Element-level modifier (aesthetic-specific close button) |
Position modifiers
Add one of these classes to the root element to control placement:
.fast-fuzzy-search--bottom-center — Fixed bottom centre (default)
.fast-fuzzy-search--bottom-left — Fixed bottom left
.fast-fuzzy-search--bottom-right — Fixed bottom right
.fast-fuzzy-search--inline — Static inline flow (no fixed positioning)
.fast-fuzzy-search--scrolled — Applied via JavaScript when scrolling past a threshold (opacity + pointer-events)
Overlay
The .ffs-overlay class is used by the search panel overlay (fixed backdrop with centred search field).
Token reference — all --ffs-* properties
| Property |
Type |
Description |
--ffs-color-primary-50 |
Colour |
Primary palette — lightest shade |
--ffs-color-primary-100 |
Colour |
Primary palette — light |
--ffs-color-primary-200 |
Colour |
Primary palette |
--ffs-color-primary-300 |
Colour |
Primary palette |
--ffs-color-primary-400 |
Colour |
Primary palette |
--ffs-color-primary-500 |
Colour |
Primary palette — base |
--ffs-color-primary-600 |
Colour |
Primary palette — selected / hover |
--ffs-color-primary-700 |
Colour |
Primary palette |
--ffs-color-primary-800 |
Colour |
Primary palette |
--ffs-color-primary-900 |
Colour |
Primary palette — darkest shade |
--ffs-font-sans |
Font |
Font-family stack for the search field |
--ffs-border-color |
Colour |
Default border colour used by panels and chips |
--ffs-radius-pill |
Radius |
Border-radius for pills, chips, and small elements |
--ffs-space-1 |
Spacing |
4 px unit |
--ffs-space-2 |
Spacing |
8 px unit |
--ffs-space-3 |
Spacing |
12 px unit |
--ffs-space-4 |
Spacing |
16 px unit |
--ffs-space-5 |
Spacing |
24 px unit |
--ffs-duration-fast |
Duration |
Fast transition duration (~150 ms) |
--ffs-easing |
Easing |
Transition easing function |
--ffs-scrollbar-thumb |
Colour |
Scrollbar thumb background |
--ffs-scrollbar-thumb-hover |
Colour |
Scrollbar thumb hover background |
To customise, add overrides in your theme’s stylesheet:
:root {
--ffs-color-primary-500: #e74c3c;
--ffs-color-primary-600: #c0392b;
--ffs-font-sans: "Open Sans", sans-serif;
--ffs-radius-pill: 6px;
}
How it works
- Select Custom — Open Fast Fuzzy Search → Display → Aesthetic and choose Custom. An inline editor appears below the theme thumbnails.
- Load a base theme — Pick any built-in theme from the dropdown and click Load Base Theme. The theme’s CSS is fetched, its
.fast-fuzzy-search--{slug} selectors are automatically rewritten to .fast-fuzzy-search--custom, and the result fills the CSS editor. Loading a base theme replaces whatever is currently in the editor.
- Customise — Edit the CSS directly in the textarea. Write any valid CSS.
- Save — Click Save Changes. The editor content is written to
wp-content/uploads/fast-fuzzy-search/custom.css and enqueued on the front end. Previously saved CSS is restored when you return to the settings page.
Important rules for custom CSS
- Scope everything under
.fast-fuzzy-search--custom — All selectors must use this class to match the root element. When you load a base theme, the selector rewrite handles this automatically.
- Use
--ffs-color-primary-* tokens — Never hardcode hex or rgba colors. Reference the user’s configured primary color via var(--ffs-color-primary-*) for direct colors and rgba(var(--ffs-color-primary-rgb), opacity) for translucent effects. This ensures styling respects the user’s color choice.
- Use design tokens — Leverage
--ffs-space-* (spacing), --ffs-radius-* (border-radius), --ffs-font-sans (font-family), --ffs-duration-* (animation), and --ffs-easing (timing) from the token system at the top of css/style.css.
Generated file location
The custom CSS is stored at wp-content/uploads/fast-fuzzy-search/custom.css. This file is generated automatically when you save the settings with the Custom aesthetic selected. It is versioned via filemtime() so browser caches invalidate after every save.
Theme-file auto-discovery
In addition to the Custom aesthetic, you can drop a custom.css file into your active WordPress theme at wp-content/themes/your-theme/fast-fuzzy-search/custom.css. The plugin auto-discovers it and enqueues it after the active theme — theme authors can ship search styling with their theme without touching the plugin or the database.
// wp-content/themes/your-theme/fast-fuzzy-search/custom.css
.fast-fuzzy-search--minimal-light .fast-fuzzy-search__button {
border-radius: 0;
text-transform: uppercase;
letter-spacing: 0.05em;
}
Load order
css/style.css — base + position modifiers + design tokens
css/{aesthetic}.css — the active built-in theme
uploads/fast-fuzzy-search/custom.css — generated custom CSS (only when aesthetic is Custom)
- Theme-file auto-discovery
custom.css (if present in the active theme)
Developer note: The base theme’s CSS is fetched via AJAX (wp_ajax_fast_fuzzy_search_get_theme_css) and its selectors are rewritten using a regex that replaces .fast-fuzzy-search--{slug} with .fast-fuzzy-search--custom. The transformed CSS is cached in the Alpine component so switching base themes doesn’t re-fetch if it was already loaded during the session. When you save, the editor content is written directly to uploads/fast-fuzzy-search/custom.css — no base-theme combination logic runs at save time (the editor content is already self-contained with rewritten selectors).
Built-in themes
Six production themes ship with the plugin. Each one is named, scoped under .fast-fuzzy-search--{slug}, and styled independently in its own file under css/ (flat directory, no subdirectories).
| Aesthetic |
Tier |
Inspiration |
minimal-light |
Free |
WordPress Design System (WPDS) + Apple's Human Interface Guidelines. White surface, gray-300 border, system font, 4px baseline grid, soft elevation. The "default" theme — safe on any site. |
minimal-dark |
Free |
WPDS + Vercel + Linear (dark variants). Dark surface, system font, tight spacing, soft elevation on hover. The dark counterpart to minimal-light. |
material-light |
Pro |
Google Material Design 3. Pill field, 2px primary-tinted border, Material elevation, circular 40×40 result icons. The official Material look. |
material-dark |
Pro |
Material Design 3 dark variant. Same shape as material-light, inverted palette (primary-900 background, primary-50 text). |
glassmorphic |
Pro |
macOS Big Sur / iOS translucent surfaces. Backdrop blur, rgba black 60% surfaces, hairline white 15% borders, white 60% focus rings. The "frosted glass" aesthetic — best on darker page backgrounds. |
brutal |
Pro |
Neo-brutalism. Hard 2px black borders, 0 border-radius, hard 6×6 offset shadows, square corners, all-caps semantic. The "raw web" aesthetic. |
custom |
Pro |
User-defined. Start from any built-in theme via the inline CSS editor. Select a base theme, click Load Base Theme, and the CSS is automatically rewritten with .fast-fuzzy-search--custom selectors. Edit freely and save — the result is written to uploads/fast-fuzzy-search/custom.css. |
iris |
Pro |
Inspired by Stripe's signature purple gradient and weight-300 elegance. Premium fintech feel. |
crisp |
Pro |
Inspired by Linear's ultra-precise, tight-density aesthetic. For product-focused teams. |
terracotta |
Pro |
Inspired by Claude's warm terracotta and editorial layout. For AI, research, and content sites. |
editorial |
Pro |
Inspired by Notion's warm minimalism. Soft surfaces, journal-like content sites. |
State pattern (every theme)
All themes follow the same surface pattern. The base style.css sets layout, transition, and the :active scale (0.97). Each theme owns the surface: color, border, shadow, focus ring. The hover and focus states are unified — one :hover rule per theme, one :focus-visible rule per theme — so the visual language is consistent.
/* Every theme styles these four selectors (the patterns differ). */
.fast-fuzzy-search--{aesthetic} .fast-fuzzy-search__icon-button { /* base */ }
.fast-fuzzy-search--{aesthetic} .fast-fuzzy-search__icon-button:hover { /* hover */ }
.fast-fuzzy-search--{aesthetic} .fast-fuzzy-search__icon-button:focus-visible { /* focus */ }
/* :active comes from the base — transform: scale(0.97) */
Trigger elements — template-to-class map
Each of the four trigger element templates renders a small set of BEM classes. When writing a new theme or a custom override, these are the classes that carry the surface (color, border, shadow):
template-parts/button.php
.fast-fuzzy-search__button — the full text “Search” trigger button
template-parts/icon-button.php
.fast-fuzzy-search__icon-button — the icon-only circular trigger
template-parts/input-button.php
.fast-fuzzy-search__field — the trigger rendered as a search-field look
.fast-fuzzy-search__icon — left-side icon column
.fast-fuzzy-search__icon-frame — the 24×24 frame around the SVG
template-parts/input-field.php
.fast-fuzzy-search__field — the search field inside the panel
.fast-fuzzy-search__icon, .fast-fuzzy-search__icon-frame — icon column + 24×24 frame
.fast-fuzzy-search__input — the native <input>
.fast-fuzzy-search__clear — the X button to clear the field
.fast-fuzzy-search__panel — the dropdown panel below the field
.fast-fuzzy-search__post-types, .fast-fuzzy-search__chip-list, .fast-fuzzy-search__chip-button — the post-type filter bar
.fast-fuzzy-search__chip — the type label inside each result row
.fast-fuzzy-search__context — the “Searching in X” strip
.fast-fuzzy-search__results — the results <ul>
.fast-fuzzy-search__result-item, .fast-fuzzy-search__result-link, .fast-fuzzy-search__result-icon, .fast-fuzzy-search__result-image — each result row
.fast-fuzzy-search__result-content, .fast-fuzzy-search__result-text, .fast-fuzzy-search__result-primary, .fast-fuzzy-search__result-secondary — result text layout
.fast-fuzzy-search__view-all, .fast-fuzzy-search__view-all-icon — the “View all N results” button
.fast-fuzzy-search__empty, .fast-fuzzy-search__empty-title, .fast-fuzzy-search__empty-description — empty + no-results state
.fast-fuzzy-search__keyboard-shortcuts, .fast-fuzzy-search__kbd — the keyboard hints footer
.fast-fuzzy-search__panel-close — the close (X) button in the overlay
For the full BEM contract including all modifiers and states, see the comment block at the top of css/style.css.
Key component classes
| Class |
Targets |
.fast-fuzzy-search__field |
Search input wrapper row |
.fast-fuzzy-search__input |
The native <input> element |
.fast-fuzzy-search__icon |
Search icon container (left side) |
.fast-fuzzy-search__icon-frame |
24x24 px frame inside the icon container |
.fast-fuzzy-search__clear |
Clear button wrapper (right side) |
.fast-fuzzy-search__panel |
Results dropdown panel |
.fast-fuzzy-search__results |
Scrollable results list |
.fast-fuzzy-search__result-item |
Single result row |
.fast-fuzzy-search__result-link |
The anchor inside each result |
.fast-fuzzy-search__result-image |
Featured image thumbnail in result |
.fast-fuzzy-search__result-icon |
Type indicator icon (link / hash) |
.fast-fuzzy-search__chip |
Small label chip (category, heading badge) |
.fast-fuzzy-search__chip-button |
Post-type filter chip button |
.fast-fuzzy-search__chip-list |
Filter chips container |
.fast-fuzzy-search__post-types |
Post-type filter bar |
.fast-fuzzy-search__context |
Contextual search indicator text |
.fast-fuzzy-search__empty |
Empty state message block |
.fast-fuzzy-search__keyboard-shortcuts |
Footer with keyboard hints |
.fast-fuzzy-search__panel-close |
Close button on the overlay panel |
.fast-fuzzy-search__scrollbar |
Custom scrollbar container |
.fast-fuzzy-search__transition-* |
Alpine transition classes for enter / leave animations |
Modifier classes
| Class |
Effect |
.fast-fuzzy-search--scrolled |
Applies opacity:0; pointer-events:none for scroll-to-hide behaviour |
.fast-fuzzy-search__field[data-has-query="true"] |
Removes bottom border radius when results are shown |
.fast-fuzzy-search__result-link[aria-selected="true"] |
Highlighted / active result via keyboard navigation |
.fast-fuzzy-search__chip-button[aria-selected="true"] |
Active post-type filter chip |
Transitions
The overlay panel uses Alpine.js transition classes. Override the duration and easing by targeting:
.fast-fuzzy-search__transition-enter .fast-fuzzy-search {
transition-duration: 300ms;
}
.fast-fuzzy-search__transition-leave {
transition-duration: 200ms;
}
Filters
| Filter |
Arguments |
Description |
fast_fuzzy_search_aesthetic |
$aesthetic (string), $options (array) |
Override the active theme slug at runtime. Return a registered aesthetic slug to change the look. |
Example — dynamic theming per post type
add_filter( 'fast_fuzzy_search_aesthetic', function( $aesthetic, $options ) {
if ( is_singular( 'product' ) ) {
return 'material-dark';
}
return $aesthetic;
}, 10, 2 );
Actions
| Action |
Description |
ffs_fs_loaded |
Fired after the Freemius SDK is initialised. Use to hook into Freemius-specific callbacks. |
Shortcode attributes
| Attribute |
Accepted values |
Default |
Description |
placeholder |
Any text string |
“Search for something here…” |
Placeholder text for the search input |
aesthetic |
minimal-light, minimal-dark, material-light, material-dark, glassmorphic, brutal |
Saved option |
Visual theme for this instance |
type |
input-field, icon-button, button, input-button |
Saved option |
Trigger type for this instance |
Attributes override the global plugin settings. Omitted attributes inherit from the saved configuration.
[fast_fuzzy_search type="input-field" aesthetic="minimal-dark" placeholder="Find products…"]
Note: The shortcode renders in inline mode by default (no fixed positioning). The overlay panel is triggered by icon-button and button types regardless of mode.
| Event |
Detail |
When |
fast-fuzzy-search:loaded |
None |
Fired once the AJAX fetch completes and the fuzzy index is ready for queries |
Usage example
document.addEventListener( 'fast-fuzzy-search:loaded', function() {
console.log( 'Fast Fuzzy Search index is ready.' );
} );