The Search box is a combination of input field and submit button. The magnifying glass is used to recognize the element as such.
At the moment the Search Box looks the same as the Page Search component.
But it is not the same element. So please treat them as different components.
wrapped in container
outside container
<!-- Container (mods: --column) -->
<div class="vi-container vi-container--column">
<!-- Search Box -->
<div class="vi-search-box">
<div class="vi-search-box__main">
<form class="vi-search-box__form" action="#search-dea8c3" method="get" role="search" novalidate="novalidate">
<fieldset class="vi-search-box__set">
<label class="sr-only" for="sg-572763">Search</label>
<input autocomplete="off" class="vi-search-box__input" id="sg-572763" name="search" placeholder="This is the search string you typed" required="" title="Search" type="search" value="">
<div class="vi-search-box__btn">
<!-- Button type: search -->
<button type="submit" class="vi-btn-search vi-btn">Search</button>
</div>
</fieldset>
<div class="vi-search-box__clear">
<div class="vi-search-box__clear-inset">
<div class="vi-search-box__clear-btn">
<!-- Button type: search -->
<button type="reset" class="vi-btn-search vi-btn-search--clear vi-btn">Clear</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<!-- Search Box -->
<div class="vi-search-box">
<div class="vi-search-box__main">
<form class="vi-search-box__form" action="#search-8eab78" method="get" role="search" novalidate="novalidate">
<fieldset class="vi-search-box__set">
<label class="sr-only" for="sg-72a872">Search</label>
<input autocomplete="off" class="vi-search-box__input" id="sg-72a872" name="search" placeholder="This is the search string you typed" required="" title="Search" type="search" value="">
<div class="vi-search-box__btn">
<!-- Button type: search -->
<button type="submit" class="vi-btn-search vi-btn">Search</button>
</div>
</fieldset>
<div class="vi-search-box__clear">
<div class="vi-search-box__clear-inset">
<div class="vi-search-box__clear-btn">
<!-- Button type: search -->
<button type="reset" class="vi-btn-search vi-btn-search--clear vi-btn">Clear</button>
</div>
</div>
</div>
</form>
</div>
</div>
To use the inversed view of the search box, a modifier '–inversed' is needed.
<!-- Search Box (mods: --inversed) -->
<div class="vi-search-box vi-search-box--inversed">
<div class="vi-search-box__main">
<form class="vi-search-box__form" action="#search-5a90d1" method="get" role="search" novalidate="novalidate">
<fieldset class="vi-search-box__set">
<label class="sr-only" for="sg-a3566b">Search</label>
<input autocomplete="off" class="vi-search-box__input" id="sg-a3566b" name="search" placeholder="This is the search string you typed" required="" title="Search" type="search" value="">
<div class="vi-search-box__btn">
<!-- Button type: search -->
<button type="submit" class="vi-btn-search vi-btn">Search</button>
</div>
</fieldset>
<div class="vi-search-box__clear">
<div class="vi-search-box__clear-inset">
<div class="vi-search-box__clear-btn">
<!-- Button type: search -->
<button type="reset" class="vi-btn-search vi-btn-search--clear vi-btn">Clear</button>
</div>
</div>
</div>
</form>
</div>
</div>
Then to use the small version of the inversed, use modifiers '–inversed' and '–inversed-small'.
<!-- Search Box (mods: --inversed, --inversed-small) -->
<div class="vi-search-box vi-search-box--inversed vi-search-box--inversed-small">
<div class="vi-search-box__main">
<form class="vi-search-box__form" action="#search-6b0098" method="get" role="search" novalidate="novalidate">
<fieldset class="vi-search-box__set">
<label class="sr-only" for="sg-6b300b">Search</label>
<input autocomplete="off" class="vi-search-box__input" id="sg-6b300b" name="search" placeholder="This is the search string you typed" required="" title="Search" type="search" value="">
<div class="vi-search-box__btn">
<!-- Button type: search -->
<button type="submit" class="vi-btn-search vi-btn">Search</button>
</div>
</fieldset>
<div class="vi-search-box__clear">
<div class="vi-search-box__clear-inset">
<div class="vi-search-box__clear-btn">
<!-- Button type: search -->
<button type="reset" class="vi-btn-search vi-btn-search--clear vi-btn">Clear</button>
</div>
</div>
</div>
</form>
</div>
</div>
Autosuggest is optional. Point data attribute data-endpoint to a valid endpoint to show the autosuggest.
Data attribute data-noresults can be used to change the default text. (the %-sign is replaced with the search string).
Options:
data-endpoint: (optional) the URL to an endpointdata-noresults: (optional) to change the 'no results' text (i18n)data-debounce: (optional) ms to postpone requesting endpoint, default 200ms.data-min-chars: (optional) minimum chars required before starting to search, default 3.data-submit-on-select: (optional) submit the form when a suggestion is selected, default true.<!-- Search Box -->
<div class="vi-search-box" data-debounce="314" data-endpoint="/api/search-box/results.json" data-noresults="No results for % found" data-submit-on-select="false">
<div class="vi-search-box__main">
<form class="vi-search-box__form" action="#search-cd0a48" method="get" role="search" novalidate="novalidate">
<fieldset class="vi-search-box__set">
<label class="sr-only" for="sg-0e8401">Search</label>
<input autocomplete="off" class="vi-search-box__input" id="sg-0e8401" name="search" placeholder="This is the search string you typed" required="" title="Search" type="search" value="">
<div class="vi-search-box__btn">
<!-- Button type: search -->
<button type="submit" class="vi-btn-search vi-btn">Search</button>
</div>
</fieldset>
<div class="vi-search-box__clear">
<div class="vi-search-box__clear-inset">
<div class="vi-search-box__clear-btn">
<!-- Button type: search -->
<button type="reset" class="vi-btn-search vi-btn-search--clear vi-btn">Clear</button>
</div>
</div>
</div>
</form>
</div>
</div>
Inverted search box with autosuggest
<!-- Search Box (mods: --inversed) -->
<div class="vi-search-box vi-search-box--inversed" data-debounce="314" data-endpoint="/api/search-box/results.json" data-noresults="No results for % found">
<div class="vi-search-box__main">
<form class="vi-search-box__form" action="#search-c3096e" method="get" role="search" novalidate="novalidate">
<fieldset class="vi-search-box__set">
<label class="sr-only" for="sg-928b52">Search</label>
<input autocomplete="off" class="vi-search-box__input" id="sg-928b52" name="search" placeholder="This is the search string you typed" required="" title="Search" type="search" value="">
<div class="vi-search-box__btn">
<!-- Button type: search -->
<button type="submit" class="vi-btn-search vi-btn">Search</button>
</div>
</fieldset>
<div class="vi-search-box__clear">
<div class="vi-search-box__clear-inset">
<div class="vi-search-box__clear-btn">
<!-- Button type: search -->
<button type="reset" class="vi-btn-search vi-btn-search--clear vi-btn">Clear</button>
</div>
</div>
</div>
</form>
</div>
</div>
<!-- Search Box (mods: --inversed, --inversed-small) -->
<div class="vi-search-box vi-search-box--inversed vi-search-box--inversed-small" data-debounce="314" data-endpoint="/api/search-box/results.json" data-noresults="No results for % found">
<div class="vi-search-box__main">
<form class="vi-search-box__form" action="#search-bdd726" method="get" role="search" novalidate="novalidate">
<fieldset class="vi-search-box__set">
<label class="sr-only" for="sg-bad66b">Search</label>
<input autocomplete="off" class="vi-search-box__input" id="sg-bad66b" name="search" placeholder="This is the search string you typed" required="" title="Search" type="search" value="">
<div class="vi-search-box__btn">
<!-- Button type: search -->
<button type="submit" class="vi-btn-search vi-btn">Search</button>
</div>
</fieldset>
<div class="vi-search-box__clear">
<div class="vi-search-box__clear-inset">
<div class="vi-search-box__clear-btn">
<!-- Button type: search -->
<button type="reset" class="vi-btn-search vi-btn-search--clear vi-btn">Clear</button>
</div>
</div>
</div>
</form>
</div>
</div>
All data attributes except for data-endpoint, data-noresults, data-debounce, data-min-chars will be added as querystring parameters.
Format is data-{key}="{value}", where key is the name if the querystring parameters and value is the value.
<!-- Search Box -->
<div class="vi-search-box" data-endpoint="/api/search-box/results.json" data-language="en" data-min-chars="2" data-noresults="No results for % found" data-pageid="141768" data-resultsperpage="10" data-searchtype="US" data-siteid="5702">
<div class="vi-search-box__main">
<form class="vi-search-box__form" action="#search-9783e0" method="get" role="search" novalidate="novalidate">
<fieldset class="vi-search-box__set">
<label class="sr-only" for="sg-4da59e">Search</label>
<input autocomplete="off" class="vi-search-box__input" id="sg-4da59e" name="search" placeholder="This is the search string you typed" required="" title="Search" type="search" value="">
<div class="vi-search-box__btn">
<!-- Button type: search -->
<button type="submit" class="vi-btn-search vi-btn">Search</button>
</div>
</fieldset>
<div class="vi-search-box__clear">
<div class="vi-search-box__clear-inset">
<div class="vi-search-box__clear-btn">
<!-- Button type: search -->
<button type="reset" class="vi-btn-search vi-btn-search--clear vi-btn">Clear</button>
</div>
</div>
</div>
</form>
</div>
</div>
The autosuggest makes a GET request to the the url provided by data-endpoint with
following parameter:
query string with the search querydata-{key}="{value}"Server should respond in JSON format an array of 'results'. Limit the result set at own discretion.
Each result has the following keys:
primary string primary search resultsecondary (optional) string with secondary info.An example of the JSON with one answer.
[{"primary":"Locavore 3 wolf moon kinfolk vice five dollar toast roof hashtag. Pop-up health twee schlitz muggle magic bicycle rights whatever. Flannel tote bag small batch bushwick 8-bit squid cleanse iphone. Small batch cronut biodiesel mlkshk five dollar toast intelligentsia cardigan. Crucifix dreamcatcher locavore.","secondary":"optional description"}]
When the primary key contains the tag %suggestion%, select the tagged suggestion only.
[{"primary":"How about the word \"%suggestion%kerfuffle%suggestion%\"?","secondary":"optional category or site section"}]
When the suggestion key is provided, the value is considered wysiwyg content and visible in the dropdown
[{"suggestion":"\u003ch1\u003eI am very \"important\" and can potentially break 'everything'\u003c/h1\u003e"}]
When a suggestion is choosen, the event vi-search-box:selected is triggered with
the suggestion data from the server.
See console.
<!-- Search Box -->
<div class="vi-search-box" data-endpoint="/api/search-box/results.json" data-language="en" data-min-chars="2" data-noresults="No results for % found" data-pageid="141768" data-resultsperpage="10" data-searchtype="US" data-siteid="5702" id="sg-4ca1c5">
<div class="vi-search-box__main">
<form class="vi-search-box__form" action="#search-be6d77" method="get" role="search" novalidate="novalidate">
<fieldset class="vi-search-box__set">
<label class="sr-only" for="sg-c10b9c">Search</label>
<input autocomplete="off" class="vi-search-box__input" id="sg-c10b9c" name="search" placeholder="This is the search string you typed" required="" title="Search" type="search" value="">
<div class="vi-search-box__btn">
<!-- Button type: search -->
<button type="submit" class="vi-btn-search vi-btn">Search</button>
</div>
</fieldset>
<div class="vi-search-box__clear">
<div class="vi-search-box__clear-inset">
<div class="vi-search-box__clear-btn">
<!-- Button type: search -->
<button type="reset" class="vi-btn-search vi-btn-search--clear vi-btn">Clear</button>
</div>
</div>
</div>
</form>
</div>
</div>
<script>
$("#sg-4ca1c5").on('vi-search-box:selected', function(event, data) {
console.log(data);
})
</script>
The following stylesheets are required to display this component.
The following additional stylesheets are used to display the example(s).
The following javascript is required to display this component.
The following additional javascript is used to display the example(s).
Usage documentation can be found here.
Changelog
- 09 Oct 2025 - fix(search-box): Secondary text color when selected.
Fix
- 24 Jun 2025 - fix(search-box): dropdown width for
--inversed-small version.
- 23 Jun 2025 - fix(search-box): dropdown width for
--inversed version.
- 13 Mar 2025 - fix(search-box): cleanup css and fix logical flow (rtl)
- 18 Jun 2024 - Null check for suggestions.
- 20 Sep 2023 - Suggestions dropdown height fix.
- 11 Aug 2023 - Inversed search box input line height fix.
- 23 Jun 2023 - Remove value when clear button clicked.
- 14 Jun 2023 - Fix missing hover color after ‘suggestion’ from server.
- 22 Mar 2023 - Fix disappearing highlighted spaces.
- 14 Mar 2023 - move
data-debounce out of auto-querystring-conversion.
- Smarter string sanitizer to allow Hebrew characters (but not
<script> for example)
- Fix RTL support, secondary text different order. Might need finetuning from native speakers.
- Fix RTL support, demo requires extra js (because of the direction switch)
Added
- 23 Oct 2024 - Optional Submit on select by using
data-submit-on-select attribute.
- 12 Sep 2023 - Added scrollpane on autocomplete results
- 2 Aug 2023 - Added examples for inverted style for search box with normal and small variants.
- 14 Jun 2023 - Add custom event
vi-search-box:selected that triggers when a suggestion is selected.
- 3 Apr 2023 - Show HTML when result-key is
suggestion
- 24 Mar 2023 - data attribute
data-min-chars to finetune the minimal characters required before requesting the endpoint.
- 24 Mar 2023 - Add clear button to form.
- 14 Mar 2023 - When
primary contains %suggestion%-tags select the tagged suggestion only.
- 14 Mar 2023 - make
data-attributes behave like properties.
- 10 Mar 2023 - data attribute
data-debounce to finetune the postpone of endpoint requests.
- 16 Dec 2022 - optional extra querystring parameters.
- PBS support
- data attribute
data-noresults to translate “No results…” string.
- Autosuggest support
- RTL support
- Initial draft
Changed
- 23 Aug 2024 - Submit on select
- 05 Jul 2023 - Placeholder capitalization settable by editor.
- 23 Mar 2023 - Show results focus (and also when clicked while active)
- CSS Optimized for print.
- Minimum 3 characters needed before suggestions start getting rendered.
- Debouncing 200ms