Category · Interactive Difficulty Level · Intermediate Published on · January 20, 2025

Accordion FAQ Component

A classic accordion-style FAQ component with smooth animations and expandable sections

#faq #accordion #expandable #questions #answers

Responsive Design

Yes

Dark Mode Support

No

lines

240

Browser Compatibility

No

Live Preview

Interact with the component without leaving the page.

600px

Accordion FAQ Component

A classic accordion-style FAQ component featuring smooth animations, expandable sections, and an intuitive user interface for displaying frequently asked questions.

Features

  • Smooth Animations: CSS transitions for opening/closing sections
  • Single/Multiple Expand: Option to allow one or multiple sections open
  • Keyboard Navigation: Full keyboard accessibility support
  • Search Functionality: Built-in search to filter questions
  • Responsive Design: Works perfectly on all device sizes
  • Icon Indicators: Visual cues for expanded/collapsed states
  • Customizable Styling: Easy to theme and customize
  • Auto-scroll: Automatically scrolls to opened sections

HTML Structure

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Accordion FAQ Component</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="faq-container">
        <!-- Header -->
        <div class="faq-header">
            <h1>Frequently Asked Questions</h1>
            <p>Find answers to common questions about our services</p>
            
            <!-- Search Box -->
            <div class="search-container">
                <input type="text" id="faqSearch" placeholder="Search questions..." class="search-input">
                <svg class="search-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                    <circle cx="11" cy="11" r="8"></circle>
                    <path d="m21 21-4.35-4.35"></path>
                </svg>
            </div>
            
            <!-- Controls -->
            <div class="faq-controls">
                <button id="expandAll" class="control-btn">
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                        <polyline points="6,9 12,15 18,9"></polyline>
                    </svg>
                    Expand All
                </button>
                <button id="collapseAll" class="control-btn">
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                        <polyline points="18,15 12,9 6,15"></polyline>
                    </svg>
                    Collapse All
                </button>
            </div>
        </div>

        <!-- FAQ Accordion -->
        <div class="faq-accordion" id="faqAccordion">
            <div class="faq-item" data-category="general">
                <div class="faq-question" tabindex="0" role="button" aria-expanded="false">
                    <h3>What is your return policy?</h3>
                    <div class="faq-icon">
                        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                            <line x1="12" y1="5" x2="12" y2="19"></line>
                            <line x1="5" y1="12" x2="19" y2="12"></line>
                        </svg>
                    </div>
                </div>
                <div class="faq-answer">
                    <div class="faq-content">
                        <p>We offer a 30-day return policy for all unused items in their original packaging. Simply contact our customer service team to initiate a return, and we'll provide you with a prepaid shipping label.</p>
                        <ul>
                            <li>Items must be unused and in original condition</li>
                            <li>Original packaging required</li>
                            <li>Refund processed within 5-7 business days</li>
                        </ul>
                    </div>
                </div>
            </div>

            <div class="faq-item" data-category="shipping">
                <div class="faq-question" tabindex="0" role="button" aria-expanded="false">
                    <h3>How long does shipping take?</h3>
                    <div class="faq-icon">
                        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                            <line x1="12" y1="5" x2="12" y2="19"></line>
                            <line x1="5" y1="12" x2="19" y2="12"></line>
                        </svg>
                    </div>
                </div>
                <div class="faq-answer">
                    <div class="faq-content">
                        <p>Shipping times vary depending on your location and selected shipping method:</p>
                        <div class="shipping-table">
                            <div class="shipping-row">
                                <span class="shipping-method">Standard Shipping</span>
                                <span class="shipping-time">5-7 business days</span>
                            </div>
                            <div class="shipping-row">
                                <span class="shipping-method">Express Shipping</span>
                                <span class="shipping-time">2-3 business days</span>
                            </div>
                            <div class="shipping-row">
                                <span class="shipping-method">Overnight Shipping</span>
                                <span class="shipping-time">1 business day</span>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="faq-item" data-category="payment">
                <div class="faq-question" tabindex="0" role="button" aria-expanded="false">
                    <h3>What payment methods do you accept?</h3>
                    <div class="faq-icon">
                        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                            <line x1="12" y1="5" x2="12" y2="19"></line>
                            <line x1="5" y1="12" x2="19" y2="12"></line>
                        </svg>
                    </div>
                </div>
                <div class="faq-answer">
                    <div class="faq-content">
                        <p>We accept all major payment methods to make your shopping experience convenient:</p>
                        <div class="payment-methods">
                            <div class="payment-item">
                                <strong>Credit Cards:</strong> Visa, MasterCard, American Express, Discover
                            </div>
                            <div class="payment-item">
                                <strong>Digital Wallets:</strong> PayPal, Apple Pay, Google Pay
                            </div>
                            <div class="payment-item">
                                <strong>Bank Transfer:</strong> ACH and wire transfers accepted
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="faq-item" data-category="account">
                <div class="faq-question" tabindex="0" role="button" aria-expanded="false">
                    <h3>How do I create an account?</h3>
                    <div class="faq-icon">
                        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                            <line x1="12" y1="5" x2="12" y2="19"></line>
                            <line x1="5" y1="12" x2="19" y2="12"></line>
                        </svg>
                    </div>
                </div>
                <div class="faq-answer">
                    <div class="faq-content">
                        <p>Creating an account is quick and easy! Follow these simple steps:</p>
                        <ol>
                            <li>Click the "Sign Up" button in the top right corner</li>
                            <li>Enter your email address and create a secure password</li>
                            <li>Verify your email address by clicking the link we send you</li>
                            <li>Complete your profile with your shipping information</li>
                            <li>Start shopping with your new account!</li>
                        </ol>
                        <p><strong>Benefits of having an account:</strong></p>
                        <ul>
                            <li>Faster checkout process</li>
                            <li>Order history and tracking</li>
                            <li>Exclusive member discounts</li>
                            <li>Wishlist functionality</li>
                        </ul>
                    </div>
                </div>
            </div>

            <div class="faq-item" data-category="support">
                <div class="faq-question" tabindex="0" role="button" aria-expanded="false">
                    <h3>How can I contact customer support?</h3>
                    <div class="faq-icon">
                        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                            <line x1="12" y1="5" x2="12" y2="19"></line>
                            <line x1="5" y1="12" x2="19" y2="12"></line>
                        </svg>
                    </div>
                </div>
                <div class="faq-answer">
                    <div class="faq-content">
                        <p>We're here to help! You can reach our customer support team through multiple channels:</p>
                        <div class="contact-methods">
                            <div class="contact-item">
                                <div class="contact-icon">📧</div>
                                <div class="contact-info">
                                    <strong>Email Support</strong>
                                    <p>support@example.com</p>
                                    <span>Response within 24 hours</span>
                                </div>
                            </div>
                            <div class="contact-item">
                                <div class="contact-icon">📞</div>
                                <div class="contact-info">
                                    <strong>Phone Support</strong>
                                    <p>1-800-123-4567</p>
                                    <span>Mon-Fri 9AM-6PM EST</span>
                                </div>
                            </div>
                            <div class="contact-item">
                                <div class="contact-icon">💬</div>
                                <div class="contact-info">
                                    <strong>Live Chat</strong>
                                    <p>Available on our website</p>
                                    <span>Mon-Fri 9AM-6PM EST</span>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="faq-item" data-category="general">
                <div class="faq-question" tabindex="0" role="button" aria-expanded="false">
                    <h3>Do you offer international shipping?</h3>
                    <div class="faq-icon">
                        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                            <line x1="12" y1="5" x2="12" y2="19"></line>
                            <line x1="5" y1="12" x2="19" y2="12"></line>
                        </svg>
                    </div>
                </div>
                <div class="faq-answer">
                    <div class="faq-content">
                        <p>Yes! We ship to over 50 countries worldwide. International shipping rates and delivery times vary by destination.</p>
                        <div class="international-info">
                            <div class="info-section">
                                <h4>Shipping Costs</h4>
                                <p>Calculated at checkout based on weight and destination</p>
                            </div>
                            <div class="info-section">
                                <h4>Delivery Time</h4>
                                <p>7-21 business days depending on location</p>
                            </div>
                            <div class="info-section">
                                <h4>Customs & Duties</h4>
                                <p>Customer responsibility, varies by country</p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- No Results Message -->
        <div class="no-results" id="noResults" style="display: none;">
            <div class="no-results-icon">
                <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                    <circle cx="11" cy="11" r="8"></circle>
                    <path d="m21 21-4.35-4.35"></path>
                </svg>
            </div>
            <h3>No questions found</h3>
            <p>Try adjusting your search terms or browse all questions above.</p>
        </div>
    </div>

    <script src="script.js"></script>
</body>
</html>

CSS Styles

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    min-height: 100vh;
    padding: 20px;
}

.faq-container {
    max-width: 800px;
    margin: 0 auto;
    background: white;
    border-radius: 16px;
    box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
    overflow: hidden;
}

/* Header Styles */
.faq-header {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    padding: 40px 30px;
    text-align: center;
}

.faq-header h1 {
    font-size: 2.5rem;
    font-weight: 700;
    margin-bottom: 8px;
}

.faq-header p {
    font-size: 1.1rem;
    opacity: 0.9;
    margin-bottom: 30px;
}

/* Search Container */
.search-container {
    position: relative;
    max-width: 400px;
    margin: 0 auto 20px;
}

.search-input {
    width: 100%;
    padding: 12px 20px 12px 50px;
    border: none;
    border-radius: 25px;
    font-size: 16px;
    background: rgba(255, 255, 255, 0.2);
    color: white;
    backdrop-filter: blur(10px);
    transition: all 0.3s ease;
}

.search-input::placeholder {
    color: rgba(255, 255, 255, 0.7);
}

.search-input:focus {
    outline: none;
    background: rgba(255, 255, 255, 0.3);
    box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.2);
}

.search-icon {
    position: absolute;
    left: 18px;
    top: 50%;
    transform: translateY(-50%);
    color: rgba(255, 255, 255, 0.7);
}

/* Controls */
.faq-controls {
    display: flex;
    gap: 12px;
    justify-content: center;
    flex-wrap: wrap;
}

.control-btn {
    background: rgba(255, 255, 255, 0.2);
    border: none;
    color: white;
    padding: 8px 16px;
    border-radius: 20px;
    font-size: 14px;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 6px;
    transition: all 0.3s ease;
    backdrop-filter: blur(10px);
}

.control-btn:hover {
    background: rgba(255, 255, 255, 0.3);
    transform: translateY(-1px);
}

/* Accordion Styles */
.faq-accordion {
    padding: 0;
}

.faq-item {
    border-bottom: 1px solid #e2e8f0;
    transition: all 0.3s ease;
}

.faq-item:last-child {
    border-bottom: none;
}

.faq-item.active {
    background: #f8fafc;
}

.faq-question {
    padding: 24px 30px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    transition: all 0.3s ease;
    outline: none;
}

.faq-question:hover {
    background: #f8fafc;
}

.faq-question:focus {
    background: #f1f5f9;
    box-shadow: inset 0 0 0 2px #667eea;
}

.faq-question h3 {
    font-size: 1.1rem;
    font-weight: 600;
    color: #1e293b;
    margin: 0;
    flex: 1;
    text-align: left;
}

.faq-icon {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: #667eea;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s ease;
    flex-shrink: 0;
    margin-left: 16px;
}

.faq-icon svg {
    color: white;
    transition: transform 0.3s ease;
}

.faq-item.active .faq-icon {
    background: #4f46e5;
    transform: rotate(45deg);
}

.faq-answer {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.3s ease;
}

.faq-item.active .faq-answer {
    max-height: 1000px;
}

.faq-content {
    padding: 0 30px 24px;
    color: #64748b;
    line-height: 1.6;
}

.faq-content p {
    margin-bottom: 16px;
}

.faq-content ul,
.faq-content ol {
    margin: 16px 0;
    padding-left: 20px;
}

.faq-content li {
    margin-bottom: 8px;
}

/* Shipping Table */
.shipping-table {
    background: #f8fafc;
    border-radius: 8px;
    padding: 16px;
    margin: 16px 0;
}

.shipping-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 0;
    border-bottom: 1px solid #e2e8f0;
}

.shipping-row:last-child {
    border-bottom: none;
}

.shipping-method {
    font-weight: 500;
    color: #374151;
}

.shipping-time {
    color: #667eea;
    font-weight: 500;
}

/* Payment Methods */
.payment-methods {
    margin: 16px 0;
}

.payment-item {
    background: #f8fafc;
    padding: 12px 16px;
    border-radius: 8px;
    margin-bottom: 8px;
    border-left: 4px solid #667eea;
}

.payment-item strong {
    color: #374151;
    display: block;
    margin-bottom: 4px;
}

/* Contact Methods */
.contact-methods {
    margin: 20px 0;
}

.contact-item {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    padding: 16px;
    background: #f8fafc;
    border-radius: 12px;
    margin-bottom: 12px;
}

.contact-icon {
    font-size: 24px;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: white;
    border-radius: 50%;
    flex-shrink: 0;
}

.contact-info strong {
    color: #374151;
    display: block;
    margin-bottom: 4px;
}

.contact-info p {
    margin: 0;
    color: #667eea;
    font-weight: 500;
}

.contact-info span {
    font-size: 14px;
    color: #64748b;
}

/* International Info */
.international-info {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 16px;
    margin: 20px 0;
}

.info-section {
    background: #f8fafc;
    padding: 16px;
    border-radius: 8px;
    border-left: 4px solid #667eea;
}

.info-section h4 {
    color: #374151;
    margin-bottom: 8px;
    font-size: 16px;
}

.info-section p {
    margin: 0;
    font-size: 14px;
}

/* No Results */
.no-results {
    text-align: center;
    padding: 60px 30px;
    color: #64748b;
}

.no-results-icon {
    margin-bottom: 20px;
    opacity: 0.5;
}

.no-results h3 {
    font-size: 1.5rem;
    margin-bottom: 8px;
    color: #374151;
}

.no-results p {
    font-size: 1rem;
}

/* Animations */
@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(10px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.faq-item {
    animation: fadeIn 0.3s ease;
}

/* Responsive Design */
@media (max-width: 768px) {
    body {
        padding: 10px;
    }
    
    .faq-container {
        border-radius: 12px;
    }
    
    .faq-header {
        padding: 30px 20px;
    }
    
    .faq-header h1 {
        font-size: 2rem;
    }
    
    .faq-question {
        padding: 20px;
    }
    
    .faq-content {
        padding: 0 20px 20px;
    }
    
    .faq-question h3 {
        font-size: 1rem;
    }
    
    .contact-item {
        flex-direction: column;
        text-align: center;
    }
    
    .international-info {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 480px) {
    .faq-header h1 {
        font-size: 1.75rem;
    }
    
    .faq-controls {
        flex-direction: column;
        align-items: center;
    }
    
    .control-btn {
        width: 100%;
        max-width: 200px;
        justify-content: center;
    }
}

JavaScript Functionality

class AccordionFAQ {
    constructor() {
        this.accordion = document.getElementById('faqAccordion');
        this.searchInput = document.getElementById('faqSearch');
        this.expandAllBtn = document.getElementById('expandAll');
        this.collapseAllBtn = document.getElementById('collapseAll');
        this.noResults = document.getElementById('noResults');
        this.faqItems = Array.from(document.querySelectorAll('.faq-item'));
        
        this.init();
    }
    
    init() {
        this.bindEvents();
        this.setupKeyboardNavigation();
    }
    
    bindEvents() {
        // Accordion click events
        this.accordion.addEventListener('click', (e) => {
            const question = e.target.closest('.faq-question');
            if (question) {
                this.toggleItem(question.parentElement);
            }
        });
        
        // Search functionality
        this.searchInput.addEventListener('input', (e) => {
            this.filterQuestions(e.target.value);
        });
        
        // Control buttons
        this.expandAllBtn.addEventListener('click', () => this.expandAll());
        this.collapseAllBtn.addEventListener('click', () => this.collapseAll());
    }
    
    setupKeyboardNavigation() {
        this.accordion.addEventListener('keydown', (e) => {
            const question = e.target.closest('.faq-question');
            if (!question) return;
            
            switch (e.key) {
                case 'Enter':
                case ' ':
                    e.preventDefault();
                    this.toggleItem(question.parentElement);
                    break;
                case 'ArrowDown':
                    e.preventDefault();
                    this.focusNext(question);
                    break;
                case 'ArrowUp':
                    e.preventDefault();
                    this.focusPrevious(question);
                    break;
                case 'Home':
                    e.preventDefault();
                    this.focusFirst();
                    break;
                case 'End':
                    e.preventDefault();
                    this.focusLast();
                    break;
            }
        });
    }
    
    toggleItem(item) {
        const isActive = item.classList.contains('active');
        const question = item.querySelector('.faq-question');
        
        if (isActive) {
            this.closeItem(item);
        } else {
            this.openItem(item);
        }
        
        // Update ARIA attributes
        question.setAttribute('aria-expanded', !isActive);
        
        // Auto-scroll to opened item
        if (!isActive) {
            setTimeout(() => {
                item.scrollIntoView({
                    behavior: 'smooth',
                    block: 'nearest'
                });
            }, 150);
        }
    }
    
    openItem(item) {
        item.classList.add('active');
        const answer = item.querySelector('.faq-answer');
        const content = item.querySelector('.faq-content');
        
        // Set max-height to content height for smooth animation
        answer.style.maxHeight = content.scrollHeight + 'px';
        
        // Add animation class
        item.style.animation = 'fadeIn 0.3s ease';
    }
    
    closeItem(item) {
        item.classList.remove('active');
        const answer = item.querySelector('.faq-answer');
        answer.style.maxHeight = '0';
    }
    
    expandAll() {
        const visibleItems = this.faqItems.filter(item => 
            item.style.display !== 'none'
        );
        
        visibleItems.forEach((item, index) => {
            setTimeout(() => {
                if (!item.classList.contains('active')) {
                    this.openItem(item);
                    const question = item.querySelector('.faq-question');
                    question.setAttribute('aria-expanded', 'true');
                }
            }, index * 100);
        });
    }
    
    collapseAll() {
        const activeItems = this.faqItems.filter(item => 
            item.classList.contains('active')
        );
        
        activeItems.forEach((item, index) => {
            setTimeout(() => {
                this.closeItem(item);
                const question = item.querySelector('.faq-question');
                question.setAttribute('aria-expanded', 'false');
            }, index * 50);
        });
    }
    
    filterQuestions(searchTerm) {
        const term = searchTerm.toLowerCase().trim();
        let visibleCount = 0;
        
        this.faqItems.forEach(item => {
            const question = item.querySelector('h3').textContent.toLowerCase();
            const answer = item.querySelector('.faq-content').textContent.toLowerCase();
            
            const matches = question.includes(term) || answer.includes(term);
            
            if (matches || term === '') {
                item.style.display = 'block';
                visibleCount++;
                
                // Highlight search terms
                if (term !== '') {
                    this.highlightSearchTerm(item, term);
                } else {
                    this.removeHighlights(item);
                }
            } else {
                item.style.display = 'none';
                // Close hidden items
                if (item.classList.contains('active')) {
                    this.closeItem(item);
                }
            }
        });
        
        // Show/hide no results message
        if (visibleCount === 0 && term !== '') {
            this.noResults.style.display = 'block';
            this.accordion.style.display = 'none';
        } else {
            this.noResults.style.display = 'none';
            this.accordion.style.display = 'block';
        }
    }
    
    highlightSearchTerm(item, term) {
        const question = item.querySelector('h3');
        const content = item.querySelector('.faq-content');
        
        // Simple highlighting (in a real app, use a more robust solution)
        const highlightText = (element) => {
            const text = element.textContent;
            const regex = new RegExp(`(${term})`, 'gi');
            const highlightedText = text.replace(regex, '<mark>$1</mark>');
            
            if (text !== highlightedText) {
                element.innerHTML = highlightedText;
            }
        };
        
        highlightText(question);
    }
    
    removeHighlights(item) {
        const marks = item.querySelectorAll('mark');
        marks.forEach(mark => {
            mark.outerHTML = mark.textContent;
        });
    }
    
    focusNext(currentQuestion) {
        const questions = Array.from(document.querySelectorAll('.faq-question'));
        const visibleQuestions = questions.filter(q => 
            q.closest('.faq-item').style.display !== 'none'
        );
        const currentIndex = visibleQuestions.indexOf(currentQuestion);
        const nextIndex = (currentIndex + 1) % visibleQuestions.length;
        visibleQuestions[nextIndex].focus();
    }
    
    focusPrevious(currentQuestion) {
        const questions = Array.from(document.querySelectorAll('.faq-question'));
        const visibleQuestions = questions.filter(q => 
            q.closest('.faq-item').style.display !== 'none'
        );
        const currentIndex = visibleQuestions.indexOf(currentQuestion);
        const prevIndex = currentIndex === 0 ? visibleQuestions.length - 1 : currentIndex - 1;
        visibleQuestions[prevIndex].focus();
    }
    
    focusFirst() {
        const firstVisible = document.querySelector('.faq-item:not([style*="display: none"]) .faq-question');
        if (firstVisible) firstVisible.focus();
    }
    
    focusLast() {
        const questions = Array.from(document.querySelectorAll('.faq-question'));
        const visibleQuestions = questions.filter(q => 
            q.closest('.faq-item').style.display !== 'none'
        );
        const lastVisible = visibleQuestions[visibleQuestions.length - 1];
        if (lastVisible) lastVisible.focus();
    }
}

// Initialize the accordion when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
    new AccordionFAQ();
    
    // Add smooth scrolling for better UX
    document.documentElement.style.scrollBehavior = 'smooth';
    
    // Add loading animation
    const faqItems = document.querySelectorAll('.faq-item');
    faqItems.forEach((item, index) => {
        item.style.opacity = '0';
        item.style.transform = 'translateY(20px)';
        
        setTimeout(() => {
            item.style.transition = 'opacity 0.5s ease, transform 0.5s ease';
            item.style.opacity = '1';
            item.style.transform = 'translateY(0)';
        }, index * 100);
    });
});

Usage Examples

Basic Implementation

// Initialize the accordion
const faq = new AccordionFAQ();

// Programmatically open a specific item
faq.openItem(document.querySelector('.faq-item[data-category="general"]'));

// Programmatically search
faq.filterQuestions('shipping');

Custom Configuration

// Extended configuration options
const faq = new AccordionFAQ({
    allowMultiple: true,        // Allow multiple items open
    autoClose: false,          // Don't auto-close other items
    animationDuration: 300,    // Animation duration in ms
    scrollOffset: 100,         // Scroll offset when opening items
    highlightSearch: true      // Highlight search terms
});

Integration with Analytics

// Track FAQ interactions
class AnalyticsAccordionFAQ extends AccordionFAQ {
    toggleItem(item) {
        super.toggleItem(item);
        
        const question = item.querySelector('h3').textContent;
        const isOpening = item.classList.contains('active');
        
        // Send analytics event
        gtag('event', 'faq_interaction', {
            'question': question,
            'action': isOpening ? 'open' : 'close'
        });
    }
}

Browser Compatibility

  • Chrome 60+
  • Firefox 55+
  • Safari 12+
  • Edge 79+

Features Included

✅ Smooth accordion animations
✅ Search functionality with highlighting
✅ Keyboard navigation support
✅ Expand/collapse all controls
✅ Auto-scroll to opened sections
✅ Responsive design
✅ ARIA accessibility attributes
✅ Custom styling options
✅ No external dependencies
✅ SEO-friendly structure
✅ Touch-friendly interface
✅ Loading animations

Customization Options

  • Colors: Modify CSS custom properties for theming
  • Animation Speed: Adjust transition durations
  • Layout: Customize spacing and typography
  • Icons: Replace SVG icons with custom ones
  • Search: Configure search behavior and highlighting
  • Keyboard: Customize keyboard shortcuts

This accordion FAQ component provides a professional and user-friendly way to display frequently asked questions with smooth animations and comprehensive accessibility support.

HTML

58

lines

CSS

152

lines

JavaScript

30

lines


                <div class="accordion-faq-container">
  <div class="faq-header">
    <h1>Frequently Asked Questions</h1>
    <p>Find answers to common questions about our services</p>
  </div>
  
  <div class="accordion-wrapper">
    <div class="accordion-item">
      <div class="accordion-header">
        <h3>What services do you offer?</h3>
        <span class="accordion-icon">+</span>
      </div>
      <div class="accordion-content">
        <p>We offer a comprehensive range of web development services including custom website design, e-commerce solutions, mobile app development, and digital marketing strategies tailored to your business needs.</p>
      </div>
    </div>
    
    <div class="accordion-item">
      <div class="accordion-header">
        <h3>How long does a typical project take?</h3>
        <span class="accordion-icon">+</span>
      </div>
      <div class="accordion-content">
        <p>Project timelines vary depending on complexity and scope. A simple website typically takes 2-4 weeks, while more complex applications can take 2-6 months. We provide detailed timelines during our initial consultation.</p>
      </div>
    </div>
    
    <div class="accordion-item">
      <div class="accordion-header">
        <h3>What is your pricing structure?</h3>
        <span class="accordion-icon">+</span>
      </div>
      <div class="accordion-content">
        <p>Our pricing is project-based and depends on your specific requirements. We offer competitive rates and provide detailed quotes after understanding your needs. Contact us for a free consultation and estimate.</p>
      </div>
    </div>
    
    <div class="accordion-item">
      <div class="accordion-header">
        <h3>Do you provide ongoing support?</h3>
        <span class="accordion-icon">+</span>
      </div>
      <div class="accordion-content">
        <p>Yes, we offer comprehensive maintenance and support packages. This includes regular updates, security monitoring, backup services, and technical support to ensure your website runs smoothly.</p>
      </div>
    </div>
    
    <div class="accordion-item">
      <div class="accordion-header">
        <h3>Can you help with SEO and digital marketing?</h3>
        <span class="accordion-icon">+</span>
      </div>
      <div class="accordion-content">
        <p>Absolutely! We provide SEO optimization, content marketing, social media management, and paid advertising campaigns to help increase your online visibility and drive more traffic to your website.</p>
      </div>
    </div>
  </div>
</div>

              
58lines
2557characters
HTMLLanguage

Related Code Snippets

Explore template packs

Need larger building blocks? Browse responsive landing pages and component bundles.

Open HTML Template Library →