CSS: Introduzione
Transcript
CSS: Introduzione
Laboratorio di Tecnologie Web CSS: Introduzione Dott. Stefano Burigat www.dimi.uniud.it/burigat Cascading Style Sheets (CSS) è uno standard W3C che definisce gli aspetti di presentazione dei documenti HTML. L'utilizzo di CSS permette un controllo preciso del layout e dell'aspetto grafico di un documento, permette di modificare la presentazione di un intero sito senza modificarne minimamente il contenuto, rende più semplice la creazione di siti accessibili (perchè il codice HTML non viene sporcato da elementi presentazionali estranei), ha un ottimo livello di supporto da parte dei browser. La versione più recente di CSS è la 3 (CSS3) e, al contrario delle versioni precedenti, è suddivisa in moduli, ciascuno dei quali dedicato ad una specifica funzionalità. Alcuni moduli hanno raggiunto un buon livello di standardizzazione mentre altri sono ancora sperimentali. Come per HTML5, il livello di compatibilità dei browser con CSS3 è variabile ed è quindi necessario fare attenzione alle funzionalità che si utilizzano, cercando di evitare quelle che non consentono di mantenere compatibilità all'indietro con le versioni precedenti di CSS, in particolare CSS2.1. Regole di stile La sintassi utilizzata da CSS è diversa da quella HTML. Un foglio di stile CSS è costituito da una o più regole di stile che descrivono come dovrebbero essere visualizzati un elemento o un gruppo di elementi HTML. Ogni regola seleziona un elemento e dichiara come questo deve essere presentato. Il seguente frammento di codice CSS mostra due regole di stile: la prima definisce il colore del testo per l'elemento <h1>; la seconda definisce dimensione e tipo di font utilizzati per l'elemento <p>. h1 { color: green; } p { font-size: small; font-family: sans-serif; } Nella terminologia CSS, i due componenti principali di una regola sono il selettore, che definisce a cosa si applica la regola, e la dichiarazione, che specifica le istruzioni da applicare. Una dichiarazione è a sua volta suddivisa in una proprietà (ad esempio “color” nella prima regola dell'esempio sopra) ed un valore (“green” nella prima regola dell'esempio sopra), separati da due punti ed uno spazio. I possibili valori dipendono dalla specifica proprietà considerata. Ci possono essere una o più dichiarazioni per ogni regola ed il blocco di dichiarazioni viene racchiuso da parentesi graffe. Ogni dichiarazione deve essere separata dalla successiva tramite un punto e virgola (l'ultimo è opzionale ma è preferibile inserirlo). Nell'esempio precedente, il selettore specifica il nome di un elemento e la relativa regola viene applicata a tutte le istanze di quell'elemento all'interno del documento a cui viene associato il foglio di stile. Come vedremo in seguito, CSS supporta anche selettori più sofisticati. Applicazione dello stile Ci sono tre modi per applicare informazione di stile ad un documento HTML: • Fogli di stile esterni. Le regole di stile vengono incluse in un file di testo con estensione .css e importate nel documento HTML tramite l'elemento vuoto <link> oppure la regola @import. Il metodo più comune è l'utilizzo dell'elemento <link> all'interno dell'elemento <head>. In tal caso, è necessario specificare i due attributi “rel” (tipo di documento a cui si sta facendo riferimento; assume valore stylesheet per i fogli di stile) e “href” (path del documento), come nell'esempio seguente. <!DOCTYPE html> <html> <head> <title>Tecnologie web</title> <link rel="stylesheet" href="css/stile.css" /> </head> <body> <p>A questo paragrafo vengono applicate <em>regole distile</em> in cascata.</p> </body> </html> Prima di HTML5 era anche necessario inserire l'attributo “type” con valore text/css. E' possibile inserire più elementi link per fare riferimento a più fogli di stile per lo stesso documento. Il secondo metodo per applicare un foglio di stile esterno è utilizzare la regola @import all'inizio di un elemento <style> (questo elemento viene utilizzato per definire fogli di stile embedded come spiegato nel punto seguente; in tal caso le regole di stile devono essere inserite successivamente alla regola @import). La regola @import definisce il path a cui trovare il foglio di stile esterno. <!DOCTYPE html> <html> <head> <title>Tecnologie web</title> <style> @import url("css/stile.css"); </style> </head> <body> <p>A questo paragrafo vengono applicate <em>regole di stile</em> in cascata.</p> </body> </html> Come per il metodo basato su <link> si possono importare più fogli di stile anche tramite @import. La regola @import può anche essere utilizzata all'interno di un foglio di stile esterno. Il vantaggio di utilizzare fogli di stile esterni è che è possibile applicare lo stesso foglio di stile a più documenti HTML. • Fogli di stile embedded. Le regole di stile vengono incluse nel documento HTML tramite utilizzo dell'elemento <style>, inserito comunemente all'interno di <head> (HTML5 consente di includerlo all'interno di <body>). E' possibile utilizzare l'attributo “type” per specificare il tipo di foglio di stile (non necessario in HTML5). Le regole specificate in questo modo si applicano solamente al documento in cui sono incluse. Il seguente esempio di foglio di stile embedded mostra anche la sintassi da utilizzare per inserire commenti all'interno di un foglio di stile. <!DOCTYPE html> <html> <head> <title>Tecnologie web</title> <style type="text/css"> /* Qui vengono inserite le regole */ p { color: red; font-family: sans-serif; } </style> </head> <body> <p>A questo paragrafo vengono applicate regole di stile definite in modo embedded.</p> </body> </html> • Regole di stile inline. E' possibile applicare regole di stile a singoli elementi all'interno di un documento HTML mediante l'utilizzo dell'attributo “style”. Più regole possono essere incluse separate tramite punto e virgola. <p style="color: red; font-family: sans-serif;"> A questo paragrafo vengono applicate regole di stile definite in modo inline.</p> Questo tipo di soluzione dovrebbe essere evitata a meno che non sia assolutamente necessario per sovrascrivere una regola importata tramite i metodi precedenti. Concetti fondamentali Ereditarietà Un primo concetto fondamentale relativo a CSS è che gli elementi HTML ereditano alcune regole di stile degli elementi nei quali sono contenuti. <!DOCTYPE html> <html> <head> <title>Tecnologie web</title> <style type="text/css"> p { color: red; font-family: sans-serif; } </style> </head> <body> <p>A questo paragrafo vengono applicate <em>regole di stile</em> definite in modo embedded.</p> </body> </html> Nell'esempio precedente, all'elemento <em> viene applicato lo stesso stile dell'elemento <p> nel quale è contenuto (oltre allo specifico stile di default). Se l'elemento <p> fosse contenuto all'interno di un altro elemento a cui viene applicato uno stile relativo al testo, quello stile verrebbe ereditato sia da <p> che da <em>, e così via. Per poter capire quali regole di stile vengono applicate ad un elemento è quindi fondamentale tenere in considerazione la gerarchia degli elementi all'interno del documento html. Bisogna comunque considerare che non tutte le proprietà sono supportate da tutti gli elementi. Ad esempio, un elemento <img> inserito all'interno del paragrafo dell'esempio precedente non erediterebbe le regole del paragrafo in quanto quelle specifiche regole (relative al font) non si applicano alle immagini. Inoltre, ci sono proprietà che normalmente non vengono ereditate come, ad esempio, quelle relative a margini, bordi, o background. L'ereditarietà può essere sfruttata per semplificare i fogli di stile. Ad esempio, se si vuole applicare un certo font a tutti gli elementi testuali di un documento, non serve aggiungere una regola per ogni elemento ma basta inserire la regola per l'elemento <body> in modo tale che venga ereditata da tutti gli elementi testuali racchiusi in <body>. Una regola ereditata può essere ridefinita in uno specifico elemento in modo da applicare uno stile diverso a quell'elemento, come nell'esempio seguente. <!DOCTYPE html> <html> <head> <title>Tecnologie web</title> <style type="text/css"> p { color: red; font-family: sans-serif; } em { color: blue; } </style> </head> <body> <p>A questo paragrafo vengono applicate <em>regole di stile</em> definite in modo embedded.</p> </body> </html> Conflitti di stile Quando si applica informazione di stile ad un documento, possono presentarsi conflitti tra le regole. Questo può accadere perchè CSS consente di applicare più fogli di stile allo stesso documento o perchè sono state definite regole conflittuali all'interno di uno stesso foglio di stile. I conflitti tra fogli di stile possono essere risolti grazie al fatto che esiste una gerarchia delle diverse sorgenti di informazione di stile. In particolare, le regole definite ad un livello della gerarchia vengono passate anche ai livelli seguenti (da cui il termine “cascading” in CSS). Se viene incontrata ad un livello una regola già definita ad un livello precedente, la regola precedente viene sostituita da quella corrente (in pratica, più si scende nella gerarchia più il peso delle regole aumenta). Il risultato è un foglio di stile che combina (con eventuali ridefinizioni in caso di conflitto) le regole incluse nei diversi fogli di stile applicati ad un documento. La gerarchia considerata da CSS è la seguente: • Foglio di stile di default del browser • Foglio di stile dell'utente (tutti i browser permettono di creare un CSS che sostituisce il foglio di stile di default) • Foglio di stile esterno aggiunto tramite elemento <link> • Foglio di stile esterno importato tramite regola @import • Foglio di stile embedded tramite elemento <style> • Informazione di stile inline (attributo “style”) • Regole di stile marcate dall'autore con l'indicatore !important • Regole di stile marcate dall'utente con l'indicatore !important Nell'esempio seguente vengono applicate in cascata delle regole embedded e delle regole inline. Come si vede, le regole inline hanno la precedenza su quelle embedded. <!DOCTYPE html> <html> <head> <title>Tecnologie web</title> <style type="text/css"> p { color: red; font-family: sans-serif; } </style> </head> <body> <p style="color: black">A questo paragrafo vengono applicate regole di stile in cascata.</p> </body> </html> Nell'esempio seguente viene utilizzato l'indicatore !important per dare peso maggiore alla regola embedded relativa alla proprietà “color”. <!DOCTYPE html> <html> <head> <title>Tecnologie web</title> <style type="text/css"> p { color: red !important; font-family: sans-serif; } </style> </head> <body> <p style="color: black">A questo paragrafo vengono applicate regole di stile in cascata.</p> </body> </html> Nel caso in cui ci siano più fogli di stile esterni (quindi allo stesso livello) che entrano in conflitto tra loro, vince il foglio che viene inserito per ultimo nel codice. Oltre ai conflitti dovuti alla presenza di sorgenti di stile diverse, ci possono essere conflitti anche all'interno di uno stesso foglio di stile. Questi possono essere dovuti alla presenza di selettori diversi per lo stesso elemento, più versioni dello stesso selettore con regole differenti per la stessa proprietà, regole differenti per la stessa proprietà all'interno dello stesso selettore. Nel primo caso, vince il selettore più specifico (finora abbiamo visto un solo tipo di selettore, quello più generico che indica il nome di un elemento). Nel secondo e terzo caso, vince la regola che appare per ultima. Nei due frammenti di codice seguenti, ad esempio, la regola vincente è quella che assegna il colore green alla proprietà “color”. <style> p { color: red; } p { color: blue; } p { color: green; } </style> <style> p { color: red; color: blue; color: green; } </style> Box model Un altro concetto generale di CSS, alla base del sistema di formattazione visuale del contenuto, è il cosiddetto box model. Ogni browser vede ogni elemento html di una pagina (sia esso di tipo blocco che di tipo inline) come racchiuso all'interno di un box rettangolare. Tramite CSS è possibile definire proprietà di questi box come i bordi, i margini, il background ed altre, oltre a poterne definire il posizionamento sulla pagina web. L'esempio seguente evidenzia i diversi box tramite utilizzo della proprietà “border” dei diversi elementi. Notate come i box relativi agli elementi blocco occupino la pagina per tutta la sua larghezza mentre i box per gli elementi inline racchiudono solo il contenuto dell'elemento. <!DOCTYPE html> <html> <head> <title> Tecnologie web </title> <style type="text/css"> h1, h2, p, em, img { border: 1px solid blue; } </style> </head> <body> <article> <h1>Documentazione su Java</h1> <section> <h2>Introduzione al linguaggio</h2> <p>Uno dei principi fondamentali del linguaggio Java è espresso dal motto <em>write once, run anywhere</em> ...</p> <figure><img src="../imgs/java.jpg" alt=""/></figure> </section> <section> <h2>Storia</h2> <p>Java è stato creato a partire da ricerche effettuate alla Stanford University agli inizi degli anni Novanta ...</p> </section> </article> </body> </html> L'esempio precedente evidenzia anche un modo compatto per definire le stesse regole per elementi diversi: è sufficiente raggruppare i selettori, separati da virgole, e definire un solo blocco di dichiarazioni. Tipi principali di selettore In tutti gli esempi precedenti, abbiamo utilizzato il nome degli elementi html come selettori. Lo svantaggio di selezionare elementi in questo modo è che le regole specificate vengono applicate a tutti gli elementi di quel tipo nella pagina. Se vogliamo applicare regole in modo più specifico, dobbiamo utilizzare altri tipi di selettore. Selettori di discendenti Un selettore di discendente specifica elementi che sono contenuti in (e quindi sono discendenti di) altri elementi. Per definire un selettore di discendente si indica l'elemento contenitore seguito dall'elemento discendente, separati da uno spazio. Nell'esempio seguente, specifichiamo un selettore di discendente per gli elementi <em> contenuti all'interno di elementi <p>. Notate che abbiamo anche specificato un selettore generico per l'elemento <em> ma che la regola che viene applicata è quella del selettore più specifico. <!DOCTYPE html> <html> <head> <title> Tecnologie web </title> <style type="text/css"> em { color: red; } p em { color: blue; } </style> </head> <body> <article> <h1>Documentazione su <em>Java</em></h1> <section> <h2>Introduzione al linguaggio</h2> <p>Uno dei principi fondamentali del linguaggio Java è espresso dal motto <em>write once, run anywhere</em> ...</p> <figure><img src="../imgs/java.jpg" alt=""/></figure> </section> </article> </body> </html> E' anche possibile avere livelli di innestamento multipli. La regola seguente, ad esempio, si applica agli elementi <em> contenuti all'interno di elementi <a> contenuti in liste non ordinate <ol>. ol a em { color: gray; } Selettori di figli Nella definizione di selettori di discendenti vista in precedenza, non è impostante che l'elemento contenitore sia il padre dell'elemento di cui vogliamo specificare le regole di stile, è sufficiente che sia un suo antenato. Se vogliamo invece specificare regole che valgono per i figli diretti di uno specifico elemento, dobbiamo utilizzare i selettori di figli che vengono specificati separando padre e figlio con un simbolo di maggiore, come nell'esempio seguente. p > em { color: yellow; } La regola sopra definita si applicherà agli elementi <em> che sono direttamente contenuti all'interno di elementi <p> ma non ad elementi <em> contenuti all'interno di altri elementi anche se questi ultimi sono contenuti all'interno di elementi <p>. Selettori di fratelli adiacenti Un selettore di fratelli adiacenti identifica un elemento che appare nel codice immediatamente dopo un altro elemento all'interno dello stesso padre. I due elementi vengono separati dal simbolo +. La regola seguente si applica ad esempio a paragrafi <p> che seguono immediatamente un elemento <h1>. h1 + p { color: red; } Selettori di fratelli generici Un selettore di fratello generico identifica un elemento che appare successivamente ad un altro elemento all'interno dello stesso padre . Questo tipo di selettore è stato introdotto in CSS3. L'esempio seguente si applica ad elementi <h2> che appaiono dopo elementi <h1> (ma non necessariamente subito dopo) all'interno dello stesso padre. h1 ~ h2 { color: red; } Selettori di id Abbiamo visto in precedenza come l'attributo “id” possa essere utilizzato per assegnare un identificatore univoco ad un qualsiasi elemento html. Un selettore di id consente di creare regole di stile per un elemento identificato da uno specifico id. Per creare un tale selettore, è sufficiente unire il nome dell'elemento al valore dell'attributo “id” tramite l'utilizzo del simbolo #. Nell'esempio seguente viene creata una regola di stile per un elemento <p> con id par12. p#par12 { color: red; } Dato che gli dovrebbero essere unici, è anche possibile tralasciare il nome dell'elemento scrivendo solo il valore dell'id preceduto dal simbolo #. Un selettore di id può essere utilizzato anche come parte di un selettore contestuale (uno qualsiasi dei selettori visti nelle precedenti 4 sezioni). Il frammento seguente, ad esempio, definisce una regola per tutti gli elementi <em> contenuti all'interno del paragrafo con id par12. #par12 em { color: red; } Selettori di classe Oltre ad identificare un elemento tramite “id”, abbiamo visto in precedenza che l'attributo “class” può essere utilizzato per classificare un certo elemento come appartenente ad un gruppo. A differenza di “id”, più elementi possono appartenere allo stesso gruppo ed un elemento può appartenere a più gruppi. Un selettore di classe permette di specificare regole di stile per gli elementi appartenenti ad una specifica classe. In modo simile ai selettori di id, è possibile creare un selettore di classe unendo il nome dell'elemento al valore dell'attributo “class” tramite l'utilizzo di un punto. Nell'esempio seguente viene creata una regola di stile per tutti gli elementi <p> con attributo “class” di valore intro. p.intro { color: red; } Se vogliamo applicare una regola a tutti gli elementi di una certa classe (indipendentemente dal loro tipo), è sufficiente indicare solo il nome della classe preceduta dal punto, come nell'esempio seguente. .intro { color: red; } Conflitti di stile tra selettori Abbiamo visto in precedenza come risolvere conflitti di stile nel caso di sorgenti di stile diverse o nel caso di più versioni dello stesso selettore. Nel caso di conflitti tra selettori diversi all'interno dello stesso foglio di stile esistono delle regole di precedenza (in realtà abbastanza complicate, si veda http://www.w3.org/TR/CSS21/cascade#specificity) che possono essere riassunte in modo semplificato come segue: • I selettori di id sono più specifici e sovrascrivono • i selettori di classe, che sono più specifici e sovrascrivono • i selettori contestuali, che sono più specifici e sovrascrivono • i selettori di elemento. Quindi, nel seguente esempio, il selettore contestuale di discendente ha la precedenza sul selettore di elemento ed il testo dell'elemento <em> all'interno dei paragrafi comparirà in colore verde. em { color: red; } p em { color: green; } Nell'esempio seguente, gli elementi <em> di classe nero verranno visualizzati con colore nero anche quando compaiono all'interno di paragrafi, poiché i selettori di classe hanno la precedenza sugli altri due selettori specificati. em { color: red; } p em { color: green; } em.nero { color: black; } Altri selettori Oltre a quelli descritti in precedenza, esistono altri tipi di selettore che vengono utilizzati in casi particolari. Nelle sezioni seguenti, vedremo i più comuni mentre all'indirizzo http://www.w3.org/TR/2011/REC-css3-selectors-20110929/ potete trovare l'elenco completo. Selettori di pseudo-classe Durante la navigazione dei siti web, il browser tiene traccia di alcuni stati nei quali si possono trovare gli elementi. Ad esempio, viene tenuta traccia del fatto che un link sia stato cliccato oppure no. Tutti gli elementi che si trovano nello stesso stato fanno parte della stessa classe ma tali classi non sono definite esplicitamente nel codice, da cui il nome pseudo-classi. E' comunque possibile andare a modificare lo stile degli elementi che si trovano in una particolare pseudo-classe attraverso un tipo di particolare di selettore che dipende dal nome dello stato che si sta considerando. I selettori di pseudo-classe più utilizzati sono quelli relativi ai link (elementi <a>). In particolare, è possibile identificare tutti i link che non sono ancora stati cliccati e tutti i link che sono già stati visitati. Ciò può avvenire utilizzando i selettori :link e :visited come nell'esempio seguente. a:link { color: maroon; } a:visited { color: gray; } Inoltre, si possono utilizzare i selettori :focus, :hover e :active per indicare rispettivamente elementi (non solo link) che sono in uno stato selezionato (hanno il focus come ad esempio un campo di testo su cui l'utente sta scrivendo), su cui è posizionato il puntatore del mouse, o che sono in procinto di essere attivati. a:hover { color: gray; } a:active { color: red; } Quando vengono applicati degli stili ai link utilizzando questi selettori, il loro ordine nei fogli di stile è importante e DEVE essere :link, :visited, :focus, :hover, :active. CSS3 definisce diversi altri selettori di pseudo-classe, la maggior parte dei quali consentono la selezione di elementi in base a dove tali elementi sono posizionati all'interno della struttura di un documento. Un elenco completo con esempi è disponibile al seguente link: http://www.w3.org/TR/2011/REC-css3-selectors20110929/#pseudo-classes. Tenete anche presente che è possibile combinare tra loro le diverse categorie di selettori per ottenere risultati come applicare uno stile ai link visitati di una particolare classe. a.mainmenu:visited { color: gray; } Selettori di attributo I selettori di attributo permettono di selezionare degli elementi in base ai loro attributi. E' possibile sia effettuare selezioni in base al nome degli attributi che in base al valore degli attributi. Il selettore di attributo semplice permette di selezionare elementi in base al nome di un attributo. Ad esempio, la regola seguente si applica agli elementi <img> che hanno definito l'attributo “title”. img[title] {border: 3px solid;} Il selettore di attributo con valore esatto seleziona elementi in base ad uno specifico valore di un attributo. Ad esempio, la regola seguente si applica agli elementi <img> che hanno definito l'attributo “title” con valore Logo (la selezione è case-sensitive). img[title=“Logo”] {border: 3px solid;} Ci sono diversi altri selettori di attributo più specifici per situazioni in cui si vuole ad esempio selezionare elementi in base a parte del valore di un attributo. Si veda http://www.w3.org/TR/2011/REC-css3-selectors20110929/#attribute-selectors per un elenco completo. Selettore universale Il selettore universale, identificato dal simbolo di asterisco (*) permette di selezionare qualsiasi elemento nel contesto specificato. Ad esempio, la regola seguente rende di colore grigio tutti gli elementi in foreground di un documento. * { color: gray; }