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

Christian Cantrell
Christian Cantrell

Introduzione

Il web è una piattaforma di testo estremamente potente, un'area in cui Adobe ha una grande esperienza e competenza. Quando Adobe stava cercando modi per far progredire il web, quindi, il miglioramento delle funzionalità di testo del web sembrava un punto di partenza ovvio. Generalmente, il Web prevede una singola colonna con orientamento verticale per il testo. Sebbene sia possibile far scorrere il testo intorno alle immagini e persino formattare il testo in più colonne con CSS, è comunque molto difficile ottenere un vero layout simile a una rivista sul web. Con le regioni CSS ed le esclusioni CSS, Adobe sta promuovendo il lavoro di portare la potenza del desktop Publishing nei browser moderni. Ad esempio, nello screenshot di seguito, le esclusioni CSS vengono utilizzate per far scorrere il testo lungo il contorno della montagna:

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

Anche nel documento nello screenshot di seguito vengono utilizzate le esclusioni CSS per consentire al testo di avvolgere le forme nelle immagini, nonché le regioni CSS per formattare il testo in colonne e intorno a una citazione:

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

Regioni CSS

Prima di entrare nel dettaglio delle regioni CSS, vorrei spiegarti come attivarle in Google Chrome. Dopo aver attivato le regioni CSS, puoi provare alcuni degli esempi indicati in questo articolo e crearne di nuovi.

Attivare le regioni CSS in Google Chrome

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

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

Per ulteriori informazioni sui flag di Chrome, vedi il mio post del blog Tutto sui flag di Chrome.

Una volta riavviato il browser, potrai iniziare a sperimentare le regioni CSS.

Panoramica delle regioni CSS

La sezione Regioni CSS consente a un blocco di testo con markup semantico di confluire automaticamente in "caselle" (al momento elementi). Il diagramma seguente mostra la separazione tra testo (flusso) e caselle (le aree in cui scorre il testo):

I contenuti confluiscono in regioni definite
I contenuti passano in regioni definite

Diamo un'occhiata a un caso d'uso effettivo delle 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 poter funzionare sul numero massimo di dispositivi e browser, spesso utilizzo un formato estremamente semplice simile a questo:

Esempio di progetto legacy umano senza stile
Esempio di progetto di eredità umana senza stile

Utilizzando le regioni CSS, sono riuscito a creare un'esperienza visivamente più interessante e molto più funzionale, in quanto risulta più semplice da navigare e più comoda da leggere:

Progetto legacy umano che mostra la regione
Progetto Human Legacy con regioni.

A scopo dimostrativo, ho aggiunto la possibilità di mostrare le regioni CSS in questo prototipo. Il seguente screenshot mostra come sono disposte le regioni in modo da dare l'impressione di essere colonne disposte attorno a un grafico e a una citazione al centro:

Progetto legacy umano che mostra le regioni
Progetto Human Legacy che mostra le regioni

Puoi fare degli esperimenti con questo prototipo (e 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 richiesto per far passare un blocco di testo attraverso le regioni è estremamente semplice. Lo snippet riportato di seguito assegna un flusso denominato "article" a un div con ID "content" e lo stesso flusso denominato "article" a qualsiasi elemento con la classe "region". Il risultato è che il testo contenuto nell'elemento "content" passerà automaticamente attraverso 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 a questo:

Risultato del codice precedente
Risultato del codice riportato sopra

Tieni presente che il testo all'interno del div"contenuti" non è a conoscenza della sua presentazione. In altre parole, può rimanere interamente semanticamente intatta anche se attraversa varie regioni. Inoltre, poiché le regioni sono solo elementi, vengono posizionate e ridimensionate utilizzando CSS come qualsiasi altro elemento e pertanto sono perfettamente compatibili con i principi del reattivo design. La designazione di elementi come parte di un flusso denominato significa semplicemente che il testo specificato scorre automaticamente attraverso di essi.

Il modello a oggetti CSS

Il modello di oggetti CSS, o CSSOM, definisce le API JavaScript per l'utilizzo di CSS. Di seguito è riportato un elenco delle nuove API correlate alle regioni CSS:

  • document.webkitGetNamedFlows(): una funzione che restituisce la raccolta di flussi denominati 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 precedente, devi passare la stringa "article".
  • WebKitNamedFlow: una rappresentazione oggetto di un piano denominato 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 delle regioni.
    • name: un valore stringa con il nome del flusso.
    • overset: una proprietà booleana che ha le seguenti caratteristiche:
      • false quando i contenuti del flusso denominato si adattano alle regioni associate
      • true quando i contenuti non sono adatti e tutte le regioni devono includere tutti i contenuti.
    • getContent(): una funzione che restituisce una raccolta con 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. Ciò è particolarmente utile per trovare regioni contenenti elementi come anchor con nome.
  • webkitregionoversetchange evento. Questo evento viene attivato su un WebkitNamedFlow ogni volta che, per qualsiasi motivo, il layout dei contenuti associati cambia (contenuti vengono aggiunti o rimossi, le dimensioni dei caratteri cambiano, la forma della regione e così via) e provoca la modifica della proprietà webkitRegionOverset di una regione. Questo evento è utile per ascoltare modifiche approssimative al layout. Indicano che si è verificato qualcosa di importante e che il layout potrebbe richiedere attenzione, ad esempio: sono necessarie più regioni, alcune potrebbero essere vuote e così via.
  • webkitregionfragmentchange evento. Non implementata al momento di questa modifica. Questo evento viene attivato su un WebkitNamedFlow ogni volta che il layout dei contenuti associati cambia per qualsiasi motivo, come accade per webkitregionoversetchange, ma indipendentemente da eventuali modifiche nelle proprietà webkitRegionOverset. Questo evento è utile per esaminare modifiche granulari al layout che non influiscono necessariamente sull'intero layout del flusso denominato, ad esempio: i contenuti si spostano da una regione all'altra, ma i contenuti complessivi rientrano comunque in tutte le regioni.
  • Element.webkitRegionOverset: gli elementi diventano regioni se hanno la proprietà CSS flow-from assegnata. Questi elementi hanno una proprietà webkitRegionOverset che, se fanno parte di un flusso denominato, indica se i contenuti di un flusso eccedono la regione. I valori possibili webkitRegionOverset sono:
    • "overflow" se ci sono più contenuti di quanto la regione possa contenere
    • "fit" se i contenuti si interrompono prima della fine della regione
    • "vuoto" se i contenuti non raggiungono la regione

Uno degli utilizzi principali del CSSOM è l'ascolto degli eventi webkitregionoversetchange e l'aggiunta o la rimozione dinamica delle regioni per supportare diverse quantità 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 la dimensione del carattere cambia, potrebbe essere necessario aggiungere o rimuovere regioni per adattarsi al cambiamento nel 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 esigenze. Tieni presente che, per semplicità, non gestisce la rimozione delle regioni o la definizione delle dimensioni e delle posizioni delle regioni, ma è 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.
}

Altre demo sono disponibili nella pagina di esempi per le regioni CSS.

Modelli di pagina CSS

L'utilizzo del CSSOM è probabilmente il modo più potente e flessibile per implementare elementi come il paging e il layout reattivo, ma Adobe sta lavorando abbastanza a lungo con strumenti di pubblicazione di testo e desktop da far sapere che designer e sviluppatori vorranno anche un modo più semplice per ottenere funzionalità di paging relativamente generiche. Per questo motivo, stiamo lavorando a una proposta chiamata Modelli di pagina CSS, che consente di definire il comportamento del paging in modo completamente dichiarativo.

Vediamo un caso d'uso comune per i modelli di pagina CSS. Lo snippet di codice riportato di seguito mostra l'utilizzo di CSS per creare due flussi denominati: "article-flow" e "timeline-flow". Inoltre, definisce un terzo selettore chiamato "combined-articles" all'interno del quale saranno contenuti i due flussi. La semplice inclusione della proprietà overflow-style nel selettore "combined-articles" indica che i contenuti devono essere impaginati automaticamente sull'asse x oppure 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". Nello snippet di codice riportato sopra, vengono definite tre aree, ciascuna corrispondente a una colonna. Il testo di "flusso della cronologia" scorrerà attraverso le colonne a sinistra e destra, mentre il testo di "flusso della cronologia" completerà la colonna al centro. Il risultato potrebbe essere simile al seguente:

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 e la sequenza temporale al centro è in tedesco. Inoltre, le pagine del documento sono orizzontali senza bisogno di alcun codice JavaScript. Tutto è stato fatto in modo dichiarativo in CSS.

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

Per scoprire di più sulle regioni CSS in generale, consulta la pagina delle regioni CSS sul sito html.adobe.com.

Esclusioni CSS

Per ottenere un vero layout simile a una rivista, non è sufficiente essere in grado di far scorrere il testo attraverso le regioni. Un elemento fondamentale della pubblicazione desktop di alta qualità e visivamente interessante è la capacità di far scorrere il testo intorno o all'interno di grafica e forme irregolari. Le esclusioni CSS portano al web questo livello di qualità della produzione.

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

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

Nello screenshot successivo è illustrato l'inverso: testo che scorre all'interno di poligoni di forma irregolare:

Testo che scorre all&#39;interno di poligoni di forma irregolare
Testo che scorre all'interno di poligoni di forma irregolare

Il primo passo per essere in grado di far scorrere il testo intorno o all'interno di forme arbitrarie è sviluppare e ottimizzare gli algoritmi richiesti. Adobe si sta occupando di implementazioni che contribuiranno direttamente a WebKit. Una volta ottimizzati, questi algoritmi diventeranno le basi, oltre a creare le altre esclusioni CSS.

Per ulteriori informazioni sulle esclusioni CSS, consulta la pagina Esclusioni CSS all'indirizzo html.adobe.com e per un approfondimento sul lavoro di Adobe sulla tecnologia di base per le esclusioni CSS, consulta il post del blog di Hans Muller intitolato Horizontal Box: Polygon Intersection for CSS Esclusioni.

Lo stato attuale delle regioni e delle esclusioni CSS

La prima volta che ho parlato pubblicamente di regioni CSS ed esclusioni CSS è stata in occasione dell'Adobe Developer Pod alla conferenza Google I/O 2011. All'epoca mostravo le demo nel nostro prototipo di browser personalizzato. L'accoglienza era estremamente entusiasta, tuttavia c'era un palpabile senso di delusione quando gli spettatori scoprivano che nessuna delle funzionalità che stavo mostrando era ancora disponibile in nessuno dei principali browser.

Ho partecipato di nuovo alla conferenza Google I/O quest'anno (2012), questa volta come presentatore insieme ai miei colleghi Vincent Hardy e Alex Danilo di Google (puoi guardare la presentazione qui). Appena un anno dopo, circa l'80% della specifica per le 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 è arrivato persino 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 nell'anteprima di Internet Explorer 10 e sono attualmente in fase di roadmap di Mozilla 2012 per Firefox. La prossima versione principale di Safari dovrebbe supportare la maggior parte delle specifiche delle regioni CSS e i successivi aggiornamenti dovrebbero includere il resto.

Di seguito è riportata una cronologia dettagliata dei progressi compiuti in relazione alle regioni e alle esclusioni CSS in seguito alla nostra proposta iniziale al W3C di aprile 2011:

Avanzamento regione ed esclusione
Avanzamento per regioni ed esclusioni

Conclusione

Adobe ha una grande esperienza con i testi, i caratteri e la pubblicazione su desktop in generale grazie a strumenti come InDesign. Sebbene il web sia già una piattaforma molto potente per il testo, vogliamo utilizzare le nostre conoscenze ed esperienze per ottimizzare ulteriormente la presentazione dei testi. Le regioni CSS ed le esclusioni CSS consentono ai contenuti di rimanere strutturati semanticamente, consentendo al contempo di offrire un vero layout simile a quello di una rivista e, in ultima analisi, un web molto più espressivo.