Skip to main content

google-search.html

google-search.html is a standalone HTML page that provides a customized search interface for gwern.net using Google's standard search engine.

Pathgoogle-search.html
LanguageHTML
Lines161
Sourcegoogle-search.html
at 406d3e423

Read this when Use this page when tracing the HTML/Pandoc templates and include fragments that shape rendered gwern.net pages around google-search.

Overview

google-search.html is a standalone HTML page that provides a customized search interface for gwern.net using Google's standard search engine. Unlike google-cse.html which embeds Google's Custom Search widget, this page implements a native HTML form that submits searches to Google with site-specific filters.

The page features a clean, minimalist design with support for both light and dark color schemes and provides options to search all of gwern.net, essays only, or documentation only. The search form opens results in a new tab, maintaining the user's current browsing context.

File Structure

Location: /Users/m/Projects/gwern-analysis/gwern.net/google-search.html

Type: HTML page (standalone)

Lines: 161 lines

HTML Structure

Title and Metadata

<title>Gwern.net Search</title>

Simple title without additional meta tags, suggesting this is designed for embedding or iframe use rather than direct navigation.

Styling System

The page includes two style blocks:

  1. Base styles (#search-styles)
  2. Dark mode styles (#search-styles-dark with prefers-color-scheme: dark media query)

This approach provides automatic dark mode support based on user's system preferences.

Main Layout

<body>
<main>
<form id="searchform-main" class="searchform">...</form>
<fieldset id="search-where-selector">...</fieldset>
<form id="searchform-ref" class="searchform">...</form>
</main>
</body>

Layout technique:

  • Body uses flexbox to center content vertically
  • Main element contains the search UI
  • Pointer events disabled on body, re-enabled on interactive elements
  • Flexbox ensures content stays centered regardless of viewport size

Search Form

<form action="https://www.google.com/search"
class="searchform"
method="get"
name="searchform"
target="_blank">
<input autocomplete="on"
class="form-control search"
placeholder="Gwern.net search"
required="required"
type="text">
<input class="query" name="q" type="hidden">
<button class="button" type="submit">Search</button>
</form>

Form Behavior

Action: https://www.google.com/search - Submits to Google's search engine

Method: GET - Query parameters appear in URL

Target: _blank - Opens results in new tab/window

Input Fields

  1. Visible text input:

    • Class: form-control search
    • Autocomplete enabled
    • Required field (HTML5 validation)
    • Placeholder: "Gwern.net search"
  2. Hidden query input:

    • Name: q (Google's query parameter)
    • Populated by JavaScript before form submission
    • Combines user query with site filter

Search Button

Styled submit button with:

  • Hover effects (background darkens, text lightens)
  • Focus states with outline
  • Fixed width (5em) vs flexible text input
  • Pointer cursor on hover

Site Filter Selector

<fieldset id="search-where-selector">
<legend>Search in:</legend>
<label><input type="radio" value="site:gwern.net" checked /> All</label>
<label><input type="radio" value="site:gwern.net -site:gwern.net/doc/" /> Essays only</label>
<label><input type="radio" value="site:gwern.net/doc/" /> Docs only</label>
</fieldset>

Filter Options

OptionGoogle Site FilterPurpose
Allsite:gwern.netSearches entire gwern.net domain
Essays onlysite:gwern.net -site:gwern.net/doc/Excludes /doc/ directory
Docs onlysite:gwern.net/doc/Only searches /doc/ directory

Default: "All" is checked by default

Site Filter Logic

The radio buttons use Google's site: operator syntax:

  • Positive filter: site:gwern.net/doc/ includes only that path
  • Negative filter: -site:gwern.net/doc/ excludes that path
  • These values would be combined with the user's query via JavaScript

Color Scheme Design

Light Mode (Default)

body {
background-color: #fff;
color: (inherited);
}
.searchform input.search {
background-color: #fff;
color: #000;
outline: 1px solid #ccc;
}
.searchform button {
background-color: #e4e4e4;
outline: 1px solid #ccc;
}

Light mode palette:

  • Background: Pure white (#fff)
  • Text: Black (#000)
  • Borders: Light gray (#ccc)
  • Buttons: Very light gray (#e4e4e4)
  • Hover: Medium gray (#777)

Dark Mode

@media all and (prefers-color-scheme: dark) {
body {
background-color: #161616;
}
.searchform input.search {
background-color: #161616;
color: #f1f1f1;
outline: 1px solid #5c5c5c;
}
.searchform button {
background-color: #404040;
color: #f1f1f1;
}
}

Dark mode palette:

  • Background: Very dark gray (#161616)
  • Text: Off-white (#f1f1f1)
  • Borders: Medium-dark gray (#5c5c5c)
  • Buttons: Dark gray (#404040)
  • Hover: Medium-light gray (#a6a6a6)

Responsive Design

No mobile breakpoints are defined (the only @media rule is the dark-mode prefers-color-scheme block); responsiveness comes from the base flexbox layout and em-based sizing.

Font Sizing

html {
font-size: 18px; /* Base size */
}

Uses rem/em units throughout for scalable, accessible sizing.

Styling Patterns

Focus States

Multi-level focus indication:

.searchform input.search:focus {
outline: 2px solid #777; /* Direct focus */
}
.searchform:focus-within input.search {
outline: 2px solid #ccc; /* Container focus */
}

Uses :focus-within pseudo-class to style parent containers when children are focused, providing clear visual hierarchy.

Appearance Reset

.searchform input.search {
appearance: none;
border: none;
}
.searchform button {
appearance: none;
border: none;
}

Removes default browser styling to ensure consistent cross-browser appearance.

Pointer Events

body {
pointer-events: none;
}
#search-where-selector label,
.searchform {
pointer-events: auto;
}

Purpose: Disables interaction with background/body while enabling only the search UI. This is likely because the page is embedded in a modal/popup where the underlying page should be non-interactive.

JavaScript Integration

The HTML page is mostly markup and CSS. misc.js registers and activates the search widget, while rewrite.js initializes the injected /static/google-search.html iframe, syncs dark-mode media, and attaches the submit handler that fills #searchform-main input.query from the visible query plus selected site filter.

  1. Combine the user's query with the selected site filter
  2. Populate the hidden q input before submission
  3. Handle form submission event

Behavior (actual handler, from rewrite.js):

iframe.contentDocument.querySelector("#searchform-main").addEventListener("submit", (event) => {
event.preventDefault();

let form = event.target;
form.querySelector("input.query").value = searchWhereSelector.querySelector("input[checked]").value
+ " "
+ form.querySelector("input.search").value;
form.submit();
});

(Note the site filter is prepended, not appended, to the user's query.)

Design Philosophy

Minimalism

  • No header, navigation, or footer
  • Pure white/black backgrounds
  • Centered single-purpose interface
  • Minimal decoration

Accessibility

  • Semantic HTML (form, fieldset, legend, label)
  • Focus states clearly defined
  • Required field validation
  • Autocomplete enabled for user convenience
  • Sufficient color contrast in both modes

User Experience

  • Target blank keeps context
  • Radio buttons for clear mutual exclusion
  • Placeholder text provides context
  • Button hover states provide feedback
  • Dark mode respects system preferences

Use Cases

Primary Use: Search Pop-Frame Widget

The minimal design and pointer-events manipulation support the search widget configured by misc.js:

  1. Loaded in a pop-frame - As the /static/google-search.html search widget
  2. Handled by the pop-frame system - Displayed through the same popup/popover infrastructure used for other widgets
  3. Registered by misc.js, enhanced by rewrite.js - Widget creation is in misc.js; query composition happens after injection in rewrite.js

Secondary Use: Direct Access

Can also be accessed directly at /static/google-search.html (the repository root is served as /static/ on the live site) for standalone searching, though without the parent-page JavaScript the site-filter combination is not applied. It is also injected into /ref/ error pages by rewrite.js (via synthesizeIncludeLink("/static/google-search.html", ...)).

Comparison with google-cse.html

Featuregoogle-search.htmlgoogle-cse.html
BackendStandard Google SearchGoogle Custom Search Engine
ResultsOpens in new tabEmbedded in page
CustomizationSite filter radio buttonsNone (configured in CSE panel)
JavaScriptRegistered by misc.js; injected iframe handled by rewrite.jsWidget handles all
StylingFull custom designMinimal widget styling
Dark modeBuilt-in CSSWidget-dependent
ComplexityHigher (form handling)Lower (widget does everything)

Browser Compatibility

Modern features used:

  • :focus-within - CSS3 pseudo-class (Chrome 60+, Firefox 52+, Safari 10.1+)
  • prefers-color-scheme - Media query (Chrome 76+, Firefox 67+, Safari 12.1+)
  • Flexbox - Layout (IE11+)
  • appearance: none - Styling (with prefixes: IE/Edge, Chrome, Firefox, Safari)

Graceful degradation:

  • Focus-within fallback: Direct :focus still works
  • Dark mode fallback: Light mode styles apply
  • Flexbox fallback: Still functional without perfect centering

Performance

  • Small runtime hook - HTML/CSS page with widget registration in misc.js and query handling supplied by rewrite.js after injection
  • Inline styles - No external CSS requests
  • No images - Pure text/color interface
  • Minimal markup - Under 2KB total

Integration Points

Runtime JavaScript

Parent page provides:

  1. Widget registration and activation through misc.js
  2. Form submission handler and query combination through rewrite.js
  3. Popup/popover management through the pop-frame system

Coordinates with:

  • popups.js - Opens/closes search interface
  • extracts.js - Manages embedded content lifecycle
  • transclude.js - May transclude search box into other contexts

See Also
  • google-cse.html - Google Custom Search Engine alternative implementation
  • popups.js - Popup system that displays search interfaces
  • extracts.js - Popup/embed content coordinator
  • content.js - Content type definitions and handlers
  • misc.js - Runtime widget registration for the search pop-frame
  • rewrite.js - Injected search iframe setup and submit override