In questo articolo vedremo alcune proprietà e selettori CSS2 avanzate attraverso esempi reali. Ritengo infatti che siano disponibili molte risorse teoriche, ma è attraverso casi reali che si arriva a conoscerli a fondo. È consigliata una buona conoscenza dei selettori base, i miei consigli di lettura sono:
- La guida ai CSS di HTML.it, in particolare le lezioni dalla 8 alla 14
- I selettori CSS
- Il tutorial base sui CSS di brainjar.com
Inoltre, ottime risorse per approfondire quello di cui parleremo sono la
guida CSS2 di richinstyle.com e la completissima reference
sui CSS2 del W3C.
Per un'interpretazione verbale dei selettori suggerisco infine Selectoracle.
Il supporto dei browser
C'è da dire che nessuno degli esempi che vedremo è supportato da Internet Explorer 5.x o 6. Vi chiederete: allora qual è l'utilità pratica? Anche se Internet Explorer è senza dubbio il browser più diffuso, non è l'unico. Dave Shea, in un suo articolo parla del MOSe (Mozilla - Safari - Opera Enhancement, ossia miglioramento per Opera,Safari e Mozilla) e sostiene che il fatto che alcune caratteristiche CSS2 non siano supportate da Internet Explorer non dovrebbe essere un ostacolo per il webdesigner: si può comunque progettare pagine per Internet Explorer che presentino però "qualcosa in più" sui browser con maggiore supporto CSS2. Un esempio validissimo è questa entry di CSS Zen Garden.
Cosa si propone questo articolo
Cominciamo col dire che la lettura di questo articolo è consigliata a chi ha una buona conoscenza dei CSS. Non è un articolo teorico, ma più che altro un'introduzione alle caratteristiche avanzate dei CSS attraverso esempi, per la cui visualizzazione corretta è consigliato l'uso di Mozilla (o un altro browser Gecko), Opera o Safari, magari affiancata ad Internet Explorer per constatare come degradano gli esempi.
Nascondere regole ad IE
Un modo semplice per nascondere regole a Internet Explorer è usare selettori che non supporta. Il child selector (selettore di figlio) è un selettore che permette di definire una regola rivolta solo ai figli "diretti" (ossia ai discendenti primi) di un dato elemento. Vediamo una realizzazione pratica. Si tratta di un <div>
posizionato assolutamente per IE, mentre per gli altri browsers che supportano il child selector, questo viene posizionato fisso rispetto alla finestra del browser. Ecco il codice fondamentale dell'esempio:
div#maybefixed { position: absolute;top: 50px;left: 20px } body>div#maybefixed{ position:fixed }
IE non supporta position:fixed, così come il child selector, e non vedrà quindi la seconda regola. Per i browser compatibili, la seconda regola risulta più specifica del semplice selettore di id, e va quindi a ridefinire la proprietà position. Se guardate l'esempio con IE, vi sarà impossibile ottenere una schermata del genere:
Un filler text con i CSS
I CSS, attraverso gli pseudo-elementi :before
e :after combinati con la proprietà content,
consentono di andare a aggiungere contenuto (testo o immagini) a specifici elementi
di una pagina web. C'è da notare che il compito dei CSS è la presentazione, non
il contenuto. In alcuni casi, per esempio per test di layout, può però essere
utile disporre di un testo di riempimento da attribuire alle varie sezioni di
pagina. Ecco come fare. Si definisce una classe filler
in questo modo:
html>body div.filler:after{content: "Ma non lo è. Con i CSS è facile ottenere un filler text.... Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam posuere. Pellentesque ut elit. Duis dapibus lectus eu mi. Suspendisse ut arcu. Aliquam nunc nunc, pharetra sed, commodo vel, convallis eget, mauris. Phasellus nec augue eu odio blandit feugiat. Curabitur sagittis elementum tellus. Suspendisse potenti. Donec gravida molestie augue. Etiam nec turpis. "}
Per prima cosa vediamo com'è strutturato il selettore: è composto da un selettore
discendente, la cui prima parte html>body
serve a nascondere la regola ad IE. Poi viene generato del contenuto attraverso
lo pseudo-elemento :after applicato alla
classe filler. La proprietà content
si occuperà di inserire il contenuto (il codice sopra risulterà su più righe,
ma è importante che nel CSS sia tutto in una riga sola). Nel codice HTML basterà
assegnare la classe filler agli elementi necessari, ad esempio:
<div id="navigation" class="filler"></div>
<div id="content" class="filler"></div>
Non ci resta che vedere l'esempio,
in cui la classe filler è stata applicata al div con id container.
Ecco uno screenshot:
Contare gli elementi di una pagina html
Rispetto all'esempio precedente, possiamo spingerci ancora oltre. I contatori
CSS possono servire per numerare liste, titoli, così come qualsiasi elemento di
una pagina web. Se siete curiosi di sapere quanti elementi contiene una pagina
HTML, basterà semplicemente aggiungere una sola regola al CSS e visualizzare la
pagina con Mozilla, Opera o Safari. Ecco la regola:
html>body *:before{
content: "[" counter(contatore) "]";
counter-increment: contatore;
color: #f00}
La regola viene applicata a qualsiasi elemento contenuto nel body,
attraverso il selettore universale. Attraverso lo pseudoelemento before
viene generato il contenuto che dovrà precedere ogni elemento all'interno del
body. Questo sarà il valore del contatore (definito attraverso la proprietà counter
e con nome contatore) racchiuso tra parentesi quadre. Per ogni elemento
il contatore verrà incrementato attraverso la proprietà counter-increment
il cui valore è proprio il nome che abbiamo scelto per il contatore. Infine, lo
pseudoelemento generato, con il contatore racchiuso tra parentesi quadre, verrà
reso in rosso. Non ci resta che vedere l'esempio.
Anche per quest'ultimo, ho fatto uno screenshot della pagina visualizzata con
Opera 7.23:
Debug di una pagina HTML
Se state pensando di partecipare a CSS
Zen Garden, dovete modificare un foglio di stile di stile o l'HTML di una
pagina non vostra, l'esempio che stiamo per vedere potrebbe esservi utile per
capire come è strutturata la pagina e a quale sezione appartiene un certo paragrafo
senza dover consultare il codice HTML. Il selettore di attributo consente
di applicare una regola agli elementi che hanno un dato attributo. L'idea è semplice:
creare una regola che andrà applicata ai soli div
con attributo id, a cui generalmente
vengono associate le sezioni di una pagina html con layout basato sui CSS, racchiuderli
tra dei bordi e mostrarne per ciascuno l'id attraverso lo pseudo-elemento before
e la proprietà content, che mostrerà in questo caso propio il valore dell'attributo
(e quindi l'id). Vediamo il CSS:
div[id]{
border: 1px solid #000;
background-color: #fff;
margin:20px 10px}
div[id]:before{
display:block;
content: "div#" attr(id);
background-color: #cf9;
color: #060}
Da notare che l'elemento generato con la proprietà content è per sua natura un elemento inline,
e che in questo caso attraverso la dichiarazione display:block l'abbiamo reso block-level. Non ci resta che vedere l'esempio
e il relativo screenshot su Opera:
In maniera analoga si può andare a visualizzare il nome delle classi degli elementi di una pagina html, magari in questo caso
combinando il selettore universale e il selettore di attributo:
*[class]:before{content: "class=" attr(class); background-color:#000; color: #0f0}
Indentazione dei paragrafi
È uso comune nell'editoria cartacea indentare i paragrafi,
ossia lasciare un po' di spazio sulla destra della prima riga di testo, per evidenziarne
l'inizio e aggiungere un po' di dinamicità al testo, così come è comune che il
primo paragrafo che segue un titolo non sia indentato. Un'impostazione simile
può essere facilmente ottenuta con i fogli di stile e il selettore adjacent-sibling
(selettore di fratello adiacente). Questo selettore determinerà regole applicate
a un elemento che sia successivo, in ordine di codice HTML, ad un altro elemento,
purchè entrambi condividano lo stesso contenitore. Possiamo allora creare una
regola generica per i paragrafi indentati, e una più specifica per il paragrafo
immediatamente successivo ad un titolo:
p{text-indent:2em}
h1+p, h2+p{text-indent:0}
La seconda regola, che usa il raggruppamento, verrà applicata quindi solo ai
paragrafi preceduti da un h1 o da un
h2. Vediamo l'esempio
e uno screenshot:
Un'alternativa
Con i CSS ci sono sempre diversi modi per ottenere lo stesso risultato. Possiamo far si che tutti i paragrafi abbiano indentazione pari a zero, e
sfruttando l'adjacent sibiling selector dichiarare una regola più specifica che verrà applicata a tutti i paragrafi preceduti da un paragrafo.
Ecco le due regolette:
p{text-indent:0}
p+p{text-indent:2em}
Il risultato
sui browsers che supportano il selettore di fratello adiacente è identico all'esempio
precedente. Non ci resta che scegliere come vogliamo che i visitatori che navigano
le nostre pagine con IE vedano i paragrafi: tutti indentati oppure nessuno, dato
che IE non supporta questo selettore e quindi non sarà in grado di interpretare
la seconda regola dei due esempi.
Per uno studio più ravvicinato di quanto proposto, si può scaricare
lo zip con tutti i documenti analizzati.