<content-warning>

A web component for block and inline content warnings. See the README for installation and API documentation.

Block Content Warning

A block-level content warning that overlays the entire content area.

Single Warning Type

Click or press Enter to reveal the content.

<content-warning type="violence" hidden>
  <p>This content contains graphic violence.</p>
  <p>Lorem ipsum dolor sit amet...</p>
</content-warning>

Multiple Warning Types

Use space-separated types for multiple warning categories.

<content-warning type="violence spoilers nsfw" hidden>
  <p>Contains violence, spoilers, and mature content.</p>
</content-warning>

Inline Content Warning

An inline content warning that works within text flow.

Inline Usage

Click the warning to reveal the hidden text.

<p>
  The character dies in
  <content-warning type="spoilers" inline>
    episode 5
  </content-warning>.
</p>

The character dies in episode 5.

Multiple Inline Warnings

You can have multiple inline warnings in one sentence.

<p>
  <content-warning type="spoilers" inline>Jon</content-warning>
  meets <content-warning type="spoilers" inline>Daenerys</content-warning>
  in season 7.
</p>

Jon meets Daenerys in season 7.

Content Hiding Modes

The component offers two modes for hiding content, each with different trade-offs.

Default Mode (Reader Mode Safe)

Content is truly hidden using hidden and inert attributes. This mode ensures content is not extracted by Reader Mode and is completely hidden from screen readers until revealed.

<content-warning type="sensitive content" hidden>
  <p>This content is completely hidden.</p>
  <p>Reader Mode won't extract it.</p>
</content-warning>

Blur Mode (Visual Only)

Content is visually obscured with CSS blur but remains in the DOM. Uses aria-hidden="true" to hide from screen readers. Not guaranteed to be hidden from Reader Mode.

<content-warning type="spoilers" blur hidden>
  <p>This content is blurred visually.</p>
  <p>May be visible in Reader Mode.</p>
</content-warning>

Custom Blur Amount

Adjust the blur intensity using the --content-warning-blur-amount CSS custom property.

<style>
  .light-blur {
    --content-warning-blur-amount: 5px;
  }
  .heavy-blur {
    --content-warning-blur-amount: 20px;
  }
</style>

<content-warning type="spoilers" blur class="light-blur">
  <p>Lightly blurred (5px)</p>
</content-warning>

<content-warning type="spoilers" blur class="heavy-blur">
  <p>Heavily blurred (20px)</p>
</content-warning>


Comparison

Side-by-side comparison of both modes:

Default (Hidden)

Blur Mode

Custom Styling

Customize the appearance using CSS Shadow Parts.

Custom Colors

<style>
  .custom-warning::part(overlay) {
    background: rgba(139, 0, 0, 0.95);
  }
  .custom-warning::part(button) {
    color: #fff;
    border: 3px solid #ff6b6b;
    padding: 2rem;
    background: rgba(0, 0, 0, 0.5);
    border-radius: 0.5rem;
  }
</style>

<content-warning type="horror" class="custom-warning">
  <p>Scary content here!</p>
</content-warning>

This is scary content with custom styling!

The dark red background and red border make it stand out.

Styled Button Text

Style the button text and appearance.

<style>
  .styled-parts::part(button) {
    text-transform: uppercase;
    letter-spacing: 0.15em;
    font-weight: 900;
    background: #333;
    border-radius: 0.5rem;
  }
</style>

<content-warning type="mature" class="styled-parts">
  <p>Mature content here.</p>
</content-warning>

Event Handling

Listen for the revealed event to track user interactions.

Tracking Reveals

<content-warning type="spoilers" id="tracked">
  <p>Secret content!</p>
</content-warning>
<p id="status">Status: Hidden</p>

<script>
  document.getElementById('tracked')
    .addEventListener('content-warning:revealed', (e) => {
      document.getElementById('status').textContent =
        `Status: Revealed (${e.detail.type})`;
    });
</script>

Status: Hidden

Internationalization (i18n)

Customize the button label using label-prefix and label-suffix attributes to support different languages. Each label part can be styled individually using CSS Shadow Parts.

Spanish Translation

<style>
  .spanish-warning::part(label-type) {
    font-style: italic;
    text-transform: capitalize;
  }
</style>

<content-warning
  type="violencia gore"
  label-prefix="Advertencia de Contenido"
  label-suffix="Haz clic para revelar"
  class="spanish-warning"
>
  <img src="..." alt="...">
</content-warning>

French Translation

<style>
  .french-warning::part(label-prefix) {
    font-weight: bold;
    color: #ffeb3b;
  }
  .french-warning::part(label-suffix) {
    font-size: 0.875em;
  }
</style>

<content-warning
  type="contenu sensible"
  label-prefix="Avertissement"
  label-suffix="Cliquez pour révéler"
  class="french-warning"
>
  <p>Contenu en français...</p>
</content-warning>

Ce contenu pourrait être considéré comme sensible par certains utilisateurs. Veuillez faire preuve de discrétion.

No Suffix

Set label-suffix="false" to hide the suffix entirely.

<content-warning
  type="graphic content"
  label-suffix="false"
>
  <p>Content here</p>
</content-warning>

This warning has no suffix text - just the prefix and type.

API Reference

For complete documentation of attributes, events, CSS custom properties, and browser support, see the README.