sintassi prescrittive

L'elemento <picture> non esegue il rendering di nulla, ma agisce invece da motore decisionale per un elemento <img> interno, indicando cosa eseguire il rendering. <picture> segue un precedente già impostato dagli elementi <audio> e <video>: un elemento wrapper contenente singoli elementi <source>.

<picture>
   <source …>
   <source …>
    <img …>
</picture …>

L'elemento <img> interno fornisce anche un pattern di riserva affidabile per i browser meno recenti che non supportano le immagini adattabili: se l'elemento <picture> non viene riconosciuto dal browser dell'utente, viene ignorato. Anche gli elementi <source> vengono eliminati, poiché il browser non li riconoscerà affatto oppure non avrà un contesto significativo per gli elementi senza un elemento padre <video> o <audio>. Tuttavia, l'elemento <img> interno verrà riconosciuto da qualsiasi browser e l'origine specificata in src verrà visualizzata come previsto.

Immagini "diretti da arte" con <picture>

Le modifiche ai contenuti o alle proporzioni di un'immagine in base alle dimensioni dell'immagine nella pagina sono in genere definite immagini adattabili "art-direct". srcset e sizes sono progettati per funzionare in modo invisibile e scambiando facilmente le fonti in base alle specifiche del browser dell'utente. Tuttavia, in alcuni casi è necessario modificare le origini in base ai punti di interruzione per evidenziare meglio i contenuti, nello stesso modo in cui adatti i layout di pagina. Ad esempio, un'immagine intestazione a larghezza intera con un piccolo elemento centrale centrale potrebbe funzionare bene su un'area visibile di grandi dimensioni:

Immagine larga intestazione di un fiore di pervinca circondato da foglie e steli, visitato da un&#39;ape.

Tuttavia, quando viene ridimensionata per adattarsi all'area visibile di piccole dimensioni, l'elemento centrale dell'immagine potrebbe andare perso:

Immagine di un fiore di pervinca, larga intestazione, ridimensionata. L&#39;ape è appena visibile.

Il soggetto di queste origini dell'immagine è lo stesso, ma, per una maggiore attenzione visiva su quel soggetto, è consigliabile che le proporzioni dell'origine dell'immagine cambino tra i punti di interruzione. Ad esempio, uno zoom più intenso sul centro dell'immagine e alcuni dettagli ai bordi ritagliati:

Un&#39;immagine ingrandita del fiore di pervinca.

Questo tipo di "ritaglio" può essere ottenuto tramite CSS, ma un utente richiede tutti i dati che costituiscono l'immagine, anche se potrebbe non vederli mai.

Ogni elemento source ha attributi che definiscono le condizioni per la selezione di source: media, che accetta una query multimediale, e type, che accetta un tipo multimediale (precedentemente noto come "tipo MIME"). Viene selezionato il primo <source> nell'ordine di origine corrispondente al contesto di navigazione corrente dell'utente e i contenuti dell'attributo srcset in tale source verranno utilizzati per determinare i candidati giusti per quel contesto. In questo esempio, verrà selezionato il primo elemento source con un attributo media che corrisponde alle dimensioni dell'area visibile dell'utente:

<picture>
  <source media="(min-width: 1200px)" srcset="wide-crop.jpg">
  <img src="close-crop.jpg" alt="…">
</picture>

Devi sempre specificare il valore img interno per ultimo nell'ordine: se nessuno degli elementi source corrisponde ai criteri media o type, l'immagine verrà usata come origine "predefinita". Se utilizzi query supporti min-width, vuoi prima avere le origini più grandi, come mostrato nel codice precedente. Quando utilizzi le query supporti max-width, dovresti posizionare per prima la fonte più piccola.

<picture>
   <source media="(max-width: 400px)" srcset="mid-bp.jpg">
   <source media="(max-width: 800px)" srcset="high-bp.jpg">
   <img src="highest-bp.jpg" alt="…">
</picture>

Quando viene scelta una fonte in base ai criteri specificati, l'attributo srcset su source viene trasmesso a <img> come se fosse definito su <img> stesso, il che significa che puoi usare liberamente sizes per ottimizzare anche le fonti di immagini dirette alle opere d'arte.

<picture>
   <source media="(min-width: 800px)" srcset="high-bp-1600.jpg 1600w, high-bp-1000.jpg 1000w">
   <source srcset="lower-bp-1200.jpg 1200w, lower-bp-800.jpg 800w">
   <img src="fallback.jpg" alt="…" sizes="calc(100vw - 2em)">
</picture>

Naturalmente, un'immagine con proporzioni che possono variare a seconda dell'elemento <source> selezionato genera un problema di rendimento: <img> supporta solo un singolo attributo width e height, ma l'omissione di questi attributi può portare a un'esperienza utente misuratamente peggiore. Per tenere conto di ciò, un'aggiunta relativamente recente, ma ben supportata, alla specifica HTML consente l'utilizzo degli attributi height e width negli elementi <source>. Queste operazioni consentono di ridurre le variazioni del layout come accade su <img>, con lo spazio appropriato riservato nel layout per qualsiasi elemento <source> selezionato.

<picture>
   <source
      media="(min-width: 800px)"
      srcset="high-bp-1600.jpg 1600w, high-bp-1000.jpg 1000w"
      width="1600"
      height="800">
   <img src="fallback.jpg"
      srcset="lower-bp-1200.jpg 1200w, lower-bp-800.jpg 800w"
      sizes="calc(100vw - 2em)"
      width="1200"
      height="750"
      alt="…">
</picture>

È importante notare che la direzione artistica può essere utilizzata per prendere decisioni più che semplici in base alle dimensioni dell'area visibile e dovrebbe, dato che la maggior parte di questi casi può essere gestita in modo più efficiente con srcset/sizes. Ad esempio, selezionando un'origine immagine più adatta alla combinazione di colori dettata dalle preferenze di un utente:

<picture>
   <source media="(prefers-color-scheme: dark)" srcset="hero-dark.jpg">
   <img srcset="hero-light.jpg">
</picture>

Attributo type

L'attributo type ti consente di utilizzare il motore decisionale di richiesta singola dell'elemento <picture> per pubblicare i formati delle immagini solo nei browser che li supportano.

Come hai appreso nel documento Formati e compressione delle immagini, una codifica che il browser non è in grado di analizzare non sarà neanche riconoscibile come dati di immagine.

Prima dell'introduzione dell'elemento <picture>, le soluzioni front-end più attuabili per la pubblicazione di nuovi formati di immagine richiedevano al browser di richiedere e tentare di analizzare un file immagine prima di determinare se ignorarlo e caricare un file di riserva. Un esempio comune è stato uno script come segue:

   <img src="image.webp"
    data-fallback="image.jpg"
    onerror="this.src=this.getAttribute('data-fallback'); this.onerror=null;"
    alt="...">

Con questo pattern, verrebbe comunque effettuata una richiesta per image.webp in ogni browser, il che significa un trasferimento inutili per i browser che non supportano WebP. I browser che non sono in grado di analizzare la codifica WebP genererebbero un evento onerror e scambiavano il valore data-fallback in src. Era una soluzione dispendiosa, ma, ancora una volta, approcci come questo erano l'unica opzione disponibile nel front-end. Ricorda che il browser inizia a effettuare richieste di immagini prima che qualsiasi scripting personalizzato abbia la possibilità di essere eseguito o addirittura di essere analizzato, quindi non abbiamo potuto prerilasciare questo processo.

L'elemento <picture> è progettato esplicitamente per evitare queste richieste ridondanti. Anche se un browser non può ancora riconoscere un formato che non supporta senza richiederlo, l'attributo type avvisa preventivamente il browser della codifica del codice sorgente, in modo che possa decidere se effettuare o meno una richiesta.

Nell'attributo type, fornisci il tipo di media (in precedenza tipo MIME) dell'origine dell'immagine specificata nell'attributo srcset di ogni <source>. In questo modo il browser ha tutte le informazioni necessarie per determinare immediatamente se l'immagine candidata da tale source può essere decodificata senza effettuare richieste esterne. Se il tipo di media non viene riconosciuto, <source> e tutti i suoi candidati vengono ignorati e il browser va avanti.

<picture>
 <source type="image/webp" srcset="pic.webp">
 <img src="pic.jpg" alt="...">
</picture>

In questo caso, qualsiasi browser che supporta la codifica WebP riconosce il tipo multimediale image/webp specificato nell'attributo type dell'elemento <source>, seleziona <source> e, dato che abbiamo indicato un solo candidato in srcset, chiedi al <img> interno di richiedere, trasferire e visualizzare pic.webp. Tutti i browser senza supporto per WebP ignoreranno il source e, in assenza di istruzioni contrarie, <img> mostrerà i contenuti di src come fa dal 1992. Qui non è necessario specificare un secondo elemento <source> con type="image/jpeg", puoi presumere che il supporto sia universale per JPEG.

Indipendentemente dal contesto di navigazione dell'utente, tutto questo si ottiene con un singolo trasferimento di file, senza sprechi di larghezza di banda per le origini delle immagini che non possono essere visualizzate. Anche questo è un approccio lungimirante: dato che formati di file più recenti ed efficienti verranno integrati i tipi di media propri e potremo sfruttarli grazie a picture, senza JavaScript, senza dipendenze lato server e con tutta la velocità di <img>.

Il futuro delle immagini adattabili

Tutti i pattern di markup qui presentati sono stati un grosso passo avanti in termini di standardizzazione: cambiare la funzionalità di qualcosa consolidato e centrale per il web come <img> non era cosa da poco, e la serie di problemi che quelle modifiche puntavano a risolvere erano a dir poco ampie. Se hai notato che ci sono molti margini di miglioramento con questi pattern di markup, hai assolutamente ragione. Fin dall'inizio, questi standard sono stati pensati per fornire una base di partenza per le tecnologie future.

Tutte queste soluzioni dipendono necessariamente dal markup, in modo da essere incluse nel payload iniziale del server e arrivano in tempo utile perché il browser richieda le origini delle immagini, una limitazione che ha portato a un attributo sizes, certamente poco gestibile.

Tuttavia, poiché queste funzionalità sono state introdotte sulla piattaforma web, è stato introdotto un metodo nativo per posticipare le richieste di immagine. Gli elementi <img> con l'attributo loading="lazy" non vengono richiesti finché il layout della pagina non è noto, al fine di rinviare le richieste di immagini al di fuori dell'area visibile iniziale dell'utente a un momento successivo nel processo di rendering della pagina, evitando potenzialmente richieste non necessarie. Poiché il browser comprende appieno il layout della pagina quando vengono effettuate queste richieste, in questi casi è stato proposto un attributo sizes="auto" in aggiunta alla specifica HTML per evitare di dover scrivere manualmente gli attributi sizes.

Inoltre, all'orizzonte ci sono anche aggiunte all'elemento <picture>, per abbinare alcune modifiche eccezionalmente entusiasmanti al modo in cui stiliamo i layout di pagina. Anche se le informazioni relative all'area visibile sono una base valida per decisioni sul layout di alto livello, ci impediscono di adottare un approccio allo sviluppo completamente a livello di componente, ovvero un componente che può essere inserito in qualsiasi parte del layout di una pagina, con stili che rispondono allo spazio occupato dal componente stesso. Questo problema ha portato alla creazione delle query del container, ovvero un metodo di stile degli elementi in base alle dimensioni del contenitore principale, anziché solo all'area visibile.

Sebbene la sintassi delle query relative ai container si sia appena stabilizzata e il supporto del browser è molto limitato, al momento della scrittura, l'aggiunta delle tecnologie del browser che la attivano fornirà all'elemento <picture> lo stesso modo: un potenziale attributo container che consente criteri di selezione <source> in base allo spazio occupato dall'elemento <img> dell'elemento <picture>, anziché in base alle dimensioni dell'area visibile.

Se sembra un po' vago, beh, c'è una buona ragione: queste discussioni sugli standard web sono in corso, ma tutt'altro che risolte: non puoi ancora utilizzarle.

Anche se il markup delle immagini reattive promette di semplificare l'utilizzo con il passare del tempo, come qualsiasi tecnologia web, esistono una serie di servizi, tecnologie e framework che contribuiscono a rendere disponibile questo markup a mano libera. Nel prossimo modulo, vedremo come integrare tutto ciò che abbiamo appreso sui formati delle immagini, sulla compressione e sulle immagini adattabili in un flusso di lavoro di sviluppo moderno.