# Inline Spoiler Shortcode

> Adds a [spoiler] shortcode that blurs a word or sentence until the reader clicks it or presses Enter or Space, and keeps the hidden text from screen readers until it is revealed.

- Type: PHP
- Runs: Run everywhere
- Category: [Content](https://wpide.com/library/category/content/)
- Tags: content, shortcode, accessibility
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/spoiler-shortcode/

## Code

```php
// What screen readers announce (and the tooltip shows) before the spoiler is revealed.
$wpide_spoiler_label = 'Spoiler, select to reveal';

$wpide_spoiler_script = function () {
    ?>
    <script>
    ( function () {
        function reveal( spoiler ) {
            spoiler.classList.add( 'is-revealed' );
            [ 'role', 'aria-label', 'aria-expanded', 'title' ].forEach( function ( name ) {
                spoiler.removeAttribute( name );
            } );
            spoiler.setAttribute( 'tabindex', '-1' );
            var text = spoiler.querySelector( '.wpide-spoiler__text' );
            if ( text ) {
                text.removeAttribute( 'inert' );
            }
        }

        function find( target ) {
            return target && target.closest ? target.closest( '.wpide-spoiler:not(.is-revealed)' ) : null;
        }

        document.addEventListener( 'click', function ( event ) {
            var spoiler = find( event.target );
            if ( spoiler ) {
                event.preventDefault();
                reveal( spoiler );
            }
        } );

        document.addEventListener( 'keydown', function ( event ) {
            var spoiler = find( event.target );
            if ( spoiler && ( event.key === 'Enter' || event.key === ' ' ) ) {
                event.preventDefault();
                reveal( spoiler );
            }
        } );
    } )();
    </script>
    <?php
};

add_shortcode( 'spoiler', function ( $atts, $content = '' ) use ( $wpide_spoiler_label, $wpide_spoiler_script ) {
    static $assets_added = false;

    $atts    = shortcode_atts( array( 'label' => $wpide_spoiler_label ), $atts, 'spoiler' );
    $content = trim( do_shortcode( wp_kses_post( (string) $content ) ) );

    if ( '' === $content ) {
        return '';
    }

    // Feed readers do not run scripts or keep styles, so feeds only get the label.
    if ( is_feed() ) {
        return '[' . esc_html( $atts['label'] ) . ']';
    }

    $style = '';

    if ( ! $assets_added ) {
        $assets_added = true;
        add_action( 'wp_footer', $wpide_spoiler_script );

        // Printed with the first spoiler so the text is never visible before the styles load.
        $style = '<style>'
            . '.wpide-spoiler{border-radius:3px;background:rgba(128,128,128,.25);cursor:pointer;}'
            . '.wpide-spoiler__text{filter:blur(.3em);-webkit-user-select:none;user-select:none;transition:filter .2s ease;}'
            . '.wpide-spoiler:focus-visible{outline:2px solid currentColor;outline-offset:2px;}'
            . '.wpide-spoiler:focus .wpide-spoiler__text,.wpide-spoiler.is-revealed .wpide-spoiler__text{filter:none;-webkit-user-select:auto;user-select:auto;}'
            . '.wpide-spoiler.is-revealed{background:none;cursor:auto;outline:none;}'
            . '@media (prefers-reduced-motion:reduce){.wpide-spoiler__text{transition:none;}}'
            . '</style>';
    }

    return $style . sprintf(
        '<span class="wpide-spoiler" role="button" tabindex="0" aria-expanded="false" aria-label="%1$s" title="%1$s"><span class="wpide-spoiler__text" inert>%2$s</span></span>',
        esc_attr( $atts['label'] ),
        $content
    );
} );
```

## Notes

Example: The killer was [spoiler]the butler[/spoiler]. Change what screen readers announce with [spoiler label="Ending spoiler"]. Feeds show only the label. Without JavaScript the text shows while the spoiler has keyboard focus.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Inline Spoiler Shortcode" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
