Capitolo 4.   I fogli di stile

In questo capitolo vengono esaminati gli aspetti fondamentali della natura e dell'uso dei «fogli di stile a cascata» o CSS (Cascading Style Sheet) della cui importanza si è già accennato precedentemente.

4.1   Caratteristiche dei fogli di stile

I CSS sono raccolte di regole riguardanti la presentazione di un documento HTML e che non influiscono sulla sua struttura interna.

Questo è un primo motivo per cui essi si fanno preferire rispetto ai tag HTML utilizzabili per variare l'aspetto del documento.

Altri vantaggi sono: la maggiore varietà di «interventi» realizzabili, grazie ai CSS, sull'aspetto della pagina; la possibilità di creare facilmente un'unica definizione delle caratteristiche di un certo sito esternamente alle sue pagine, cosa che porta un duplice ulteriore beneficio:

Occorre comunque segnalare che, a fronte di questi vantaggi, i fogli di stile presentano anche un inconveniente dovuto al mancato rispetto degli standard CSS da parte di qualche programma di navigazione; può infatti accadere che le stessa pagina, costruita con determinate regole di stile, venga visualizzata in modo diverso da browser diversi.

Al momento gli standard riguardanti i fogli di stile, rilasciati dal W3C, sono CSS1, CSS2 e CSS3; la sintassi non prevede distinzione fra maiuscole e minuscole ma in queste dispense si preferisce l'uso delle minuscole in coerenza con la scelta fatta riguardo ai sorgenti HTML.

4.2   Struttura delle regole di stile

Un foglio di stile è costituito da varie regole ognuna delle quali formata da un «selettore» e da un «blocco di dichiarazioni»; ogni dichiarazione consiste poi nell'associazione tra una «proprietà» e il relativo «valore».

L'insieme delle dichiarazioni deve essere racchiuso tra i simboli «{» e «}»; ogni dichiarazione deve essere conclusa con «;» e fra proprietà e rispettivo valore deve essere inserito un «:».

Il selettore determina, nell'ambito del documento HTML che fa uso di quella regola di stile, a quale elemento o a quali elementi si applicano le formattazioni specificate con le successive dichiarazioni.

Dei modi con cui le regole di stile possono essere associate a un documento HTML si occupa il prossimo paragrafo (4.3).

Come primo esempio di regola di stile si consideri la seguente:

h1 {color: red; font-style: italic;}

Anche senza conoscere ulteriori dettagli sulla definizione delle regole di stile è abbastanza semplice capire che la regola in questione permette di ottenere intestazioni di primo livello (selettore h1) con testo di colore rosso e in corsivo.

4.2.1   Definizione dei selettori

Un selettore può definire gli elementi da formattare nei seguenti modi:

La definizione può anche avvenire combinando uno o più dei succitati criteri.

Inoltre è possibile applicare le stesse dichiarazioni a più selettori semplicemente elencandoli separati da una «,».

4.2.1.1   Selettori basati sul nome di elementi

Questa categoria di selettori è molto semplice in quanto gli elementi cui si vogliono applicare le regole si identificano con il nome che hanno nel linguaggio HTML.

Nell'esempio precedente si è visto un selettore di questo tipo, identificato con h1, che permette di applicare le regole specificate nelle successive dichiarazioni a tutti i marcatori <h1>.

Vediamo un altro esempio con il quale facciamo in modo che tutti i paragrafi e le intestazioni di livello tre abbiano testo di colore verde e giustificato:

p,h3 {color: green; text-align: justify;}

4.2.1.2   Selettori di classe e selettori ID

Attraverso le classi e gli ID si possono specificare regole da applicare in modo indipendente dai marcatori HTML.

Una classe si definisce utilizzando il simbolo «.» seguito dal nome della classe e preceduto (non obbligatoriamente) dal nome di un marcatore.

Vediamo un esempio:

p.classe1 {color: red; text-align: left;}
.classe2 {font-weight: bold;}

In questo modo vengono definita una classe classe1 relativa al marcatore <p> e una classe classe2 relativa a qualsiasi marcatore.

Nel codice HTML si può fare riferimento a queste regole usando l'attributo class per i tag cui si vogliono applicare; ad esempio:

<h1 class="classe2">Titolo di classe2</h1>
<p class="classe1">
Testo di colore rosso e allineato a sinistra</p>
<p>
Paragrafo normale</p>
<p class="classe2">
Paragrafo con caratteri in grassetto</p>

Come si vede la classe classe2 si può associare a qualsiasi tag, mentre la classe classe1 solo a marcatori <p>.

Un ID si definisce utilizzando il simbolo «#» seguito dal nome della classe e preceduto (non obbligatoriamente) dal nome di un marcatore.

Vediamo un esempio:

#ident1 {color: green; font-style: italic;}

Nel codice HTML si può fare riferimento a questa regola usando l'attributo id per il tag cui si vuole applicare tali formattazioni, ad esempio nel modo seguente:

<h1 id="ident1">Titolo con ID ident1</h1>
<p>
Paragrafo normale</p>

La differenza fondamentale tra i selettori di classe e i selettori ID è che i primi si possono usare in associazione a quanti si vuole elementi, i secondi invece una sola volta all'interno di un documento HTML.

Quindi le regole da utilizzare per molteplici elementi del documento si definiranno per selettori di classe, mentre quelle uniche per selettori di ID.

Gli ID hanno il vantaggio che possono funzionare da segnaposti individuabili dai programmi di navigazione; se abbiamo un indirizzo come http://www.dominio.it#id1, il browser cerca di localizzare l’elemento con ID id1 e se lo trova si posiziona in quel punto della pagina.

Notiamo comunque che un tag può tranquillamente essere associato contemporaneamente ad una classe e ad un ID in modo da avere delle peculiarità comuni anche ad altri elementi e contemporaneamente altre uniche, oltre che essere essere individuabile facilmente dal programma di navigazione.

4.2.1.3   Selettori in base a attributi e valori

La selezione di marcatori può avvenire anche in base alla presenza di un attributo oppure di un attributo con un dato valore (anche parziale); l'indicazione dell'attributo, semplice o valorizzato deve avvenire tra i simboli «[» e «]».

L'esempio seguente mostra nell'ordine l'uso di un selettore di attributo semplice, di un selettore di attributo esatto e di un selettore di attributo parziale (si noti in questo caso l'uso dell'operatore «~=»):

[align] {font-style: italic;}
a[href="www.google.com"] {font-weight: bold;}
a[href~="google"] {font-weight: bold;}

4.2.1.4   Selettori in base al contesto

I selettori basati sul contesto tengono conto della struttura del documento HTML e permettono di fare riferimento a marcatori che sono «discendenti», «figli», «adiacenti» di altri marcatori.

Un marcatore è discendente di un altro (che viene detto «antenato») quando è annidato in esso a un qualunque livello di profondità; è invece figlio di un marcatore (che viene detto «genitore») se è un discendente diretto; infine due marcatori si dicono adiacenti se hanno lo stesso genitore.

Si tenga presente che in documento HTML il tag <html> è l'antenato di qualsiasi altro marcatore e per questo viene detto «elemento radice».

Nel prossimo esempio viene mostrata una porzione di codice HTML in cui abbiamo due tag <h1> e <p> adiacenti e figli di <body>, e i tag <em> e <b> figli rispettivamente di <h1> e <p> (oltre che, ovviamente, discendenti di <body>).

<body>
<h1>Esempio per mostrare <em>struttura</em></h1>
<p>
Testo normale, <b>testo in grassetto</b></p>
</body>

La selezione in base alla struttura avviene con la sintassi mostrata nell'esempio seguente:

h1 em {color: yellow;}
p > b {font-style: italic;}
h1 + p {text-align: justify;}

I tre selettori dell'esempio si interpretano nel seguente modo:

4.2.1.5   Selettori basati su pseudo-classi e pseudo-elementi

Questo tipo di selettori è particolarmente importante perché permette di assegnare stili non in base alla struttura del documento o alla presenza di certi elementi con determinati attributi e valori, ma in base allo «stato» in cui si trovano determinati oggetti in un certo momento.

In particolare con le pseudo-classi è possibile selezionare, in base allo stato in cui si trovano, certi tag che vengono utilizzati per l'interazione con l'utente.

Al momento l'unico esempio che abbiamo incontrato di tale tipo di marcatori è quello per i collegamenti <a> e quindi vediamo l'uso dei selettori di pseudo-classi solo relativamente ad esso; quanto mostrato può poi essere facilmente applicato anche ad altri tipi di tag «interattivi», quelli relativi ai moduli, presentati più avanti (paragrafo 6).

Nell'esempio seguente viene mostrato l'uso di selettori di pseudo-classi:

a:link {color: magenta;}
a:visited {color: red;}
a:hover {color: yellow;}
a:active {color: brown;}

Le prime due sono pseudo-classi per i collegamenti; le altre due insieme a :focus (seleziona qualsiasi elemento che è attivo cioè che sta ricevendo l'input dell'utente) sono dette «dinamiche» e possono essere applicate a qualsiasi tag (come detto, il loro uso è importante relativamente ai moduli HTML).

Esiste anche la possibilità di combinare le pseudo-classi come mostrato di seguito:

a:link:hover {color: magenta;}
a:visited:hover {color: red;}
a:link:visited {color: black;}

Nel primo caso si vogliono selezionare i collegamenti non visitati su cui è posizionato il puntatore del mouse; nel secondo caso stessa cosa per i collegamenti visitati; il terzo caso è assurdo (un collegamento non può essere allo stesso tempo visitato e non visitato) e viene solitamente ignorato dai browser.

Concludiamo il paragrafo con gli pseudo-elementi grazie ai quali è possibile selezionare, e applicare gli stili, alla prima lettera o alla prima riga o anche prima e dopo un certo elemento.

Riguardo alla prima lettera e alla prima riga la sintassi è molto semplice e intuitiva, come dimostrato dal prossimo esempio:

p:first-letter {color: green;}
p:first-line {color: red;}

Molto interessanti sono gli pseudo-elementi :before e :after che usati congiuntamente alla regola content permettono di inserire un contenuto (chiamato «contenuto generato») nel documento HTML prima o dopo un certo marcatore; un esempio può chiarire facilmente le potenzialità di questi selettori:

h1:before {content: "Nuovo capitolo"; display: block; color: green;}
body:after {content: "Fine del documento"; font-style: oblique;}

L'effetto è quello di inserire la stringa «Nuovo capitolo» di colore verde prima di ogni intestazione di livello 1 e la stringa «Fine del documento», obliqua, alla fine del testo visualizzato.

Interessante è anche l'uso della proprietà display che nell'esempio serve a inserire il testo generato come elemento di blocco e quindi a fare proseguire il testo contenuto nel tag <h1> su un nuovo paragrafo; tale proprietà può assumere vari altri valori, che qui non consideriamo, tra cui "inline" che è il valore per difetto.

Le possibilità offerte dalla proprietà content e da altre riguardanti tipi speciali di contenuto generato (virgolette generate, contatori) sono molto maggiori di quelle appena mostrate ma non vengono approfondite in questa sede.

4.2.2   Dichiarazione di regole di stile per la formattazione

Una volta visto come è possibile selezionare le parti del documento cui applicare gli stili passiamo ad elencare alcuni di quelli relativi alla formattazione del testo.

Alcune proprietà possono essere «ereditate»; ciò significa che gli stili vengono applicati a un marcatore e anche a tutti i suoi discendenti.

L'elenco non è completo e viene fornito in modo molto sintetico con una tabella contenente le proprietà, il loro significato, i valori (almeno i più importanti) che esse possono assumere e se sono «ereditate» oppure no; in caso di necessità, queste informazioni possono essere integrate consultando testi e manuali riguardanti i CSS.

Altri tipi di regole di stile, stavolta relative al posizionamento degli oggetti nel documento, vengono invece illustrate nel paragrafo 4.4.

Quando si fa riferimento a grandezze (misura di caratteri, interlinea ecc.) si possono utilizzare varie unità di misura; alcune sono assolute:

Altre unità di misura sono relative, come:

Esiste poi la possibilità di esprimere grandezze in percentuale, calcolata di solito in base alle dimensioni del tag genitore di quello considerato.

Proprietà Significato Valori Ereditata Commento
font-family: Famiglia di caratteri Arial, "Helvetica Bold" .... Si Si applica a qualsiasi elemento; nomi multipli devono essere racchiusi tra virgolette; è possibile inserire più valori di famiglie di caratteri separati da «,» per avere una gerarchia di scelta; il valore per difetto dipende dal browser.
font-size: Grandezza del carattere xx-small, x-small, small, medium, large, x-large, xx-large, smaller, larger, dimensione esatta in una delle unità di misura elencate in precedenza, dimensione in percentuale (nn%) Si Si applica a qualsiasi elemento; il valore per difetto è medium; nel caso di valore in percentuale, o di valore «em», o di indicazione smaller o larger, viene presa come base la dimensione del carattere dell'elemento genitore; esempi: 15px, 20pt, 75%, 0.75em.
font-style: Stile del carattere normal, italic, oblique Si Si applica a qualsiasi elemento; il valore per difetto è normal.
font-variant Maiuscoletto normal, small-caps Si Si applica a qualsiasi elemento; il valore per difetto è normal.
font-weight: Peso del carattere normal, bold, bolder, lighter Si Si applica a qualsiasi elemento; il valore per difetto è normal.
line-height: Interlinea normal, valore intero da moltiplicare per la dimensione del carattere, valore in percentuale (nn%) sulla dimensione del carattere, valore esatto espresso con una delle unità di misura previste. Si Si applica a qualsiasi elemento; il valore per difetto è normal.
background-color: Colore di sfondo transparent, colore espresso in esadecimale (preceduto da «#») o con codice mnemonico (red, green,...) No Si applica a qualsiasi elemento; il valore per difetto è transparent.
background-image: Immagine di sfondo none, URI dell'immagine No Si applica a qualsiasi elemento; il valore per difetto è none.
background-position: Posizione di partenza dell'immagine di sfondo center, left, right, top, bottom top left, top right, bottom left, bottom right, valori delle coordinate assolute o in percentuale rispetto all'angolo superiore sinistro No Si applica a elementi di blocco; il valore per difetto è 0% 0%.
background-repeat: Modo di ripetizione dell'immagine di sfondo no-repeat, repeat, repeat-x, repeat-y No Si applica a qualsiasi elemento; il valore per difetto è no-repeat.
background-attachment: Per far scorrere l'immagine di sfondo insieme all'elemento di cui è sfondo scroll, fixed No Si applica a qualsiasi elemento; il valore per difetto è scroll.
color: Colore del testo colore espresso in esadecimale (preceduto da «#») o con codice mnemonico (red, green,...) Si Si applica a qualsiasi elemento; il valore per difetto dipende dal browser.
text-align: Allineamento del testo left, center, right, justify Si Si applica a elementi di blocco; il valore per difetto dipende dal browser, di solito è left.
text-decoration: Effetti «speciali» sul testo none, underline, overline, line-through, blink No Si applica a qualsiasi elemento; il valore per difetto è none.
text-indent: Indentazione della prima riga valore o percentuale specificati come per i valori in font-size Si Si applica a elementi di blocco; il valore per difetto è 0; il valore in percentuale viene calcolato in base alla larghezza dell'elemento di blocco che contiene l'elemento considerato; si possono inserire anche valori negativi che permettono di avere rientri a sinistra del testo.
text-transform: Capitalizzazione del testo none, uppercase, lowercase, capitalize Si Si applica a qualsiasi elemento; il valore per difetto è none; con capitalize si fa in modo che la prima lettera di ogni parola sia maiuscola.
white-space: Trattamento degli spazi vuoti normal, nowrap, pre No Si applica a elementi di blocco; il valore per difetto è normal; con nowrap si evita che gli spazi facciano spezzare una riga; con pre si fa in modo che gli spazi e le righe vuote vengano mantenute e non compattate; con normal si ha il comportamento consueto del programma di navigazione relativamente agli spazi e righe vuote.
word-spacing: Controllo del tracking (spazio tra le parole) normal, valore espresso con una delle unità di misura citate in precedenza Si Si applica a qualsiasi elemento; il valore per difetto è normal.
letter-spacing: Controllo del kerning (spazio tra le lettere) normal, valore espresso con una delle unità di misura citate in precedenza Si Si applica a qualsiasi elemento; il valore per difetto è normal.
vertical-align: Allineamento verticale del testo baseline, sub, super No Si applica a elementi in linea; il valore per difetto è baseline; si noti che con sub e super si ottiene la trasformazione del testo in pedice e apice ma senza riduzione della dimensione dei caratteri, per la quale occorre intervenire con la proprietà font-size.

Una osservazione importante riguarda la proprietà font-family: è possibile che si imposti un tipo di carattere non disponibile presso l'elaboratore dell'utente; in tal caso si può includere il carattere nella pagina nel modo illustrato sotto:

@font-face {font-family: pippo; src: url(pippo.eot);}
h1 {font-family: pippo;}

Nell'esempio pippo.eot è il file che contiene la definizione del carattere e che deve ovviamente essere presente nel servente Web.

Infine è importante segnalare che esistono anche proprietà a sintassi abbreviata, come ad esempio font: o background:, con le quali si possono assegnare, scrivendoli separati da spazi, i valori elencati in precedenza e relativi rispettivamente ai font e allo sfondo.

4.3   Tipi di fogli di stile

I fogli di stile contengono delle definizioni di proprietà da applicare a documenti HTML o a parti di essi e per questo devono essere «associati» al codice HTML; tale associazione può avvenire in varie maniere e questo differenzia in modo abbastanza netto i tipi di CSS.

4.3.1   Fogli di stile in linea

In questo caso gli stili vengono assegnati direttamente agli elementi HTML a cui si vogliono applicare grazie all'attributo style; ad esempio:

<p style="font-size: 12px; color: #FF0000">
Testo contenuto nel paragrafo
</p>

4.3.2   Fogli di stile incorporati

In questo caso i fogli di stile sono definiti all'interno della pagina con l'uso del tag <style>; esempio:

<html>
<head>
<title>Esempio con foglio di stile
</title>
<style type="text/css">
h1, h2 { text-transform: capitalize;
         text-align: center; }
body { color: #10AA10; background-color: #C0C0C0; }
p.pippo { font-size: larger;
          font-weight: bolder;
          text-align: center; }
</style>
</head>
<body>
<h1> titolo di tipo h1 </h1>
<p>
Questo documento è realizzato con un foglio di stile
incorporato.</p>
<p class="pippo"> Questo paragrafo è
definito nel CSS come paragrafo di classe "pippo".</p>
<hr/>
<p>
Questo invece è un paragrafo normale.</p>
</body>
</html>

Il risultato che si ottiene con il sorgente dell'esempio è mostrato in figura 4.18.

Figura 4.18.

figure/pagine-web-ese0013

4.3.3   Fogli di stile collegati

Il modo migliore per associare un foglio di stile ad una pagina HTML è quello di definirlo esternamente alla pagina stessa (come detto in precedenza questo permette di definire uno stile standard anche per un intero sito Web e di concentrare le modifiche solo sul foglio di stile e non su tutte le pagine).

Per il collegamento al foglio esterno si usa il tag <link> nella sezione di intestazione, con gli attributi href, rel e type; vediamo un esempio:

<html>
<head>
<title>Esempio con foglio di stile esterno</title>
<link href="foglio1.css" rel="stylesheet" type="text/css"/>
</head>

L'attributo rel può avere anche il valore "alternate stylesheet" per definire un foglio di stile alternativo; inoltre si può aggiungere l'attributo title per indicare il nome del foglio (questo è utile nel caso i programmi di navigazione siano in grado di mostrare all'utente la lista dei fogli di stile associati ad un documento permettendo di scegliere il preferito).

Il foglio di stile a cui si riferisce l'esempio si chiama foglio1.css e potrebbe avere il seguente contenuto (definito con un normale editor di testo):

/* Esempio di foglio di stile 
   da collegare */
@import url(http://www.maxplanck.it/libcss/foglio2.css)
h1, h2 { text-transform: capitalize;
         text-align: center; }
body { color: #10AA10; background-color: #C0C0C0; }
p.pippo { font-size: larger;
          font-weight: bolder;
          text-align: center; }

Le righe racchiuse tra «/*» e «*/» sono un commento; il costrutto @import serve ad importare all'interno del foglio di stile ulteriori definizioni contenute nel foglio a cui fa riferimento l'indirizzo specificato (in questo caso foglio2.css nella directory libcss del servente Web www.maxplanck.it; le altre definizioni sono le stesse utilizzate nell'esempio con il CSS incorporato.

Se, per qualche motivo, si avessero problemi con il collegamento dei fogli di stile si può ricorrere all'importazione; a tale scopo basta usare il costrutto @import, in modo simile all'esempio precedente, inserito però direttamente nel documento HTML, racchiuso tra un tag <style> e un </style>.

A proposito del costrutto @import è importante osservare che esso fa parte, insieme a @media, @charset, @font-face, delle cosiddette «@-rules» con le quali si possono fare alcune operazioni particolari.

Fra queste, @media, riveste una notevole importanza per i CSS per la stampa, come mostrato nel paragrafo 4.5.

4.3.4   Organizzazione a cascata

L'organizzazione a cascata dei fogli di stile consiste semplicemenite nel fatto che c'è un ordine di priorità tra regole di stile definite con tipi di CSS diversi; in altre parole se abbiamo un documento HTML in cui si utilizzano regole di stile definite in un foglio collegato, altre regole incorporate ed altre ancora in linea, in caso di conflitto sono queste ultime ad essere applicate.

Quindi le regole di stile in linea prevalgono su quelle incorporate (e importate) e queste a loro volta su quelle collegate.

Questo fatto può essere sfruttata quando, nella definizione degli stili delle pagine di un sito, si vogliono definire delle regole generali ma si vogliono avere delle «eccezioni» per alcune pagine; in tal caso si definiscono le regole globali in fogli collegati da usare in tutte le pagine, ma nelle pagine «particolari» si inseriscono delle regole di stile incorporate o in linea che sovrascrivono le altre.

4.3.5   Fogli di stile alternativi

In precedenza si è visto come impostando l'attributo rel del tag <link> con il valore "alternate stylesheet" sia possibile definire un foglio di stile alternativo da collegare a un certo documento HTML.

Per maggiore completezza occorre chiarire che ad un documento HTML si possono collegare:

Nel prossimo esempio abbiamo una pagina HTML cui sono collegati un foglio persistente, uno automatico e due fogli alternativi; nella figura 4.22 viene mostrato il menu di scelta degli stili disponibili al momento della visualizzazione di tale documento con il browser Firefox.

<html>
<head><title>Esempio per collegamento fogli di stile</title>
<link rel="stylesheet" href="foglio_pers.css" type="text/css"/>
<link rel="stylesheet" href="foglio_auto.css" type="text/css"\
  \title="Stile di default"/> <link rel="alternate stylesheet" href="foglio1.css" type="text/css"\
  \title="Stile alternativo 1"/> <link rel="alternate stylesheet" href="foglio2.css" type="text/css"\
  \title="Stile alternativo 2"/> </head> <body> <h1>Prova fogli di stile alternativi</h1> Selezionare uno degli stili disponibile attraverso l'apposito menu nel programma di navigazione. <p></p> </body> </html>

Figura 4.22.

figure/pagine-web-ese0014

4.4   Posizionamento con i fogli di stile

Per parlare di posizionamento con i fogli di stile occorre prima di tutto chiarire come questi ultimi considerano e gestiscono gli elementi presenti in una pagina; ogni elemento genera un riquadro rettangolare (o box) non visibile comprendente:

L'unica parte sempre presente è l'area del contenuto, le altre possono essere impostate ad ampiezza nulla.

Vediamo (o ricordiamo) anche altri concetti molto importanti riguardanti gli elementi di una pagina HTML.

I riquadri degli elementi possono essere di blocco o in linea, con le conseguenze che questo comporta e che sono già state chiarite in precedenza (paragrafo 2.5.4).

Gli elementi possono essere «non rimpiazzati» o «rimpiazzati»; nel primo caso il contenuto si trova all'interno del riquadro, nel secondo il tag è solo un segnaposto per un altro oggetto (l'esempio più banale di questo tipo di elemento è <img>).

Ogni elemento è contenuto in un «blocco contenitore», ad esempio:

<body>
<div>
<h1>Titolo</h1>
<p>Testo</p>
</div>
</body>
</html>

qui i tag <h1> e <p> hanno <div> come blocco contenitore ed esso, a sua volta è contenuto in <body>.

Il «flusso» di visualizzazione di un documento HTML è da sinistra a destra e dall'alto verso il basso, questo è il comportamento normale di tutti i browser almeno per le lingue occidentali; un elemento può essere estrapolato dal flusso normale solo posizionandolo oppure rendendolo fluttuante con la proprietà float.

Nel resto del paragrafo vediamo appunto le proprietà dei CSS da utilizzare per il posizionamento oltre a quelle riguardanti le varie caratteristiche dei box degli elementi.

Il posizionamento può essere:

In caso alcuni riquadri si sovrappongano, è anche possibile ordinarli in base all'asse perpendicolare all'area di visualizzazione, immaginando che il documento sia costituito da livelli sovrapposti.

Esiste infine la possibilità di rendere l'elemento fluttuante, cioè di spostarlo dal normale flusso, ma facendo in modo che esso influisca ancora sul resto del testo (che solitamente gli viene fatto scorrere intorno).

In ogni caso con i CSS si ottiene un tipo di posizionamento che viene detto «liquido» in quanto tiene conto automaticamente del variare delle dimensione dell'area di visualizzazione della pagina (finestra del browser dell'utente).

Come abbiamo fatto nel paragrafo 4.2.2 relativamente agli stili per la formattazione del testo, ricorriamo anche qui ad una tabella per elencare le proprietà riguardanti il posizionamento dei riquadri e le loro caratteristiche.

Proprietà Significato Valori Ereditata Commento
width: Larghezza di un elemento auto, valore espresso con una delle unità di misura consentite o in percentuale No Si applica a elementi di blocco e rimpiazzati; il valore per difetto è auto; il valore in percentuale è calcolato in base all'elemento contenitore.
height: Altezza di un elemento auto, valore espresso con una delle unità di misura consentite No Si applica a elementi di blocco e rimpiazzati; il valore per difetto è auto;
visibility: Visibilità di un elemento visible, hidden No Si applica a qualsiasi elemento; il valore per difetto è visible; un elemento nascosto risulta comunque presente (cioè influenza comunque il comportamento degli elementi vicini).
border-color: Colore dei bordi di un riquadro transparent, codice colore in esadecimale o mnemonico No Si applica a qualsiasi elemento; il valore per difetto è il colore dell'elemento contenuto; se si inserisce un solo colore esso vale per tutti e quattro i bordi, altrimenti si possono inserire quattro colori separati da spazi relativi nell'ordine a: bordo alto, bordo destro, bordo basso, bordo sinistro (oppure si possono usare le proprietà specifiche border-top-color, border-right-color border-bottom-color border-left-color).
border-style: Stile dei bordi di un riquadro none, dotted, dashed, solid, double, groove, ridge, inset, outset No Si applica a qualsiasi elemento; il valore per difetto è none; se si inserisce un solo stile esso vale per tutti e quattro i bordi, altrimenti si possono inserire quattro stili separati da spazi relativi nell'ordine a: bordo alto, bordo destro, bordo basso, bordo sinistro (oppure si possono usare le proprietà specifiche border-top-style, border-right-style border-bottom-style border-left-style).
border-width: Spessore dei bordi di un riquadro thin, medium, thick, valore espresso con una delle unità di misura consentite No Si applica a qualsiasi elemento; il valore per difetto è medium; se si inserisce un solo valore o codice esso vale per tutti e quattro i bordi, altrimenti si possono inserire quattro valori o codici separati da spazi relativi nell'ordine a: bordo alto, bordo destro, bordo basso, bordo sinistro (oppure si possono usare le proprietà specifiche border-top-width, border-right-width border-bottomwidth border-left-width).
margin: Ampiezza dei margini di un riquadro auto, valore espresso con una delle unità di misura consentite o in percentuale No Si applica a qualsiasi elemento; il valore per difetto è 0; valori in percentuale vengono calcolati in base alla larghezza dell'elemento genitore; se si inserisce un solo valore esso vale per tutti e quattro i margini, altrimenti si possono inserire quattro valori separati da spazi relativi nell'ordine a: margine alto, destro, basso, sinistro (oppure si possono usare le proprietà specifiche margin-top, margin-right margin-bottom margin-left).
padding: Ampiezza del padding di un riquadro valore espresso con una delle unità di misura consentite o in percentuale No Si applica a qualsiasi elemento; il valore per difetto è 0; valori in percentuale vengono calcolati in base alla larghezza dell'elemento genitore; se si inserisce un solo valore esso vale per tutti e quattro i lati, altrimenti si possono inserire quattro valori separati da spazi relativi nell'ordine a: padding alto, destro, basso, sinistro (oppure si possono usare le proprietà specifiche padding-top, padding-right padding-bottom padding-left).
position: posizionamento di un riquadro static, relative, absolute, fixed No Si applica a qualsiasi elemento; il valore per difetto è static.
bottom: Scostamento in basso di un riquadro posizionato auto, valore espresso con una delle unità di misura consentite o in percentuale No Si applica a qualsiasi elemento posizionato (con valore di position diverso da static); il valore per difetto è auto.
left: Scostamento a sinistra di un riquadro posizionato auto, valore espresso con una delle unità di misura consentite o in percentuale No Si applica a qualsiasi elemento posizionato (con valore di position diverso da static); il valore per difetto è auto.
right: Scostamento a destra di un riquadro posizionato auto, valore espresso con una delle unità di misura consentite o in percentuale No Si applica a qualsiasi elemento posizionato (con valore di position diverso da static); il valore per difetto è auto.
top: Scostamento in alto di un riquadro posizionato auto, valore espresso con una delle unità di misura consentite o in percentuale No Si applica a qualsiasi elemento posizionato (con valore di position diverso da static); il valore per difetto è auto.
z-index: Posizionamento sull'asse perpendicolare all'area di visualizzazione auto, numero intero No Si applica a qualsiasi elemento posizionato (con valore di position diverso da static); il valore per difetto è auto; i riquadri con valori di z-index alti sono più «vicini» all'utente di quelli con valori bassi.
float: Direzione di spostamento di un elemento fluttuante none, left, right No Si applica a qualsiasi elemento; il valore per difetto è none.
clear: Controllo scorrimento elementi fluttuanti none, left, right, both No Si applica a elementi di blocco; il valore per difetto è none; si usa per impedire che elementi fluttuanti compaiano a sinistra, a destra o da entrambi i lati dell'elemento cui si assegna questa proprietà (tale elemento si posizionerà quindi dopo eventuali elementi fluttuanti e non accanto ad essi).
overflow: Modalità di gestione del traboccamento del testo visible, hidden, scroll, auto No Si applica a elementi di blocco e rimpiazzati; il valore per difetto è visible; con visible il contenuto che eccede le dimensioni del contenitore viene reso comunque visibile adattando queste ultime, con hidden invece è nascosto, con scroll e auto vengono aggiunte delle barre di scorrimento sul riquadro, nel primo caso sempre, nell'altro solo se necessario.
clip: Definizione di un'area di taglio auto, rect(valore_su, valore_dx, valore_giu, valore_sx) No Si applica a elementi posizionati in modo assoluto; il valore per difetto è auto; si usa per definire un'area rettangolare in cui è reso visibile il contenuto del riquadro; il contenuto eccedente viene trattato in base a quanto stabilito con la proprietà overflow.

Prima di concludere osserviamo che per utilizzare proficuamente i fogli di stile per il posizionamento degli elementi di un documento HTML è opportuno usare abbondantemente il tag <div> in modo da definire le sezioni della pagina cui applicare le necessarie regole di stile.

Questa non deve essere però una forzatura: una buona suddivisione del documento in sezioni, che tenga conto correttamente della sua struttura logica, sarà quasi sicuramente idonea anche all'uso per l'assegnazione degli stili di formattazione e di posizionamento.

Infine vediamo due esempi molto simili di pagine contenenti un riquadro di testo con gestione del traboccamento dello stesso, tre immagini con relative didascalie posizionate con precisione e una immagine fluttuante contornata da testo sulla sua destra o sulla sua sinistra.

Il tutto è realizzato con regole di stile di un foglio incorporato, nel primo caso usando il posizionamento relativo nell'altro il posizionamento assoluto.

La scelta del CSS di tipo incorporato è dettata solo da ragioni di praticità: in questo modo infatti, per ognuno dei due esempi, è sufficiente mostrare il sorgente HTML e non più file separati.

Vediamo il primo esempio:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Posizionamento relativo con CSS
</title>
<style type="text/css">
body { font-family: "DejaVu Sans"; font-size: 14px; }
h1.titolo { color: green;
            font-style: italic;
            text-align: center; }
.box_immagini { position: relative;
                top: 0px;
                left: 50px; }
.box_fluttua { width: 350px;
               height: 100px; }
.fluttua { float: left;
           margin-top: 5px;
           margin-right: 15px;
           width: 140px;
           height: 120px; }
.riga11 { position: relative;
          top: 0%;
          left: 0%;
          width: 120px;
          height: 135px; }
.riga12 { position: relative;
          top: 0%;
          left: 20%;
          width: 120px;
          height: 135px; }
.riga13 { position: relative;
          top: 0%;
          left: 40%;
          width: 180px;
          height: 135px; }
.riga21 { position: relative;
          top: 0%;
          left: 0%;
          margin-top: 10px;
          width: 120px;
          height: 15px;
          text-align: center; }
.riga22 { position: relative;
          top: -2em;
          left: 33%;
          margin-top: 10px;
          width: 120px;
          height: 15px;
          text-align: center; } 
.riga23 { position: relative;
          top: -4em;
          left: 66%;
          margin-top: 10px;
          width: 180px;
          height: 15px;
          text-align: center; }
p.testo { width: 300px;
          height: 100px;
          overflow: auto; }
</style>
</head>
<body>
<h1 class="titolo">Prova di posizionamento relativo con CSS</h1>
<p class="testo">
Le tre immagini seguenti con le relative didascalie sono
posizionate con la proprietà position dei CSS e posizionamento 
relativo. L'immagine successiva è fluttuante a sinistra ed è
inserita dopo la parola "fluttuante".</p> 
<div class="box_immagini">
 <img class="riga11" src="tux.jpg"/>
 <img class="riga12" src="tux_univ.jpg"/>
 <img class="riga13" src="Family_linux.png"/>
</div> 
<p/> 
<p class="riga21">
 Tux</p>
<!-- Le ultime due didascalie sono posizionate correttamente in 
verticale ricorrendo a un posizionamento relativo negativo rispettivamente 
di -2 e -4 em cioè 2 volte e 4 volte l'ampiezza media del carattere
usato; questo le fa allineare alla prima didascalia. -->
 <p class="riga22">
 Tux laureato</p>
 <p class="riga23">
 Tux family</p>
<div class="box_fluttua">
 <p>Questa immagine è fluttuante,
 <img class="fluttua" src="Linux-Inside-small.gif"/>
 a sinistra; quindi il testo si affianca alla sua destra.</p>
</div>
</body>
</html>

Il risultato che si ottiene è mostrato nella figura 4.26.

Figura 4.26.

figure/pagine-web-ese0015

Ecco invece il sorgente del secondo esempio:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Posizionamento assoluto con CSS
</title>
<style type="text/css">
h1.titolo { color: blue;
            font-style: italic;
            text-align: center; }
.box_immagini { position: relative;
                top: 1px;
                left: 15px;
                width: 66%;
                height: 50%; }
.box_fluttua { position: relative;
               top: 180px;
               left: 50px;
               width: 350px; }
.fluttua { float: right;
           margin-top: 5px;
           margin-right: 15px;
           width: 140px;
           height: 120px; }
img.dim1 { width: 120px;
           height: 135px; }
img.dim2 { width: 180px;
           height: 135px; }
.riga11 { position: absolute;
          top: 0%;
          left: 0%; }
.riga12 { position: absolute;
          top: 0%;
          left: 33%; }
.riga13 { position: absolute;
          top: 0%;
          left: 66%; }
.riga21 { position: absolute;
          top: 135px;
          left: 0%;
          margin-top: 5px; }
.riga22 { position: absolute;
          top: 135px;
          left: 33%;
          margin-top: 5px; }
.riga23 { position: absolute;
          top: 135px;
          left: 66%;
          margin-top: 5px; }
p.testo { width: 300px;
          height: 100px;
          overflow: auto; }
</style>
</head>
<body>
<h1 class="titolo">Prova di posizionamento assoluto con CSS</h1>
<p class="testo">
Le tre immagini seguenti con le relative didascalie sono
posizionate con la proprietà position dei CSS e posizionamento
assoluto. L'immagine successiva è fluttuante a destra
ed è inserita dopo la parola "fluttuante".</p> 
<div class="box_immagini">
<!-- le immagini e le didascalie sono ognuna in una sezione
figlia della sezione box_immagini che non è posizionata 
staticamente (position:relative) e quindi ha effetto il posizionamento
assoluto rispetto a questa ultima. -->
        <div class="riga11">
        <img class="dim1" src="tux.jpg"/>
        </div>
        <div class="riga12">
        <img class="dim1" src="tux_univ.jpg"/>
        </div>
        <div class="riga13">
        <img class="dim2" src="Family_linux.png"/>
        </div>
        <div class="riga21">
        <p>Tux</p>
        </div>
        <div class="riga22">
        <p>Tux universitario</p>
        </div>
        <div class="riga23">
        <p>Tux family</p>
        </div>
</div>
<div class="box_fluttua">
<!-- La sezione box_fluttua è posizionata relativamente con
uno scostamento verticale tale da "scavalcare" immagini e didascalie --> 
<p>Questa immagine è fluttuante,
<img class="fluttua" src="Linux-Inside-small.gif"/>
a destra; quindi il testo si affianca alla sua sinistra.</p>
</div>
</body>
</html>

Il risultato che si ottiene è mostrato nella figura 4.28.

Figura 4.28.

figure/pagine-web-ese0015b

Si possono confrontare i risultati di questi due esempi con la pagina, simile, presentata nel paragrafo 3.2.4 ottenuta posizionando gli elementi tramite una tabella.

4.5   Fogli di stile per la stampa

Una delle caratteristiche più interessanti dei CSS è la loro capacità di definire stili diversi per mezzi di comunicazione diversi; è possibile infatti associare allo stesso documento HTML un foglio di stile dedicato alla visualizzazione a video, uno per la stampa su carta, uno per dispositivi portatili (palmari), uno per alfabeto braille ed altri ancora.

In queste dispense si prende in esame solo il caso della stampa su carta che riveste sicuramente una notevole importanza viste le difficoltà che di solito si incontrano quando si stampano documenti visualizzati con un programma di navigazione.

Le pagine Web, infatti, sono quasi sempre concepite e realizzate per essere visualizzate a video e quindi contengono tutta una serie di oggetti e di formattazioni che al momento della stampa sono inutili se non addirittura dannosi; pensiamo ad esempio a barre di scorrimento, barre contenenti menu, immagini di sfondo, sfondi colorati.

C'è poi il caso, abbastanza comune, di pagine impostate con larghezza fissa maggiore di quella dei fogli A4 e che quindi risultano «tagliate» a destra quando trasferite su carta.

A questi inconvenienti è possibile dare una soluzione anche senza l'uso dei CSS; basta infatti predisporre versioni diverse della stessa pagina: una per il video e una per la stampa, premunendosi di inserire nella prima un collegamento alla seconda a disposizione dell'utente e da utilizzare al momento di effettuare la stampa.

In questo modo abbiamo però un notevole aggravio di lavoro per la scrittura di una doppia versione delle pagine del sito, senza contare poi che l'utente potrebbe non «notare» il collegamento alla versione da stampare e continuare quindi a usare la versione «sbagliata».

Meglio quindi ricorrere ai CSS tanto più che l'idea di base è la stessa: una pagina (o meglio, un foglio di stile) per il video e una per la carta, solo che stavolta la scelta viene fatta in automatico dal programma di navigazione al momento che si decide di mandare in stampa il documento.

4.5.1   Fogli di stile per media diversi

La specifica del mezzo di comunicazione cui è rivolto un foglio di stile avviene nel seguente modo:

Oltre ai media video e stampa sono previste altre possibilità che però sono molto meno usate e anche meno supportate dai vari browser; il pieno supporto si ha per screen, print e all che è il valore assegnato per difetto e significa che quel foglio di stile si applica a qualsiasi mezzo di comunicazione.

L'elenco completo dei media utilizzabili è il seguente:

Quando si definiscono i fogli di stile per il video e la stampa occorre fare in modo che non risultino collegati al documento HTML anche fogli di stile per qualsiasi media perché le impostazioni presenti in essi avrebbero effetto anche sul documento stampato, con effetti potenzialmente deleteri.

4.5.2   Impostazione di un foglio di stile per la stampa

Prima di tutto occorre osservare che per poter definire proficuamente un foglio di stile per la stampa occorre che il documento HTML contenga solo tag relativi alla sua struttura e non alla formattazione e presentazione; infatti, solo se queste ultime sono completamente demandate a regole di stile, è possibile alterare l'aspetto della pagina semplicemente cambiando il CSS collegato.

Nel foglio di stile per la stampa occorre eliminare gli elementi che non hanno senso per questo tipo di output associando ad essi la proprietà display con valore none; si possono poi ridimensionare e riposizionare gli altre elementi per sfruttare lo spazio «guadagnato».

Sicuramente è utile anche eliminare colori e immagini di sfondo, definendo il documento con caratteri neri su fondo bianco e togliere eventuali impostazioni della dimensione della pagina lasciando che il browser possa sfruttare tutta la dimensione del foglio in stampa.

Anche la scelta del tipo di carattere è importante: sullo schermo si preferiscono di solito caratteri «senza grazie» (sans-serif) come Arial e Verdana; per la stampante invece è meglio usare caratteri con «grazie» (serif) come Times o Georgia.

Per esprimere la dimensione dei caratteri (e tutte le altre grandezze assolute) per la stampa è preferibile abbandonare i pixel a vantaggio di altre unità di misura più legate al mezzo cartaceo come i punti (pt), i millimetri (mm) o i pollici (in); inoltre, visto che la lettura su carta è meno faticosa che sullo schermo, è possibile diminuire la dimensione dei caratteri per risparmiare carta e inchiostro.

Tra gli elementi che non hanno grande utilità passando dallo schermo alla carta ci sono i collegamenti ipertestuali che, ovviamente, sul foglio non possono essere attivati.

Per essi può allora essere utile far apparire in stampa l'indirizzo a cui puntano nel modo seguente:

a:link:after, a:visited:after {content " ["attr(href)"]";}

In questo modo, dopo ogni collegamento, visitato o no, viene stampato l'indirizzo a cui esso punta, racchiuso tra parentesi quadrate.

Infine segnaliamo la possibilità di controllare le interruzioni di pagina in stampa grazie alle proprietà page-break-before, page-break-after, page-break-inside che possono valere auto (valore per difetto), always, avoid in modo da forzare o evitare interruzioni prima, dopo o all'interno di un certo blocco.