25% off ProSNIPC25OFF

FAQ Accordion

Adds a [sc_faq q="Question"] shortcode that renders an animated, accessible FAQ item — stack multiple for a full FAQ list.

Module3 parts · by SnipCraft

PHPShortcode

php
<?php
if ( ! function_exists( 'scseed_faq_shortcode' ) ) {
    function scseed_faq_shortcode( $atts, $content = '' ) {
        $atts     = shortcode_atts( [ 'q' => '' ], $atts, 'sc_faq' );
        if ( empty( $atts['q'] ) ) {
            return '';
        }
        $id       = 'scseed-faq-' . wp_unique_id();
        $question = esc_html( $atts['q'] );
        $answer   = wp_kses_post( do_shortcode( $content ) );
        $out      = '<div class="scseed-faq-item">';
        $out     .= '<button class="scseed-faq-btn" type="button" aria-expanded="false" aria-controls="' . esc_attr( $id ) . '">';
        $out     .= '<span class="scseed-faq-q">' . $question . '</span>';
        $out     .= '<span class="scseed-faq-icon" aria-hidden="true"></span>';
        $out     .= '</button>';
        $out     .= '<div class="scseed-faq-panel" id="' . esc_attr( $id ) . '" hidden>';
        $out     .= '<div class="scseed-faq-a">' . $answer . '</div>';
        $out     .= '</div>';
        $out     .= '</div>';
        return $out;
    }
}
add_shortcode( 'sc_faq', 'scseed_faq_shortcode' );

CSSStyles

css
.scseed-faq-item {
    border: 1px solid #e5e7eb;
    border-radius: 6px;
    margin-bottom: 8px;
    overflow: hidden;
}
.scseed-faq-btn {
    width: 100%;
    background: none;
    border: none;
    padding: 14px 16px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    cursor: pointer;
    font-size: 15px;
    font-weight: 600;
    text-align: left;
    color: inherit;
    gap: 12px;
}
.scseed-faq-btn:hover { background: #f9fafb; }
.scseed-faq-icon {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    position: relative;
}
.scseed-faq-icon::before,
.scseed-faq-icon::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    background: currentColor;
    border-radius: 2px;
    transition: transform 0.2s;
}
.scseed-faq-icon::before { width: 14px; height: 2px; transform: translate(-50%, -50%); }
.scseed-faq-icon::after  { width: 2px; height: 14px; transform: translate(-50%, -50%); }
.scseed-faq-btn[aria-expanded="true"] .scseed-faq-icon::after {
    transform: translate(-50%, -50%) rotate(90deg);
}
.scseed-faq-panel { background: #fff; }
.scseed-faq-a {
    padding: 0 16px 14px;
    font-size: 15px;
    line-height: 1.65;
    color: #444;
}

JavaScriptScript

js
(function () {
    function initFaq() {
        document.querySelectorAll('.scseed-faq-btn').forEach(function (btn) {
            if (btn.dataset.scFaqInit) return;
            btn.dataset.scFaqInit = '1';
            btn.addEventListener('click', function () {
                var expanded = btn.getAttribute('aria-expanded') === 'true';
                var panelId  = btn.getAttribute('aria-controls');
                var panel    = panelId ? document.getElementById(panelId) : null;
                if (!panel) return;
                btn.setAttribute('aria-expanded', expanded ? 'false' : 'true');
                panel.hidden = expanded;
            });
        });
    }
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initFaq);
    } else {
        initFaq();
    }
})();
#ux#shortcode#faq#accordion