25% off ProSNIPC25OFF

Read-More Content Expander

Collapses long content to a fixed pixel height with a gradient fade, then expands smoothly on click — use [scseed_readmore height="200"]...[/scseed_readmore].

Module3 parts · by SnipCraft

PHPLogic

php
<?php
// Shortcode: [scseed_readmore height="200" more="Read more" less="Show less"]...[/scseed_readmore]
add_shortcode( 'scseed_readmore', 'scseed_readmore_shortcode' );
function scseed_readmore_shortcode( $atts, $content = '' ) {
    static $scseed_rm_idx = 0;
    $scseed_rm_idx++;
    $a = shortcode_atts( array(
        'height' => 200,
        'more'   => __( 'Read more', 'scseed' ),
        'less'   => __( 'Show less', 'scseed' ),
    ), $atts );
    $uid    = 'scseed-rm-' . absint( $scseed_rm_idx );
    $height = absint( $a['height'] );
    $inner  = do_shortcode( wp_kses_post( $content ?? '' ) );
    return '<div class="scseed-rm-wrap" id="' . esc_attr( $uid ) . '"'
        . ' style="--scseed-rm-h:' . $height . 'px"'
        . ' data-more="' . esc_attr( $a['more'] ) . '"'
        . ' data-less="' . esc_attr( $a['less'] ) . '">'
        . '<div class="scseed-rm-inner">' . $inner . '</div>'
        . '<div class="scseed-rm-fade" aria-hidden="true"></div>'
        . '<button class="scseed-rm-btn" type="button" aria-expanded="false"'
        . ' aria-controls="' . esc_attr( $uid ) . '">'
        . esc_html( $a['more'] ) . '</button>'
        . '</div>';
}

CSSStyles

css
.scseed-rm-wrap {
    position: relative;
    margin: 1rem 0;
}
.scseed-rm-inner {
    max-height: var(--scseed-rm-h, 200px);
    overflow: hidden;
    transition: max-height 0.4s ease;
}
.scseed-rm-wrap.scseed-rm-open .scseed-rm-inner {
    max-height: 9999px;
}
.scseed-rm-fade {
    position: absolute;
    bottom: 36px;
    left: 0;
    right: 0;
    height: 60px;
    background: linear-gradient(to bottom, transparent, #fff);
    pointer-events: none;
    transition: opacity 0.3s;
}
.scseed-rm-wrap.scseed-rm-open .scseed-rm-fade { opacity: 0; }
.scseed-rm-btn {
    display: block;
    width: 100%;
    margin-top: 4px;
    padding: 0.45rem 1rem;
    background: none;
    border: 1px solid #d0d0d0;
    border-radius: 5px;
    font-size: 0.875rem;
    color: #555;
    cursor: pointer;
    transition: background 0.2s, color 0.2s;
    text-align: center;
}
.scseed-rm-btn:hover { background: #f5f5f5; color: #222; }

JavaScriptScript

js
(function() {
    'use strict';
    document.addEventListener('DOMContentLoaded', function() {
        document.addEventListener('click', function(e) {
            var btn = e.target.closest
                ? e.target.closest('.scseed-rm-btn')
                : null;
            if ( ! btn ) { return; }
            var wrap = btn.closest('.scseed-rm-wrap');
            if ( ! wrap ) { return; }
            var isOpen = wrap.classList.contains('scseed-rm-open');
            wrap.classList.toggle('scseed-rm-open', ! isOpen);
            btn.setAttribute('aria-expanded', String( ! isOpen ));
            btn.textContent = isOpen
                ? ( wrap.dataset.more || 'Read more' )
                : ( wrap.dataset.less || 'Show less' );
        });
    });
}());
#ux#content#shortcode#toggle#read-more