<nav class="rtds-steps rtds-steps--numbered" aria-label="Avanzamento procedura">
    <ol class="rtds-steps__list">
        <li class="rtds-steps__item rtds-steps__item--completed">
            <a href="/step1" class="rtds-steps__link">
                <span class="rtds-steps__indicator" aria-hidden="true">
                    1
                </span>
                <span class="rtds-sr-only">Completato: </span>
                <span class="rtds-steps__label">Dati anagrafici</span>
            </a>
        </li>
        <li class="rtds-steps__item rtds-steps__item--completed">
            <span class="rtds-steps__link">
                <span class="rtds-steps__indicator" aria-hidden="true">
                    2
                </span>
                <span class="rtds-sr-only">Completato: </span>
                <span class="rtds-steps__label">Contatti</span>
            </span>
        </li>
        <li class="rtds-steps__item rtds-steps__item--active">
            <span class="rtds-steps__link" aria-current="step">
                <span class="rtds-steps__indicator" aria-hidden="true">
                    3
                </span>
                <span class="rtds-sr-only">Corrente: </span>
                <span class="rtds-steps__label">Documenti</span>
            </span>
        </li>
        <li class="rtds-steps__item">
            <span class="rtds-steps__link">
                <span class="rtds-steps__indicator" aria-hidden="true">
                    4
                </span>
                <span class="rtds-steps__label">Riepilogo</span>
            </span>
        </li>
        <li class="rtds-steps__item">
            <span class="rtds-steps__link">
                <span class="rtds-steps__indicator" aria-hidden="true">
                    5
                </span>
                <span class="rtds-steps__label">Conferma</span>
            </span>
        </li>
    </ol>
    <span class="rtds-steps__counter" aria-hidden="true">3 / 5</span>
</nav>
{% extends '@steps' %}

{% block modifierClass %} rtds-steps--numbered{% endblock %}
{
  "ariaLabel": "Avanzamento procedura",
  "completedLabel": "Completato: ",
  "currentLabel": "Corrente: ",
  "srStepLabel": "Step",
  "srOfLabel": "di",
  "steps": [
    {
      "label": "Dati anagrafici",
      "completed": true,
      "href": "/step1"
    },
    {
      "label": "Contatti",
      "completed": true
    },
    {
      "label": "Documenti",
      "active": true
    },
    {
      "label": "Riepilogo"
    },
    {
      "label": "Conferma"
    }
  ],
  "numbered": true
}
  • Content:
    .rtds-steps {
            --_steps-color-default:   var(--steps-color-default,   var(--color-content-03,         var(--color-neutral-900)));
            --_steps-color-active:    var(--steps-color-active,    var(--color-content-secondary,  var(--color-secondary-500)));
            --_steps-color-completed: var(--steps-color-completed, var(--color-content-secondary,  var(--color-secondary-500)));
            --_steps-label-color:     var(--steps-label-color,     var(--color-content-01,         var(--color-neutral-900)));
            --_steps-indicator-size:  var(--steps-indicator-size,  var(--spacing-6,                1.5rem));
            --_steps-indicator-bg:    var(--steps-indicator-bg,    var(--color-background-01,      var(--color-neutral-50)));
            --_steps-indicator-border: var(--steps-indicator-border, var(--color-border-gray-03,    var(--color-neutral-600)));
            --_steps-bar-color:        var(--steps-bar-color,       var(--color-border-gray-03,    var(--color-neutral-600)));
            --_steps-bar-height:       var(--steps-bar-height,      var(--spacing-1,               0.25rem));
            display: flex;
            align-items: center;
            gap: var(--spacing-2);
        }
    .rtds-steps__list {
            flex: 1;
            min-width: 0;
            display: flex;
            list-style: none;
            padding: 0;
            margin: 0;
        }
    .rtds-steps__item {
            flex: 1;
            display: flex;
            flex-direction: column;
        }
    /* Nasconde visualmente gli step non attivi su mobile, lasciandoli accessibili agli screen reader */
    :where(.rtds-steps__item):not(.rtds-steps__item--active) {
            position: absolute;
            width: 1px;
            height: 1px;
            overflow: hidden;
            clip-path: inset(50%);
            white-space: nowrap;
        }
    .rtds-steps__link {
            display: flex;
            flex-direction: row;
            align-items: center;
            gap: var(--spacing-2);
            text-decoration: none;
            color: var(--_steps-color-default);
            font-size: var(--fontsize-text-sm);
            padding-block: var(--spacing-3);
            padding-inline: var(--spacing-2);
        }
    :where(a.rtds-steps__link):hover .rtds-steps__label {
            text-decoration: underline;
        }
    /* Indicatore: nascosto su mobile */
    .rtds-steps__indicator {
            display: none;
            width: var(--_steps-indicator-size);
            height: var(--_steps-indicator-size);
            align-items: center;
            justify-content: center;
            border-radius: 50%;
            flex-shrink: 0;
            line-height: 1;
            color: var(--_steps-color-default);
            background-color: transparent;
            border: 2px solid var(--_steps-indicator-border);
        }
    /* Completato: cerchio con bordo + sfondo bianco + check icon */
    :where(.rtds-steps__item--completed) .rtds-steps__indicator {
            color: var(--_steps-color-completed);
            border-color: currentColor;
            background-color: var(--_steps-indicator-bg);
        }
    /* Attivo: cerchio con bordo spesso + sfondo bianco */
    :where(.rtds-steps__item--active) .rtds-steps__indicator {
            color: var(--_steps-color-active);
            background-color: var(--_steps-indicator-bg);
            border-color: var(--_steps-color-active);
            border-width: var(--spacing-2);
        }
    .rtds-steps__label {
            color: inherit;
        }
    :where(.rtds-steps__item--completed) .rtds-steps__label {
            color: var(--_steps-label-color);
        }
    :where(.rtds-steps__item--active) .rtds-steps__label {
            font-weight: 600;
            color: var(--_steps-color-active);
        }
    /* Counter: visibile su mobile affiancato allo step attivo */
    .rtds-steps__counter {
            display: block;
            flex-shrink: 0;
            font-size: var(--fontsize-text-sm);
            font-weight: 700;
            color: var(--_steps-color-default);
        }
    @media (min-width: 40rem) {
            .rtds-steps {
                display: block;
            }
    
            .rtds-steps__list {
                gap: var(--spacing-base);
            }
    
            /* Ripristina la visibilità di tutti gli step su desktop */
            :where(.rtds-steps__item):not(.rtds-steps__item--active) {
                position: static;
                width: auto;
                height: auto;
                overflow: visible;
                clip-path: none;
                white-space: normal;
            }
    
            .rtds-steps__item {
                border-bottom: var(--_steps-bar-height) solid var(--_steps-bar-color);
            }
    
            .rtds-steps__item--completed {
                border-bottom-color: var(--_steps-color-completed);
            }
    
            .rtds-steps__item--active {
                border-bottom-color: var(--_steps-color-active);
            }
    
            /* Indicatore: visibile su desktop */
            .rtds-steps__indicator {
                display: flex;
            }
    
            .rtds-steps__counter {
                display: none;
            }
        }
    /* Variante numerata */
    :where(.rtds-steps--numbered) .rtds-steps__indicator {
            font-size: var(--fontsize-text-sm);
            font-weight: 600;
        }
    /* Attivo numerata: cerchio pieno + numero bianco */
    :where(.rtds-steps--numbered .rtds-steps__item--active) .rtds-steps__indicator {
            background-color: var(--_steps-color-active);
            border-color: var(--_steps-color-active);
            color: var(--color-content-inverse, var(--color-neutral-50));
        }
    /* Completato numerata: cerchio con bordo + sfondo bianco + check icon */
    :where(.rtds-steps--numbered .rtds-steps__item--completed) .rtds-steps__indicator {
            color: var(--_steps-color-completed);
            border-color: currentColor;
            background-color: var(--_steps-indicator-bg);
        }
    
  • URL: /components/raw/steps/steps.built.css
  • Filesystem Path: components/08-servizi/steps/steps.built.css
  • Size: 5.6 KB
  • Content:
    @layer components {
        .rtds-steps {
            --_steps-color-default:   var(--steps-color-default,   var(--color-content-03,         var(--color-neutral-900)));
            --_steps-color-active:    var(--steps-color-active,    var(--color-content-secondary,  var(--color-secondary-500)));
            --_steps-color-completed: var(--steps-color-completed, var(--color-content-secondary,  var(--color-secondary-500)));
            --_steps-label-color:     var(--steps-label-color,     var(--color-content-01,         var(--color-neutral-900)));
            --_steps-indicator-size:  var(--steps-indicator-size,  var(--spacing-6,                1.5rem));
            --_steps-indicator-bg:    var(--steps-indicator-bg,    var(--color-background-01,      var(--color-neutral-50)));
            --_steps-indicator-border: var(--steps-indicator-border, var(--color-border-gray-03,    var(--color-neutral-600)));
            --_steps-bar-color:        var(--steps-bar-color,       var(--color-border-gray-03,    var(--color-neutral-600)));
            --_steps-bar-height:       var(--steps-bar-height,      var(--spacing-1,               0.25rem));
            display: flex;
            align-items: center;
            gap: var(--spacing-2);
        }
    
        .rtds-steps__list {
            flex: 1;
            min-width: 0;
            display: flex;
            list-style: none;
            padding: 0;
            margin: 0;
        }
    
        .rtds-steps__item {
            flex: 1;
            display: flex;
            flex-direction: column;
        }
    
        /* Nasconde visualmente gli step non attivi su mobile, lasciandoli accessibili agli screen reader */
        :where(.rtds-steps__item):not(.rtds-steps__item--active) {
            position: absolute;
            width: 1px;
            height: 1px;
            overflow: hidden;
            clip-path: inset(50%);
            white-space: nowrap;
        }
    
        .rtds-steps__link {
            display: flex;
            flex-direction: row;
            align-items: center;
            gap: var(--spacing-2);
            text-decoration: none;
            color: var(--_steps-color-default);
            font-size: var(--fontsize-text-sm);
            padding-block: var(--spacing-3);
            padding-inline: var(--spacing-2);
        }
    
        :where(a.rtds-steps__link):hover .rtds-steps__label {
            text-decoration: underline;
        }
    
        /* Indicatore: nascosto su mobile */
        .rtds-steps__indicator {
            display: none;
            width: var(--_steps-indicator-size);
            height: var(--_steps-indicator-size);
            align-items: center;
            justify-content: center;
            border-radius: 50%;
            flex-shrink: 0;
            line-height: 1;
            color: var(--_steps-color-default);
            background-color: transparent;
            border: 2px solid var(--_steps-indicator-border);
        }
    
        /* Completato: cerchio con bordo + sfondo bianco + check icon */
        :where(.rtds-steps__item--completed) .rtds-steps__indicator {
            color: var(--_steps-color-completed);
            border-color: currentColor;
            background-color: var(--_steps-indicator-bg);
        }
    
        /* Attivo: cerchio con bordo spesso + sfondo bianco */
        :where(.rtds-steps__item--active) .rtds-steps__indicator {
            color: var(--_steps-color-active);
            background-color: var(--_steps-indicator-bg);
            border-color: var(--_steps-color-active);
            border-width: var(--spacing-2);
        }
    
        .rtds-steps__label {
            color: inherit;
        }
    
        :where(.rtds-steps__item--completed) .rtds-steps__label {
            color: var(--_steps-label-color);
        }
    
        :where(.rtds-steps__item--active) .rtds-steps__label {
            font-weight: 600;
            color: var(--_steps-color-active);
        }
    
        /* Counter: visibile su mobile affiancato allo step attivo */
        .rtds-steps__counter {
            display: block;
            flex-shrink: 0;
            font-size: var(--fontsize-text-sm);
            font-weight: 700;
            color: var(--_steps-color-default);
        }
    
        @media (min-width: 40rem) {
            .rtds-steps {
                display: block;
            }
    
            .rtds-steps__list {
                gap: var(--spacing-base);
            }
    
            /* Ripristina la visibilità di tutti gli step su desktop */
            :where(.rtds-steps__item):not(.rtds-steps__item--active) {
                position: static;
                width: auto;
                height: auto;
                overflow: visible;
                clip-path: none;
                white-space: normal;
            }
    
            .rtds-steps__item {
                border-bottom: var(--_steps-bar-height) solid var(--_steps-bar-color);
            }
    
            .rtds-steps__item--completed {
                border-bottom-color: var(--_steps-color-completed);
            }
    
            .rtds-steps__item--active {
                border-bottom-color: var(--_steps-color-active);
            }
    
            /* Indicatore: visibile su desktop */
            .rtds-steps__indicator {
                display: flex;
            }
    
            .rtds-steps__counter {
                display: none;
            }
        }
    
        /* Variante numerata */
        :where(.rtds-steps--numbered) .rtds-steps__indicator {
            font-size: var(--fontsize-text-sm);
            font-weight: 600;
        }
    
        /* Attivo numerata: cerchio pieno + numero bianco */
        :where(.rtds-steps--numbered .rtds-steps__item--active) .rtds-steps__indicator {
            background-color: var(--_steps-color-active);
            border-color: var(--_steps-color-active);
            color: var(--color-content-inverse, var(--color-neutral-50));
        }
    
        /* Completato numerata: cerchio con bordo + sfondo bianco + check icon */
        :where(.rtds-steps--numbered .rtds-steps__item--completed) .rtds-steps__indicator {
            color: var(--_steps-color-completed);
            border-color: currentColor;
            background-color: var(--_steps-indicator-bg);
        }
    }
    
  • URL: /components/raw/steps/steps.css
  • Filesystem Path: components/08-servizi/steps/steps.css
  • Size: 5.7 KB

Steps

Indicatore di avanzamento per flussi multi-step (wizard, moduli a più pagine). Mostra gli step del percorso con i rispettivi stati (completato, attivo, futuro) senza includere content area né pulsanti di navigazione — entrambi sono responsabilità del consumer. Su mobile mostra solo lo step attivo (gli altri sono nascosti visivamente ma restano accessibili agli screen reader) affiancato da un contatore compatto, calcolato senza JavaScript.


Comportamento

Il componente produce sempre un <nav> con un <ol> di step. L’elemento interno di ogni step varia:

  • <a href="..."> — step completato con href fornito sull’oggetto step; consente di tornare a step precedenti senza JavaScript
  • <span> — tutti gli altri casi: step completato senza href, step attivo, step futuro

Varianti

  • steps (default): indicatore circolare sempre presente per tutti gli stati — cerchio vuoto con bordo per gli step futuri, cerchio con bordo + spunta (check-solid) per i completati, cerchio con bordo spesso (8px) e sfondo bianco senza icona per l’attivo
  • numbered: numero progressivo (1, 2, 3…) al posto di icone e cerchi; utile quando la sequenzialità numerica è significativa

Parametri di configurazione

Contesto di sviluppo Fractal/Nunjucks — parametri del context .config.yml usati nella libreria.

Parametri radice

  • steps (array, obbligatorio): lista di oggetti step (vedi Oggetto step)
  • ariaLabel (stringa, opzionale, default: "Avanzamento procedura"): label del <nav> letta dagli screen reader
  • completedLabel (stringa, opzionale, default: "Completato: "): prefisso sr-only per step completati
  • currentLabel (stringa, opzionale, default: "Corrente: "): prefisso sr-only per lo step attivo
  • classes (stringa, opzionale): classi CSS aggiuntive sul <nav>

Oggetto step

  • label (stringa, obbligatorio): testo visibile dello step
  • completed (booleano, opzionale, default: false): segna lo step come completato
  • active (booleano, opzionale, default: false): segna lo step come corrente — massimo uno per componente
  • href (stringa, opzionale): se presente e completed: true, lo step diventa un <a> navigabile
  • icon (stringa, opzionale): ID icona SVG sprite per step completati (solo variante base); default check-solid. Ignorato nella variante numerata.

Accessibilità

WCAG 2.1

Livello AA — criteri pertinenti:

  • 1.3.1 Informazioni e correlazioni — <nav> landmark + <ol> comunica sequenzialità
  • 1.3.3 Caratteristiche sensoriali — stato comunicato via testo, non solo colore
  • 2.1.1 Tastiera — step completati con href sono link navigabili da tastiera
  • 4.1.2 Nome, Ruolo, Valore — aria-current="step" sullo step attivo

Struttura e semantica

  • <nav> — landmark navigation; identificato dall’aria-label configurabile
  • <ol> — lista ordinata; comunica agli screen reader che gli step sono in sequenza
  • <a> — ruolo implicito link; attivabile con Enter; solo per step completati con href
  • <span> — nessun ruolo interattivo; usato per step attivi, futuri e completati senza link
  • <span aria-current="step"> / <a aria-current="step"> — annuncia lo step corrente agli screen reader; posizionato sull’elemento interattivo (.rtds-steps__link), non sul <li>

Attributi ARIA

Attributo Valori Condizione
aria-label stringa Sul <nav>; sempre presente
aria-current "step" Sul .rtds-steps__link (<a> o <span>) dello step attivo
aria-hidden "true" Su .rtds-steps__indicator (decorativo) e .rtds-steps__counter

Screen reader

  • <span class="rtds-sr-only">Completato: </span> — prefisso sr-only davanti alla label degli step completati; comunicano lo stato senza dipendere dai colori
  • <span class="rtds-sr-only">Corrente: </span> — prefisso sr-only per lo step attivo; in combinazione con aria-current="step" sul .rtds-steps__link, lo step viene annunciato chiaramente
  • aria-hidden="true" sull’indicatore — icone, cerchi e numeri sono decorativi; lo stato è comunicato dal testo sr-only
  • aria-hidden="true" sul contatore mobile — l’informazione è già accessibile tramite la struttura della lista completa

Stili CSS

Classi Base

  • .rtds-steps: <nav> wrapper; contiene le variabili triple fallback

Classi Modificatori

  • .rtds-steps--numbered: variante numerata; gli indicatori mostrano il numero progressivo con bordo

Classi Elementi (BEM)

  • .rtds-steps__list: <ol> — layout flex orizzontale
  • .rtds-steps__item: <li> — flex colonna; border-bottom come barra visiva di separazione orizzontale
  • .rtds-steps__item--active: step corrente — indicatore cerchio con bordo spesso (var(--spacing-2) = 8px) nel colore active e sfondo bianco (--_steps-indicator-bg), senza icona; label in grassetto; border-bottom nel colore active
  • .rtds-steps__item--completed: step completato — border-bottom nel colore completed; indicatore con bordo e sfondo chiaro
  • .rtds-steps__link: <a> o <span> — flex row centrato con gap; decorazione underline on hover solo sui link
  • .rtds-steps__indicator: contenitore icona/numero/cerchio — sempre presente per tutti gli stati; dimensione fissa --_steps-indicator-size, centrato, forma circolare; cerchio vuoto (solo bordo) per step futuri, con icona o riempito per gli altri stati
  • .rtds-steps__label: testo dello step; grassetto e colore active sullo step corrente
  • .rtds-steps__counter: contatore X / Y; nascosto su desktop, affiancato allo step attivo su mobile (< 640px)

Tematizzazione

Il componente espone variabili CSS per la personalizzazione dal CMS ospitante. Il CMS può sovrascrivere le variabili Tier 1; se non sovrascritte, usano i token semantici del DS.

Override pubblici (Tier 1)

Proprietà CSS Default DS Descrizione
--steps-color-default var(--color-content-03) Colore testo e label degli step futuri
--steps-color-active var(--color-content-secondary) Colore indicatore e label dello step corrente
--steps-color-completed var(--color-content-secondary) Colore indicatore e bordo inferiore degli step completati
--steps-label-color var(--color-content-01) Colore delle label
--steps-indicator-size var(--spacing-6) Dimensione (larghezza e altezza) dell’indicatore
--steps-indicator-bg var(--color-background-01) Sfondo dell’indicatore per step completati
--steps-indicator-border var(--color-border-gray-03) Colore del bordo dell’indicatore degli step futuri
--steps-bar-color var(--color-border-gray-03) Colore della barra inferiore degli step futuri
--steps-bar-height var(--spacing-1) Altezza della barra inferiore

Token semantici DS (Tier 2)

Token DS Fallback primitivo Descrizione
--color-content-03 var(--color-neutral-900) Grigio scuro per step futuri
--color-content-secondary var(--color-secondary-500) Colore secondario del DS
--color-content-01 var(--color-neutral-900) Testo principale
--spacing-6 1.5rem Spacing base × 6 — dimensione indicatore
--color-background-01 var(--color-neutral-50) Sfondo chiaro per indicatori completati
--color-border-gray-03 var(--color-neutral-600) Grigio per bordo indicatore e barra degli step futuri
--spacing-1 0.25rem Spacing base × 1 — altezza barra

Esempi di utilizzo

<!-- Variante base (cerchi e icone) -->
<nav class="rtds-steps" aria-label="Avanzamento procedura">
  <ol class="rtds-steps__list">
    <li class="rtds-steps__item rtds-steps__item--completed">
      <a href="/step1" class="rtds-steps__link">
        <span class="rtds-steps__indicator" aria-hidden="true">
          <!-- icona check-solid, 16×16 -->
        </span>
        <span class="rtds-sr-only">Completato: </span>
        <span class="rtds-steps__label">Dati anagrafici</span>
      </a>
    </li>
    <li class="rtds-steps__item rtds-steps__item--active">
      <span class="rtds-steps__link" aria-current="step">
        <span class="rtds-steps__indicator" aria-hidden="true"></span>
        <span class="rtds-sr-only">Corrente: </span>
        <span class="rtds-steps__label">Contatti</span>
      </span>
    </li>
    <li class="rtds-steps__item">
      <span class="rtds-steps__link">
        <span class="rtds-steps__indicator" aria-hidden="true"></span>
        <span class="rtds-steps__label">Riepilogo</span>
      </span>
    </li>
  </ol>
  <span class="rtds-steps__counter" aria-hidden="true">2 / 3</span>
</nav>

<!-- Variante numerata -->
<nav class="rtds-steps rtds-steps--numbered" aria-label="Avanzamento procedura">
  <ol class="rtds-steps__list">
    <li class="rtds-steps__item rtds-steps__item--completed">
      <span class="rtds-steps__link">
        <span class="rtds-steps__indicator" aria-hidden="true">1</span>
        <span class="rtds-sr-only">Completato: </span>
        <span class="rtds-steps__label">Dati anagrafici</span>
      </span>
    </li>
    <li class="rtds-steps__item rtds-steps__item--active">
      <span class="rtds-steps__link" aria-current="step">
        <span class="rtds-steps__indicator" aria-hidden="true">2</span>
        <span class="rtds-sr-only">Corrente: </span>
        <span class="rtds-steps__label">Contatti</span>
      </span>
    </li>
    <li class="rtds-steps__item">
      <span class="rtds-steps__link">
        <span class="rtds-steps__indicator" aria-hidden="true">3</span>
        <span class="rtds-steps__label">Riepilogo</span>
      </span>
    </li>
  </ol>
  <span class="rtds-steps__counter" aria-hidden="true">2 / 3</span>
</nav>

Note

  • Il contatore mobile (X / Y) è calcolato interamente in Nunjucks — non richiede JavaScript.
  • Su viewport < 640px gli step non attivi sono nascosti visivamente ma restano accessibili agli screen reader. Il <span class="rtds-steps__counter"> è aria-hidden="true" perché la lista completa è già navigabile.
  • Il parametro icon per-step è ignorato nella variante numerata.
  • Il componente non include content area né pulsanti di navigazione: sono responsabilità del consumer.
  • Massimo un active: true per istanza.
  • Dipende da: @icon (variante base, per step completati)