Conditional Content Visibility with show-when Web Component

Category: Javascript | May 14, 2026
Authoroddbird
Last UpdateMay 14, 2026
LicenseMIT
Views0 views
Conditional Content Visibility with show-when Web Component

show-when is a Web Component library that shows or hides HTML content based on URL, browser, language, media, CSS feature, and network conditions.

You can use it to create conditional content blocks in edit previews, feature demos, responsive notes, offline messages, and documentation pages.

The library registers two custom elements: <show-when> and <hide-when>. The first element displays content when its conditions match. The second element hides content when its conditions match.

Features:

  • Detects URL query parameters and matches specific name-value pairs.
  • Reacts to URL hash changes in real time.
  • Evaluates CSS feature support at the browser level using the native CSS supports API.
  • Checks active media queries and responds when the viewport state changes.
  • Reads the browser’s preferred language list for locale-based content control.
  • Monitors network connectivity and updates content visibility when the connection changes.
  • Supports matching against any single condition or all conditions at once.
  • Includes a companion element with inverted logic for hiding content when conditions pass.
  • Works as a native custom element in any HTML page.

Use Cases:

  • Display an editor toolbar when the URL contains a ?mode=edit parameter.
  • Show a legacy browser notice only when CSS Grid is not supported.
  • Reveal a language-specific alert based on the browser’s navigator.languages.
  • Hide a live chat widget while the user is offline.
  • Combine multiple signals: show a debug panel when #debug is in the URL and the viewport is wider than 1024px.

How to use it:

1. Install the package with NPM and import it in your JavaScript entry file:

# NPM
$ npm install @oddbird/show-when
import '@oddbird/show-when';

2. You can also load the library from a CDN for fast prototyping.

<script type="module" src="https://www.unpkg.com/@oddbird/show-when/show-when.js"></script>

3. Show content based on a URL parameter. The has-param attribute reads window.location.search on load and toggles the hidden attribute on the element.

<!-- This toolbar is visible by default.
     It hides when '?mode=preview' is absent from the URL. -->
<show-when has-param="mode=preview">
  <div class="preview-toolbar">
    <button>Edit Layout</button>
    <button>Toggle Grid</button>
  </div>
</show-when>

3. Show content based on URL hash. has-hash compares location.hash against the given value. The component listens to hashchange events and re-evaluates on every navigation, making it a clean fit for tab-style or slide-style interfaces.

<!-- This section appears only when the URL hash is #pricing -->
<show-when has-hash="pricing">
  <section class="pricing-detail">
    <h2>Plan Comparison</h2>
    <p>See the full pricing breakdown below.</p>
  </section>
</show-when>

4. Show content based on CSS feature support. has-support passes its value directly to CSS.supports(). This is where progressive enhancement gets genuinely useful. Rather than writing JavaScript feature checks by hand, declare the condition in HTML.

The hidden attribute on the element sets the initial visibility state before JavaScript runs. Add it when you want content hidden by default and revealed when conditions pass. Leave it off when you want the opposite: visible by default and hidden when conditions fail.

<!-- Hidden by default.
     Becomes visible in browsers that support the :has() selector. -->
<show-when has-support="selector(:has(+ *))" hidden>
  <p class="compat-note">
    Your browser supports the :has() selector. Advanced layout styles are active.
  </p>
</show-when>

5. Show content based on network status. has-network checks navigator.onLine and listens to the browser’s online and offline events. Content updates automatically as connectivity changes.

<!-- Visible only when the user is offline -->
<show-when has-network="offline">
  <div class="offline-banner" role="alert">
    You're offline. Some features may be unavailable.
  </div>
</show-when>
<!-- Visible only when the user is connected -->
<show-when has-network="online">
  <div class="sync-prompt">Connection restored. Data is syncing.</div>
</show-when>

6. Match any condition with match-any. All specified conditions must pass by default for the component to show content. Add match-any to change that behavior: the component shows its content when at least one condition passes.

<!-- Shows the admin panel if either the hash is #admin-panel
     OR the query parameter override=true is set -->
<show-when has-hash="admin-panel" has-param="override=true" match-any>
  <nav class="admin-controls">
    <a href="/settings">Settings</a>
    <a href="/users">Users</a>
  </nav>
</show-when>

7. hide-when inverts all condition logic. It hides content when conditions match and shows it when they don’t. The attribute API is identical to show-when.

<!-- The notice is visible by default.
     It disappears once the URL hash reaches #complete. -->
<hide-when has-hash="complete">
  <p class="progress-notice">Complete step 3 to continue.</p>
</hide-when>

8. All available attributes:

  • has-param (string): Checks for a URL query parameter. Pass key to check for presence, or key=value to match a specific value. The component re-evaluates on page load.
  • has-hash (string): Compares location.hash against the given string value. The component re-evaluates on every hashchange event.
  • has-media (string): Accepts a media query string. The component evaluates it against window.matchMedia and re-evaluates when the viewport state changes.
  • has-support (string): Passes the value to CSS.supports(). The component evaluates this once at connection time.
  • has-lang (string): Checks navigator.languages for an exact BCP 47 tag match, such as fr-FR or en-US.
  • has-network (string): Accepts online or offline. The component checks navigator.onLine and listens to network events in real time.
  • match-any (boolean): When present, the component shows its content when at least one specified condition passes. The default behavior requires all conditions to pass.

FAQs:

Q: How do I match a URL parameter against a specific value?
A: Use has-param="key=value". The component splits the string on = and calls URLSearchParams.has(key, value). Both the parameter name and value must match exactly.

Q: Content flashes before the component hides it. How do I prevent this?
A: Add the hidden attribute directly to the <show-when> tag in your HTML. The component removes it when conditions pass. This sets the correct initial state before JavaScript runs, so there’s no visible flash.

Q: Does match-any apply to all attributes on the element?
A: Yes. The component evaluates only the condition attributes present on the element. With match-any, the component shows its content when any one of those evaluated conditions returns true.

Q: Does has-support update reactively like has-media or has-network?
A: No. CSS feature support does not change after page load. The component evaluates has-support once when it connects to the DOM. The component sets up reactive listeners only for has-hash and has-network events, and for media query changes via MediaQueryList.

Q: Can I use show-when in React or Vue?
A: Yes. Import the module once, then place <show-when> or <hide-when> in your component template.

You Might Be Interested In:


Leave a Reply