StaticSearch web component
(updated )
909 words, 5-minute read
The <static-search>
web component provides full search functionality in any web page using HTML alone. It’s the easiest option, e.g.
<!-- include script once on your page -->
<script type="module" src="/search/staticsearch-component.js"></script>
<!-- define web component -->
<static-search title="press Ctrl+K to search">
<p>search</p>
</static-search>
The component uses the Shadow DOM so your styles will not affect its layout. You can style it using custom properties and/or ::part
selectors.
Search activation element #
Place <static-search>
anywhere you want a search icon or text – perhaps in the page <header>
. It requires a single inner element that the user clicks to activate the search. This opens a modal dialog with an input field and results list.
The activation element must be an element with content – it cannot be empty or text only. You can also assign part
attributes for styling, e.g.
<static-search title="press Ctrl+K to search">
<a part="staticsearchactivate" href="https://duckduckgo.com/?q=search%20site:mysite.com">
<svg part="staticsearchicon" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
<path d="M10 4a6 6 0 1 0 0 12 6 6 0 0 0 0-12Zm-8 6a8 8 0 1 1 14.3 5l5.4 5.3a1 1 0 0 1-1.4 1.4l-5.4-5.4A8 8 0 0 1 2 10Z"></path>
</svg>
</a>
</static-search>
This example links to duckduckgo.com search by default. The web component progressively enhances it to use StaticSearch instead. The user gets a search facility when JavaScript fails to load or run.
Web component attributes #
Add any of the following <static-search>
attributes to control functionality:
attribute | description |
---|---|
title="<string>" | activation instructions (users can click or press Ctrl|Cmd+K) |
label="<string>" | the label on the search <input> |
minfound="<num>" | only show pages containing at least this proportion of search words (0.0 to 1.0 ) |
minscore="<num>" | only show pages with total relevancy scores of this or above on results |
maxresults="<num>" | show up to this number of pages on the results |
Search results provide a found
value indicating the percentage of search words found on a page, e.g. two of four search words is 0.5
.
setting
minfound="0"
(the default) is a logical OR. A page appears in results when it contains ANY of the search words.setting
minfound="1"
is a logical AND. A page appears in results when it contains ALL the search words.setting
minfound="0.5"
means a page appears in results when it contains at least half of the search words.
Pages still appear in relevancy
order, but higher minfound
values will reduce the number of results.
Overriding HTML templates #
You can change the HTML shown when displaying results using <template>
elements.
Search results message #
When search results are available, you’ll see a message such as:
7 found for “web component”…
It uses the HTML code:
<p part="resultmessage">
<span part="resultcount"></span> found for
<span part="searchterm"></span>…
</p>
You can override this using a <template>
with an ID of staticsearch_resultmessage
in your HTML page (it can be within <static-search>
or anywhere else). You must set the part
attributes "resultmessage"
, "resultcount"
, and "searchterm"
as necessary, e.g.
<template id="staticsearch_resultmessage">
<p part="resultmessage">
StaticSearch found
<span part="resultcount"></span> results
for <span part="searchterm"></span>:
</p>
</template>
Search result item #
An ordered list (<ol part="searchresult">
) contains search results. Each page result uses the HTML:
<li part="item">
<a part="link">
<h2 part="title"></h2>
<p part="meta">
<time part="date"></time> –
<span part="words">0</span> words
</p>
<p part="description"></p>
</a>
</li>
You can override this using a <template>
with an ID of staticsearch_item
in your HTML page (it can be within <static-search>
or anywhere else). Set the part
attributes "item"
, "link"
, "title"
, meta
, date
, words
, and "description"
as necessary, e.g. show the title but no description, date, or word count in an <article>
:
<template id="staticsearch_item">
<li part="item">
<article>
<h2 part="title"><a part="link"></a></h2>
</article>
</li>
</template>
CSS custom property styling #
You can style <static-search>
elements using CSS custom properties (variables) in the :root
or any ancestor element. StaticSearch uses a neutral set of colors and follows your site’s light/dark theme if your CSS sets color-scheme: light dark;
, color-scheme: light;
, or color-scheme: dark;
as necessary.
The following code shows custom property defaults you can change:
:root {
/* font size */
--staticsearch-fontsize: 1em;
/* modal dimensions */
--staticsearch-maxwidth: 60ch;
--staticsearch-margin: 3vmin;
--staticsearch-padding: 2vmin;
--staticsearch-fieldset-height: calc(3em + (2 * var(--staticsearch-padding)));
/* colors */
--staticsearch-color-back: Canvas;
--staticsearch-color-border: ButtonFace;
--staticsearch-color-fore0: CanvasText;
--staticsearch-color-fore1: color-mix(in oklab, CanvasText 80%, Canvas);
--staticsearch-color-fore2: color-mix(in oklab, CanvasText 60%, Canvas);
--staticsearch-color-link: color-mix(in oklab, LinkText 70%, CanvasText);
--staticsearch-color-visited: color-mix(in oklab, VisitedText 70%, CanvasText);
--staticsearch-color-shadow: #000;
--staticsearch-color-backdrop: color-mix(in srgb, var(--colshad0), transparent 30%);
--staticsearch-backdrop-blur: 3px;
}
CSS ::part
selector styling #
You can target static-search
elements using ::part
selectors. StaticSearch generates HTML such as this – note the part
attribute names:
<static-search>
<!-- user-defined activation element -->
<p>search</p>
<!-- dialog with aria-expanded when open -->
<dialog part="dialog" aria-expanded="true">
<!-- close button -->
<form method="dialog">
<button part="close">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path xmlns="http://www.w3.org/2000/svg" fill="currentColor" d="M5.3 5.3a1 1 0 0 1 1.4 0l5.3 5.3 5.3-5.3a1 1 0 1 1 1.4 1.4L13.4 12l5.3 5.3a1 1 0 0 1-1.4 1.4L12 13.4l-5.3 5.3a1 1 0 0 1-1.4-1.4l5.3-5.3-5.3-5.3a1 1 0 0 1 0-1.4Z"/></svg>
</button>
</form>
<!-- search form -->
<search part="search">
<label for="search" part="searchlabel">search</label>
<input type="search" id="search" name="q" minlength="2" maxlength="300" part="searchinput" />
</search>
<!-- search results -->
<div part="results">
<!-- default results message -->
<p part="resultmessage">
<span part="resultcount">1</span> found for
<span part="searchterm">"web component"</span>…
</p>
<!-- results list -->
<ol part="searchresult">
<!-- default results item -->
<li part="item">
<a part="link">
<h2 part="title"></h2>
<p part="meta">
<time part="date"></time> –
<span part="words">0</span> words
</p>
<p part="description"></p>
</a>
</li>
</ol>
</div>
</dialog>
<static-search>
You can target any element with its ::part
selector:
static-search {
/* modal dialog */
&::part(dialog) {
border: 5px solid #f00;
}
/* input */
&::part(searchlabel) {
text-transform: uppercase;
}
&::part(searchinput) {
font-family: monospace;
}
&::part(resultmessage) {
font-size: 1.5em;
}
&::part(description) {
font-size: 0.8em;
}
}
Re-run the indexer #
Once you have added StaticSearch functionality to your static site’s templates, you should re-run the indexer to ensure word indexes are up-to-date.