Layout simile a una rivista per il Web con regioni ed esclusioni CSS

Christian Cantrell
Christian Cantrell

Introduzione

Il web è una piattaforma estremamente potente per il testo, un'area in cui Adobe ha una grande esperienza e competenza. Quando Adobe cercava modi per contribuire a far progredire il web, migliorare ulteriormente le funzionalità di testo del web ci è sembrato un punto di partenza ovvio. In genere, il web presuppone un'unica colonna e un orientamento verticale per il testo. Sebbene sia possibile far scorrere il testo attorno alle immagini e persino formattarlo in più colonne con CSS, è ancora molto difficile ottenere un layout simile a quello di una rivista sul web. Con le regioni CSS e le esclusioni CSS, Adobe è in prima linea nell'impegno per portare la potenza del desktop publishing ai browser moderni. Ad esempio, nello screenshot seguente le esclusioni CSS vengono utilizzate per far scorrere il testo lungo il contorno della montagna:

Esempio di esclusioni CSS in azione
Esempio di esclusioni CSS in azione

Il documento nello screenshot di seguito utilizza anche le esclusioni CSS per consentire il rientro del testo attorno alle forme nelle immagini, nonché le regioni CSS per formattare il testo in colonne e attorno a una citazione in evidenza:

Esempio di regioni CSS in azione
Esempio di regioni CSS in azione

Regioni CSS

Prima di entrare nei dettagli delle regioni CSS, vorrei spiegare come possono essere attivate in Google Chrome. Una volta attivate le regioni CSS, puoi provare alcuni dei sample a cui si fa riferimento in questo articolo e crearne di tuoi.

Attivazione delle regioni CSS in Google Chrome

A partire dalla versione 20 di Chrome (20.0.1132.57, per l'esattezza), le regioni CSS sono attivate tramite l'interfaccia chrome://flags. Per attivare le regioni CSS:

  1. Apri una nuova scheda o finestra in Chrome.
  2. Digita chrome://flags nella barra di ricerca.
  3. Utilizza la funzionalità Cerca nella pagina (Ctrl/Comando + F) e cerca la sezione "Funzionalità sperimentali della piattaforma web".
  4. Fai clic sul link Attiva.
  5. Fai clic sul pulsante Riavvia ora in basso.

Per ulteriori informazioni sui flag di Chrome, leggi il mio post del blog All About Chrome Flags.

Dopo aver riavviato il browser, puoi iniziare a fare esperimenti con le regioni CSS.

Panoramica delle regioni CSS

Le regioni CSS consentono a un blocco di testo con markup semantico di essere inserito automaticamente in "caselle" (attualmente elementi). Il diagramma seguente mostra la separazione del testo (il flusso) e delle caselle (le regioni in cui scorre il testo):

I contenuti vengono inseriti in regioni definite
I contenuti vengono inseriti in regioni definite

Diamo un'occhiata a un caso d'uso reale di regioni CSS. Oltre a essere uno sviluppatore di Adobe, sono anche uno scrittore di fantascienza. Pubblico spesso i miei lavori online con una licenza Creative Commons e, per consentirne il funzionamento sul maggior numero possibile di dispositivi e browser, utilizzo spesso un formato estremamente semplice simile a questo:

Esempio di progetto legacy con persone non stilizzato
Esempio di progetto legacy con persone senza stile

Utilizzando le regioni CSS, ho potuto creare un'esperienza più interessante dal punto di vista visivo e molto più funzionale, in quanto è più facile da navigare e più comoda da leggere:

Progetto Legacy umano che mostra la regione
Progetto precedente con regioni
.

A scopo dimostrativo, ho aggiunto la possibilità di mostrare le regioni CSS in questo prototipo. Lo screenshot seguente mostra come le regioni sono disposte in modo da dare l'impressione di essere colonne che avvolgono un'immagine e una citazione in primo piano al centro:

Progetto Legacy umano che mostra le regioni
Progetto Legacy per le persone che mostra le regioni

Puoi fare esperimenti con questo prototipo (nonché visualizzare il codice sorgente) qui. Utilizza i tasti freccia per spostarti e premi il tasto Esc per visualizzare le regioni. I prototipi precedenti sono disponibili anche qui.

Creazione di un flusso denominato

Il CSS necessario per far scorrere un blocco di testo tra le regioni è estremamente semplice. Lo snippet riportato di seguito assegna un flusso denominato "articolo" a un div con l'ID "contenuto" e assegna lo stesso flusso denominato "articolo" a qualsiasi elemento con la classe "regione". Il risultato è che il testo contenuto all'interno dell'elemento "content" verrà visualizzato automaticamente in qualsiasi elemento con la classe "region".

<!DOCTYPE html>
<html>
<head>
    <style>
    #content {
        { % mixin flow-into: article; % }
    }

    .region {
        { % mixin flow-from: article; % }
        box-sizing: border-box;
        position: absolute;
        width: 200px;
        height: 200px;
        padding: 10px;
    }

    #box-a {
        border: 1px solid red;
        top: 10px;
        left: 10px;
    }

    #box-b {
        border: 1px solid green;
        top: 210px;
        left: 210px;
    }

    #box-c {
        border: 1px solid blue;
        top: 410px;
        left: 410px;
    }
    </style>
</head>
<body>
    <div id="box-a" class="region"></div>
    <div id="box-b" class="region"></div>
    <div id="box-c" class="region"></div>
    <div id="content">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent eleifend dapibus felis, a consectetur nisl aliquam at. Aliquam quam augue, molestie a scelerisque nec, accumsan non metus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin cursus euismod nisi, a egestas sem rhoncus eget. Mauris non tortor arcu. Pellentesque in odio at leo volutpat consequat....
    </div>
</body>
</html>

Il risultato sarà simile al seguente:

Risultato del codice precedente
Risultato del codice precedente

Tieni presente che il testo all'interno del div"content" non ha alcuna conoscenza della sua presentazione. In altre parole, può rimanere completamente semanticamente intatto anche mentre attraversa varie regioni. Inoltre, poiché le regioni sono solo elementi, vengono posizionate e ridimensionate utilizzando il CSS come qualsiasi altro elemento e sono quindi perfettamente compatibili con i principi del responsive design. Designare gli elementi come parte di un flusso denominato significa semplicemente che il testo specificato li attraversa automaticamente.

Il modello oggetto CSS

Il modello oggetto CSS, o CSSOM, definisce le API JavaScript per lavorare con i CSS. Di seguito è riportato un elenco delle nuove API relative alle regioni CSS:

  • document.webkitGetNamedFlows(): una funzione che restituisce la raccolta di flussi con nome disponibili nel documento.
  • document.webkitGetNamedFlows().namedItem("article"): una funzione che restituisce un riferimento a un flusso denominato specifico. L'argomento corrisponde al nome specificato come valore delle proprietà CSS flow-into e from-from. Per ottenere un riferimento al flusso denominato specificato nello snippet di codice riportato sopra, devi passare la stringa "articolo".
  • WebKitNamedFlow: una rappresentazione oggetto di una banchisa denominata con le seguenti proprietà e funzioni:
    • firstEmptyRegionIndex: un valore intero che punta all'indice della prima regione vuota associata al flusso denominato. Consulta getRegions() di seguito per scoprire come ottenere la raccolta di regioni.
    • name: un valore di stringa con il nome del flusso.
    • overset: una proprietà booleana che:
      • false quando i contenuti del flusso denominato rientrano nelle regioni associate
      • true quando i contenuti non si adattano e sono necessarie più regioni per contenerli tutti.
    • getContent(): una funzione che restituisce una raccolta con i riferimenti ai nodi che confluiscono nel flusso denominato.
    • getRegions(): una funzione che restituisce una raccolta con riferimenti alle regioni che contengono i contenuti del flusso denominato.
    • getRegionsByContentNode(node): una funzione che restituisce un riferimento alla regione contenente il nodo specificato. Questo è particolarmente utile per trovare regioni contenenti elementi come ancore con nome.
  • Evento webkitregionoversetchange. Questo evento viene attivato in un WebkitNamedFlow ogni volta che il layout dei contenuti associati cambia per qualsiasi motivo (contenuti aggiunti o rimossi, dimensioni dei caratteri modificate, forma della regione modificata e così via) e provoca la modifica della proprietà webkitRegionOverset di una regione. Questo evento è utile per ascoltare le modifiche grossolane del layout. È un indicatore che è successo qualcosa di importante e che il layout potrebbe richiedere attenzione, ad esempio: sono necessarie più regioni, alcune regioni potrebbero essere vuote e così via.
  • Evento webkitregionfragmentchange. Non implementato al momento di questa modifica. Questo evento viene attivato su un WebkitNamedFlow ogni volta che il layout dei contenuti associati cambia per qualsiasi motivo, in modo simile a webkitregionoversetchange, ma indipendentemente da eventuali modifiche alle proprietà webkitRegionOverset. Questo evento è utile per rilevare modifiche granulari del layout che non influiscono necessariamente sull'intero layout del flusso denominato, ad esempio: i contenuti passano da una regione all'altra, ma i contenuti complessivi si adattano comunque a tutte le regioni.
  • Element.webkitRegionOverset: gli elementi diventano regioni quando è assegnata loro la proprietà CSS flow-from. Questi elementi hanno una proprietà webkitRegionOverset che, se fanno parte di un flusso denominato, indica se i contenuti di un flusso superano o meno la regione. I valori possibili di webkitRegionOverset sono:
    • "overflow" se i contenuti sono più di quelli che la regione può contenere
    • "fit" se i contenuti si interrompono prima della fine della regione
    • "empty" se i contenuti non hanno raggiunto la regione

Uno degli utilizzi principali del CSSOM è l'ascolto di eventi webkitregionoversetchange e l'aggiunta o la rimozione dinamica di regioni per adattarsi a quantità variabili di testo. Ad esempio, se la quantità di testo da formattare è imprevedibile (ad esempio generata dall'utente), se la finestra del browser viene ridimensionata o se le dimensioni dei caratteri cambiano, potrebbe essere necessario aggiungere o rimuovere regioni per adattarsi alla modifica del flusso. Inoltre, se vuoi organizzare i contenuti in pagine, avrai bisogno di un meccanismo per modificare dinamicamente il DOM e le regioni.

Il seguente snippet di codice JavaScript mostra l'utilizzo del CSSOM per aggiungere dinamicamente le regioni in base alle necessità. Tieni presente che, per semplicità, non gestisce la rimozione delle regioni o la definizione delle dimensioni e delle posizioni delle regioni. È solo a scopo dimostrativo.

var flow = document.webkitGetNamedFlows().namedItem("article")
flow.addEventListener("webkitregionoversetchange", onLayoutUpdate);

function onLayoutUpdate(event) {
    var flow = event.target;
    
    // The content does not fit
    if (flow.overset === true) {
    addRegion();
    } else {
    regionLayoutComplete();
    }
}

function addRegion() {
    var region = document.createElement("div");
    region.style = "flow-from: article";
    document.body.appendChild(region);
}

function regionLayoutComplete() {
    // Finish up your layout.
}

Altri esempi sono disponibili nella pagina Samples di regioni CSS.

Modelli di pagina CSS

Sfruttare il CSSOM è probabilmente il modo più efficace e flessibile per implementare funzionalità come la paginazione e il layout responsive, ma Adobe lavora con strumenti di desktop publishing e di testo da tempo sufficiente per sapere che anche designer e sviluppatori vorranno un modo più semplice per ottenere funzionalità di paginazione relativamente generiche. Pertanto, stiamo lavorando a una proposta chiamata Modelli di pagina CSS che consente di definire il comportamento di paginazione in modo completamente dichiarativo.

Diamo un'occhiata a un caso d'uso comune per i modelli di pagina CSS. Lo snippet di codice riportato di seguito mostra l'utilizzo del CSS per creare due flussi denominati: "article-flow" e "timeline-flow". Inoltre, definisce un terzo selettore denominato "combined-articles" all'interno del quale saranno contenuti i due flussi. La semplice inclusione della proprietà overflow-style all'interno del selettore "combined-articles" indica che i contenuti devono essere suddivisi automaticamente in pagine lungo l'asse x o orizzontalmente:

<style>
    #article {
    { % mixin flow-into: article-flow; % }
    }

    #timeline {
    { % mixin flow-into: timeline-flow; % }
    }

    #combined-articles {
    overflow-style: paged-x;
    }
</style>

Ora che i flussi sono stati definiti e il comportamento di overflow desiderato è stato specificato, possiamo creare il modello di pagina stesso:

@template {
    @slot left {
    width: 35%;
    float: left;
    { % mixin flow-from: article-flow; % }
    }

    @slot time {
    width: 25%;
    float: left;
    { % mixin flow-from: timeline-flow; % }
    }

    @slot right {
    width: 35%;
    float: left;
    { % mixin flow-from: article-flow; % }
    }
}

I modelli di pagina vengono definiti utilizzando la nuova sintassi "at". Nel frammento di codice riportato sopra, definiamo tre slot, ciascuno corrispondente a una colonna. Il testo di "article-flow" verrà visualizzato nelle colonne a sinistra e a destra, mentre il testo di "timeline-flow" verrà inserito nella colonna al centro. Il risultato potrebbe avere il seguente aspetto:

Esempio di modelli di pagina
Esempio di modelli di pagina

Tieni presente che il testo dell'articolo, ovvero il testo nelle colonne a sinistra e a destra, è in inglese, mentre la cronologia al centro è in tedesco. Inoltre, le pagine del documento vengono visualizzate orizzontalmente senza la necessità di alcun codice JavaScript. Tutto è stato fatto in modo completamente dichiarativo in CSS.

I modelli di pagina CSS sono ancora una proposta, ma abbiamo un prototipo che utilizza un "shim" JavaScript (noto anche come polyfill) per consentirti di sperimentarli subito.

Per saperne di più sulle regioni CSS in generale, consulta la pagina Regioni CSS su html.adobe.com.

Esclusioni CSS

Per ottenere un layout simile a quello di una rivista, non è sufficiente poter far scorrere il testo nelle regioni. Un elemento fondamentale del desktop publishing di alta qualità e visivamente interessante è la capacità di far scorrere il testo attorno o all'interno di elementi grafici e forme irregolari. Le esclusioni CSS offrono questo livello di qualità di produzione sul web.

Lo screenshot seguente è tratto da un prototipo di esclusioni CSS e mostra il testo che scorre dinamicamente lungo un percorso che corrisponde al contorno di una grande formazione rocciosa:

Esempio di esclusioni CSS in azione
Esempio di esclusioni CSS in azione

Il contrario è illustrato nello screenshot successivo: il testo scorre all'interno di poligoni di forma irregolare:

Testo che si inserisce in poligoni di forma irregolare
Testo che scorre in poligoni di forma irregolare

Il primo passaggio per poter far scorrere il testo attorno o all'interno di forme arbitrarie consiste nello sviluppare e ottimizzare gli algoritmi richiesti. Adobe sta attualmente lavorando a implementazioni che verranno fornite direttamente a WebKit. Una volta ottimizzati, questi algoritmi diventeranno le basi su cui verranno costruite le altre esclusioni CSS.

Per saperne di più sulle esclusioni CSS, consulta la pagina Esclusioni CSS su html.adobe.com e, per un'analisi più dettagliata del lavoro di Adobe sulla tecnologia di base per le esclusioni CSS, leggi il post del blog di Hans Muller intitolato Riquadro orizzontale: intersezione di poligoni per le esclusioni CSS.

Stato attuale delle regioni CSS e delle esclusioni CSS

La prima volta che ho parlato pubblicamente di regioni CSS ed esclusioni CSS è stato nel pod per sviluppatori Adobe al Google I/O 2011. All'epoca, stavo mostrando le demo nel nostro browser di prototipi personalizzato. L'accoglienza è stata estremamente entusiasta, ma c'è stato un palpabile senso di delusione quando gli spettatori hanno scoperto che nessuna delle funzionalità che stavo mostrando era ancora disponibile in nessuno dei principali browser.

Quest'anno (2012) ho partecipato di nuovo a Google I/O, questa volta come presentatore insieme al mio collega Vincent Hardy e ad Alex Danilo di Google (puoi guardare la presentazione qui). Solo un anno dopo, circa l'80% della specifica delle regioni CSS è stata implementata in WebKit ed è già presente nella versione più recente di Google Chrome (tieni presente che al momento le regioni CSS devono essere attivate tramite chrome://flags). Il supporto preliminare per le regioni CSS è stato implementato anche in Chrome per Android:

Regioni su Chrome per Android
Regioni su Chrome per Android

Inoltre, sia le regioni CSS che le esclusioni CSS sono implementate nella versione di anteprima di Internet Explorer 10 e sono attualmente nella roadmap di Mozilla per Firefox del 2012. La prossima versione principale di Safari dovrebbe supportare la maggior parte della specifica delle regioni CSS e gli aggiornamenti successivi dovrebbero includere il resto.

Di seguito è riportata una sequenza temporale dettagliata dei progressi compiuti con le regioni CSS e le esclusioni CSS dalla nostra proposta iniziale al W3C nell'aprile 2011:

Aggiornamento delle regioni e delle esclusioni
Avanzamento delle regioni e delle esclusioni

Conclusione

Adobe ha una vasta esperienza con testo, caratteri e desktop publishing in generale tramite strumenti come InDesign. Anche se il web è già una piattaforma molto potente per il testo, vogliamo utilizzare le nostre conoscenze ed esperienze per migliorare ulteriormente la presentazione del testo. Le regioni CSS e le esclusioni CSS consentono ai contenuti di rimanere strutturati semanticamente, consentendo al contempo un layout simile a quello di una rivista e, in definitiva, un web molto più espressivo.