Accordion FAQ WordPress: HTML, CSS e JavaScript

Un accordion FAQ WordPress realizzato con HTML, CSS e JavaScript mostra le risposte solo quando l’utente ne ha bisogno, riducendo l’ingombro della pagina senza sacrificare l’accessibilità. La struttura corretta usa elementi button per le domande, attributi ARIA aggiornati dinamicamente e pannelli associati con ID univoci. Il codice può essere inserito in un blocco HTML personalizzato, mentre CSS e JavaScript possono essere caricati dal tema child. Il risultato è leggero, personalizzabile e indipendente da plugin aggiuntivi.

Struttura HTML semantica per le domande frequenti

Un accordion accessibile non dovrebbe usare semplici titoli cliccabili o elementi div trasformati artificialmente in pulsanti. L’elemento button comunica correttamente l’azione ai lettori di schermo, supporta la navigazione da tastiera e permette di aggiornare lo stato della domanda tramite aria-expanded.

In WordPress puoi inserire la struttura seguente in un blocco HTML personalizzato dell’editor Gutenberg. Ogni pulsante possiede un ID univoco e collega la risposta corrispondente con l’attributo aria-controls.

<section class="faq-accordion" aria-labelledby="faq-titolo">
<h2 id="faq-titolo">Domande frequenti</h2>

<div class="faq-item">
<h3 class="faq-question">
<button
type="button"
aria-expanded="false"
aria-controls="faq-risposta-1"
id="faq-domanda-1">
Come posso modificare il mio ordine?
<span class="faq-icon" aria-hidden="true">+</span>
</button>
</h3>

<div
id="faq-risposta-1"
class="faq-answer"
role="region"
aria-labelledby="faq-domanda-1"
hidden>
<p>
Puoi modificare il tuo ordine contattando il servizio clienti
prima della sua spedizione.
</p>
</div>
</div>

<div class="faq-item">
<h3 class="faq-question">
<button
type="button"
aria-expanded="false"
aria-controls="faq-risposta-2"
id="faq-domanda-2">
Quali sono i tempi di consegna?
<span class="faq-icon" aria-hidden="true">+</span>
</button>
</h3>

<div
id="faq-risposta-2"
class="faq-answer"
role="region"
aria-labelledby="faq-domanda-2"
hidden>
<p>
I tempi di consegna dipendono dalla località e dal metodo
di spedizione scelto durante il pagamento.
</p>
</div>
</div>
</section>

La combinazione tra h2 e h3 mantiene una gerarchia coerente con il resto del contenuto. L’attributo hidden nasconde davvero le risposte quando JavaScript non è ancora intervenuto, mentre role="region" identifica ogni pannello come area separata.

Per aggiungere altre domande, duplica il blocco faq-item e modifica tutti gli ID. Non riutilizzare faq-domanda-1 o faq-risposta-1 in più elementi, perché gli ID duplicati possono compromettere l’associazione tra pulsante e contenuto.

CSS per un accordion FAQ WordPress responsive

Il CSS deve occuparsi dell’aspetto grafico, non dello stato funzionale dell’accordion. La visibilità viene controllata dall’attributo hidden, mentre la classe is-open può essere utilizzata per ruotare l’icona o evidenziare la domanda attiva.

Inserisci queste regole in Aspetto > Personalizza > CSS aggiuntivo oppure nel foglio di stile del tema child.

.faq-accordion {
max-width: 760px;
margin: 2rem auto;
}

.faq-accordion h2 {
margin-bottom: 1.25rem;
}

.faq-item {
border-bottom: 1px solid #d9d9d9;
}

.faq-question {
margin: 0;
}

.faq-question button {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
width: 100%;
padding: 1.1rem 0;
border: 0;
background: transparent;
color: inherit;
cursor: pointer;
font: inherit;
font-weight: 700;
text-align: left;
}

.faq-question button:focus-visible {
outline: 3px solid #1d70b8;
outline-offset: 4px;
}

.faq-icon {
flex: 0 0 auto;
font-size: 1.5rem;
line-height: 1;
transition: transform 180ms ease;
}

.faq-question button[aria-expanded="true"] .faq-icon {
transform: rotate(45deg);
}

.faq-answer {
padding: 0 2.5rem 1.1rem 0;
}

.faq-answer p {
margin: 0;
}

@media (max-width: 600px) {
.faq-accordion {
margin: 1.5rem 0;
}

.faq-question button {
padding: 1rem 0;
}

.faq-answer {
padding-right: 0;
}
}

@media (prefers-reduced-motion: reduce) {
.faq-icon {
transition: none;
}
}

Il selettore :focus-visible mantiene un indicatore chiaro per chi usa la tastiera senza aggiungere un contorno permanente agli utenti del mouse. La media query prefers-reduced-motion elimina l’animazione per le persone che hanno richiesto la riduzione dei movimenti nelle impostazioni del sistema operativo.

Il layout usa larghezze relative e una media query per gli schermi piccoli, quindi l’accordion si adatta a smartphone, tablet e desktop senza richiedere un framework CSS.

JavaScript per aprire e chiudere le risposte

Il JavaScript deve aggiornare contemporaneamente aria-expanded, hidden e lo stato visivo dell’elemento. Il codice seguente permette di scegliere tra due comportamenti: più risposte aperte allo stesso tempo oppure una sola risposta aperta.

Salva il codice in un file chiamato faq-accordion.js all’interno del tema child, per esempio nella cartella js.

document.addEventListener("DOMContentLoaded", function () {
const accordion = document.querySelector(".faq-accordion");

if (!accordion) {
return;
}

const buttons = accordion.querySelectorAll(".faq-question button");

buttons.forEach(function (button) {
button.addEventListener("click", function () {
const panelId = button.getAttribute("aria-controls");
const panel = document.getElementById(panelId);
const isExpanded = button.getAttribute("aria-expanded") === "true";

if (!panel) {
return;
}

buttons.forEach(function (otherButton) {
const otherPanelId = otherButton.getAttribute("aria-controls");
const otherPanel = document.getElementById(otherPanelId);

if (
otherButton !== button &&
otherPanel &&
otherButton.getAttribute("aria-expanded") === "true"
) {
otherButton.setAttribute("aria-expanded", "false");
otherPanel.hidden = true;
}
});

button.setAttribute("aria-expanded", String(!isExpanded));
panel.hidden = isExpanded;
});
});
});

In questo esempio, l’apertura di una risposta chiude automaticamente le altre risposte dello stesso accordion. Il controllo con querySelector(".faq-accordion") limita il comportamento alla sezione interessata e impedisce conflitti con altri pulsanti presenti nella pagina.

Per consentire più risposte aperte contemporaneamente, rimuovi dal codice il blocco che inizia con buttons.forEach e contiene otherButton e otherPanel. Il resto dello script può rimanere invariato.

Come caricare JavaScript in WordPress senza plugin

WordPress può rimuovere o non eseguire i tag script inseriti direttamente nel blocco HTML personalizzato, soprattutto in base al ruolo dell’utente e alle regole di sicurezza dell’installazione. Il metodo più affidabile consiste nel caricare il file tramite functions.php del tema child.

Aggiungi questo codice al file functions.php del tema child:

function backdigit_carica_faq_accordion() {
wp_enqueue_script(
'faq-accordion',
get_stylesheet_directory_uri() . '/js/faq-accordion.js',
array(),
'1.0.0',
true
);
}
add_action('wp_enqueue_scripts', 'backdigit_carica_faq_accordion');

Il quinto parametro true chiede a WordPress di caricare lo script nel piè di pagina, dopo il contenuto HTML. L’evento DOMContentLoaded mantiene comunque il codice sicuro anche quando il file viene combinato o spostato da altre ottimizzazioni del tema.

Se il tema child non è disponibile, modifica direttamente il tema attivo solo come soluzione temporanea: gli aggiornamenti del tema possono sovrascrivere functions.php e il file JavaScript. Prima di intervenire, esegui un backup e verifica che il codice PHP non contenga errori di sintassi.

Verifica dell’accordion dopo l’inserimento

Controlla il funzionamento con mouse e tastiera. Il tasto Tab deve raggiungere ogni domanda, mentre Invio e Barra spaziatrice devono aprire o chiudere il pannello attivo. Quando una risposta è aperta, il pulsante deve avere aria-expanded="true" e il relativo pannello non deve più avere l’attributo hidden.

Verifica anche questi aspetti:

  • Ogni aria-controls deve puntare a un ID realmente presente nella pagina.
  • Ogni aria-labelledby deve collegarsi al pulsante della stessa risposta.
  • Il testo deve restare leggibile senza dipendere dal colore o dall’animazione.
  • L’accordion deve funzionare anche su schermi stretti e con zoom elevato.
  • Il contenuto delle risposte deve essere indicizzabile quando è presente nel codice HTML.

L’accordion FAQ WordPress non richiede necessariamente dati strutturati FAQPage. L’eventuale markup strutturato deve descrivere contenuti realmente visibili e conformi alle linee guida di Google; non va aggiunto automaticamente solo per ottenere un risultato avanzato nei motori di ricerca.

Un accordion FAQ WordPress HTML CSS JavaScript ben costruito deve restare accessibile, leggero e facilmente modificabile anche senza plugin.

Potrebbe interessarti anche:

FAQ

Sì, la struttura HTML può essere inserita in un blocco HTML personalizzato. CSS e JavaScript vanno però gestiti preferibilmente dal tema child per evitare problemi di sicurezza o filtri dell’editor.

No, HTML semantico, CSS e JavaScript sono sufficienti per realizzare un accordion funzionale e accessibile. Un plugin può essere utile solo se servono gestione avanzata, dati strutturati automatici o integrazione con altri sistemi.

Sì, basta rimuovere dal JavaScript il blocco che chiude gli altri pannelli quando viene aperta una nuova domanda. La gestione degli attributi aria-expanded e hidden deve rimanere attiva.

WordPress può filtrare gli script inseriti nell’editor in base ai permessi dell’utente o alle impostazioni di sicurezza. Il caricamento tramite wp_enqueue_script nel tema child è il metodo più affidabile.

Il contenuto inserito nel codice HTML può essere analizzato dai motori di ricerca, ma la visibilità tramite accordion non garantisce risultati avanzati. Le risposte devono essere utili, pertinenti e realmente presenti nella pagina.

Altri articoli di questa serie:

PDF Strumenti PDF gratis Nel browser, senza upload Apri gli strumenti