Pillole CSS n.1
Sommario
- Esercizio sui float complessi
- Errori di parsing
- Fogli di stile utente in Firefox
- L'Acid Test 2 dal punto di vista di un parser CSS
- Contenuto generato: normal o none?
- Clear dei float: aggiornamento per Internet Explorer 7
- Clear dei float: Andy Budd (2003)
- Gestire l'elemento del
- Gestione dei caratteri speciali nei CSS
- Gestire l'elemento hr
- CSS scanner: i token
- Il float secondo Microsoft
Esercizio sui float complessi
Per comprendere appieno il funzionamento dei float, e di ogni altra caratteristica dei fogli di stile, a volte è necessario ricorrere ad esercizi ad hoc che ne illustrino i dettagli. Per esempio, si consideri la seguente immagine:
Float annidati
Si potrebbe partire dalla seguente marcatura:
<div id="box"> <div id="left"> <div id="left1"> <div id="lefta"> <div id="subleft"> <div id="subleft1"></div> <div id="subleft2"></div> <div id="subleft3"></div> </div> <div id="subright"></div> </div> <div id="leftb"></div> <div id="leftc"></div> </div> <div id="left2"></div> <div id="left3"></div> </div> <div id="right"></div> </div>
In questa struttura notiamo che alcuni elementi sono flottati ed altri no. Fondamentalmente occorre tener presente la dimensione di ciascun elemento in relazione alla dimensione complessiva del suo contenitore. Quindi avremo il seguente codice CSS:
body {margin: 2em 0; padding: 0;}
#box {
margin: 0 auto;
width: 600px;
height: 600px;
background: #0c0;
color: #fff;
}
#left {
margin: 0;
width: 300px;
height: 600px;
background: #ffc;
color: #000;
float: left;
}
#right {
margin: 0;
width: 300px;
height: 600px;
float: right;
}
#left1 {
margin: 0;
width: 100px;
height: 300px;
background: green;
float: left;
}
#left2 {
margin: 0;
width: 100px;
height: 300px;
background: yellow;
float: left;
}
#left3 {
margin: 0;
width: 100px;
height: 300px;
background: lime;
float: left;
}
#lefta, #leftb, #leftc {
width: 100px;
height: 100px;
margin: 0;
}
#lefta {background: #00f;}
#leftb {background: #693;}
#leftc {background: teal;}
#subleft {
float: left;
margin: 0;
width: 50px;
height: 100px;
background: maroon;
}
#subleft1 {
float: left;
width: 25px;
height: 25px;
background: pink;
}
#subleft2 {
float: right;
width: 25px;
height: 25px;
background: fuchsia;
}
#subleft1, #subleft2 {margin: 0;}
#subleft3 {
clear: both;
margin: 0;
height: 50px;
background: orange;
}
#subright {
float: right;
margin: 0;
width: 50px;
height: 100px;
background: purple;
}
Notiamo che i float in questo caso sono spesso autocontenuti dal loro genitore, che ha sempre un'altezza esplicita. Occorre calcolare sempre le dimensioni complessive degli elementi al fine di evitare problemi di sovrapposizione o di superamento dei limiti del box.
Errori di parsing
Osservando la pagina di un' intervista a Noam Chomsky ho notato un errore ripetuto nel parsing del foglio di stile:
Avviso: Era atteso ',' o '{', invece si è trovato 'html'. Insieme di regole ignorato a causa del selettore errato.
Avviso: Era atteso ',' o '{', invece si è trovato 'html'. Insieme di regole ignorato a causa del selettore errato.
Avviso: Era atteso ',' o '{', invece si è trovato 'html'. Insieme di regole ignorato a causa del selettore errato.
Avviso: Era atteso ',' o '{', invece si è trovato 'html'. Insieme di regole ignorato a causa del selettore errato.
La sezione di codice incriminato è la seguente:
*html #wrapper_left {
height: 100%;
overflow: visible;
}
*html #wrapper_right {
height: 100%;
width: 901px;
overflow: visible;
}
*html #middle {
height: 100%;
}
*html body#shows #middle {
padding-right: 0px;
}
Il parser di Firefox (o meglio, lo scanner) attendeva dopo
il selettore universale due delimitatori (DELIM), invece non ha trovato lo spazio tra il selettore universale
e quello di tipo, e quindi ha considerato il tutto come un unico selettore. Quando si scrivono hack per Internet Explorer si dovrebbe
avere l'accortezza di 1) scriverli in un file separato e 2) scriverli nel modo corretto (se di correttezza si può parlare).
Fogli di stile utente in Firefox
Nella cartella defaults/profile/chrome vi sono due fogli di stile. In uno di essi (userContent-example.css) viene descritto il modo con cui creare un foglio di stile utente:
Modificare questo file e copiarlo come userContent.css nel proprio profilo-directory/chrome/
Questo file può essere utile per applicare uno stile a tutte le pagine visualizzate. Le regole senza
!importantvengono sovrascritte dalle impostazioni dell'autore, se esistenti. Le regole con!importantsovrascrivono quelle dell'autore.esempio: disattivare il lampeggio dell'elemento
blinkblink { text-decoration: none ! important; }esempio: imposta un bordo di 2px a tutte le tabelle
table { border: 2px solid; }esempio: disattiva l'elemento
marqueemarquee { -moz-binding: none; }Per altri esempi consultare http://www.mozilla.org/unix/customizing.html
L'Acid Test 2 dal punto di vista di un parser CSS
Grazie alla Web Developer Toolbar di Chris Pederick è possibile seguire l'analisi del foglio di stile dell' Acid Test 2 da parte del parser di Firefox. Questi sono i risultati:
- Avviso: Era atteso ']' per terminare il selettore di attributo, invece si è trovato 'two'. Insieme di regole ignorato a causa del selettore errato. Riga: 44
- Avviso: Proprietà sconosciuta 'error'. Dichiarazione tralasciata. Riga: 95
- Avviso: Proprietà sconosciuta 'm rgin'. Dichiarazione tralasciata. Riga: 98
- Avviso: Selettore atteso. Insieme di regole ignorato a causa del selettore errato. Riga: 99
- Avviso: Errore nell'interpretazione del valore della proprietà 'width'. Dichiarazione tralasciata. Riga: 100
- Avviso: Era attesa la fine del valore per la proprietà, invece si è trovato 'pink'. Errore nell'interpretazione del valore della proprietà 'background'. Dichiarazione tralasciata. Riga: 102
- Avviso: Era atteso 'important', invece si è trovato 'error'. Riga: 101
Interessante notare come Internet Explorer 5 fallisce notoriamente al punto 3 nella gestione degli escape.
Contenuto generato: normal o none?
normal e none sono due valori della proprietà 'content'.
Dato il seguente codice CSS:
#generated div {
color: blue;
}
#generated div:before {
content: "Generated ";
}
#generated div.normal {
color: red;
}
#generated div.normal:before {
content: normal;
}
E data la seguente marcatura:
<div id="generated"> <div>Static</div> <div class="normal">Static</div> </div>
l'elemento con classe normal non avrà la parola "Generated"
davanti a se. Le specifiche (non ancora ufficiali) 2.1 affermano che normal viene calcolato come
none per gli pseudo-elementi :before ed :after.
Dopo vari test su Firefox, Opera e Safari 3, sembra che il valore none venga ignorato in favore di normal.
Per quanto riguarda i browser standard compliant che ancora non hanno implementato quanto specificato nei CSS 2.1
(ossia i valori normal e none), per sopprimere il contenuto generato è
sufficiente introdurre una stringa vuota. Esempio:
a[href]:after {
content: " ";
}
Clear dei float: aggiornamento per Internet Explorer 7
Riporto e traduco un articolo da Soxiam:
Questa versione aggiornata del Metodo Easy Clearing di Position Is Everything (altrimenti noto come "Dare il clear ai float senza marcatura strutturale") scaturisce da Roger Johansson di 456 Berea Street.
Dato che IE7 non supporta gli pseudo-elementi del contenuto generato, questa aggiunta alla tecnica esistente si basa su
display: inline-blockedisplay: block:.clearfix:after { content:"."; display:block; height:0; clear:both; visibility:hidden; } .clearfix { display:inline-block; } .clearfix { display:block; } * html .clearfix { height:1px; }
Clear dei float: Andy Budd (2003)
Riporto e traduco il post di Andy Budd:
Soluzioni CSS #2 - Clear dei float | 18 dicembre 2003
Quando si fanno flottare gli elementi è abbastanza comune aggiungere un elemento nel documento con il solo scopo di dare il clear al float precedente.
In un sito a cui sto attualmente lavorando, il nostro sviluppatore ha aggiunto un elemento
<br class="clear" />per svolgere tale compito. Funzionava bene in Safari ma in IE/Win esso dava il clear solo al float precedente e non a tutti i float.Ho pensato che il problema fosse dovuto al fatto che
<br />è inline, così l'ho trasformato in un elemento di blocco. Tuttavia non funzionava ancora in IE. Sarebbe stato meglio da un punto di vista semantico essere in grado di usare un<br />, comunque alla fine si è deciso di usare un elemento di blocco. Abbiamo di fatto usato un elemento<p>con un , ma di solito avrei fatto questo:.clear { clear: both; height: 0; } <div class="clear"><!-- --></div>Questo ha il beneficio aggiuntivo di non lasciare spazio verticale, cosa abbastanza importante in alcuni layout.
Postato il 18 dicembre 2003, 11:26 AM
Gestire l'elemento del
Ingo Chao ha trovato una soluzione interessante:
del {display: none;}
In effetti non è necessario che l'elemento del ed il suo contenuto vengano rappresentati sulla pagina.
Una soluzione più grossolana, simile ad una cancellatura con pennarello, sarebbe:
del {
background: #000;
color: #333;
}
In questo caso andremmo però incontro a dei problemi nel check sull'accessibilità del sito, in quanto il contrasto proposto non soddisfa i criteri del W3C.
Tuttavia anche la soluzione di Ingo presenta dei problemi con i lettori di schermo, che non leggeranno il contenuto dell'elemento. Bisogna chiedersi se il contenuto è rilevante ai fini della comprensione della pagina. In caso affermativo, s i può usare questa soluzione alternativa:
del {
position: absolute;
top: -1000em;
}
In caso contrario va bene la soluzione di Ingo.
Gestione dei caratteri speciali nei CSS
Ho realizzato il seguente codice per verificare il supporto ai caratteri speciali nei fogli di stile. La marcatura è semplicissima:
<p id="@"> This should not be green. This should be teal. </p> <p id="a@"> This should not be red. This should be navy. </p> <p id="@">This should be teal</p>
Il codice CSS è altrettanto semplice:
@charset "utf-8";
#@ {color: green;}
#a@ {color: red;}
#\0040 {color: teal;}
#a\0040 {color: navy;}
La regola-at @charset specifica il tipo di codifica che stiamo usando nel foglio di stile.
Quando si usano caratteri speciali è consigliabile usare sempre la codifica UTF-8.
Notiamo che i primi due colori non vengono applicati, in quanto le prime due regole non possono essere onorate per il fatto che il carattere chiocciola è stato inserito senza usare l'opportuna codifica Unicode, specificata da un escape seguito dal codice del carattere da inserire. Al contrario, la terza e quarta regola segue questa formula, e quindi i colori vengono applicati come specificato.
Per noi occidentali questa caratteristica dei fogli di stile può sembrare inusuale, ma per le lingue orientali si rivela decisiva al fine di permettere agli sviluppatori di dare un nome ai selettori nella loro lingua e con i loro caratteri, applicando poi le regole di stile corrispondenti.
Gestire l'elemento hr
La gestione dell'elemento hr è sempre stata una fonte di preoccupazione per i designer.
Infatti questo elemento presenta dei problemi di compatibilità cross-browser dovuti alla differente interpretazione che ogni browser da all'elemento.
I problemi principali sono soprattutto quelli relativi alla gestione del bordo dell'elemento e d alla sua formattazione verticale. Riassumendo, si incontrano le seguenti difficoltà:
- I margini verticali vengono calcolati in modo differente.
- Specificare un bordo per l'elemento produce risultati diversi.
- Attribuire un'immagine di sfondo porta a risultati inattesi.
Alcuni anni fa Marek Prokop ha pubblicato un
articolo
nel quale illustrava i vari metodi per bypassare il problema. Il metodo certamente più
efficace consiste nell'eliminare l'elemento hr e sostituirlo con un elemento
div a cui si andranno ad attribuire gli stili desiderati. Il codice (X)HTML
è simile al seguente:
<div class="center"> <div class="hr"><hr></div> </div>
Il div con classe .center serve a
centrare l'elemento anche in Internet Explorer 5 Windows. Il codice CSS sarà:
hr {display: none;}
div.hr {
height: 1px;
margin: 0 auto;
border-top: 1px solid #000;
width: 70%;
}
div.center {text-align: center;}
Il risultato finale sarà uniforme in tutti i browser.
Se avessimo voluto attribuire un'immagine di sfondo avremmo semplicemente dovuto specificarla per l'elemento
con classe .hr, ovviamente impostando per esso delle dimensioni adeguate a quelle dell'immagine.
CSS scanner: i token
Il file header nsCSSScanner.h dello scanner lessicale di Firefox è
estremamente interessante. Ne riporto una parte:
// Tipi di token
enum nsCSSTokenType {
// Identificatore CSS (es. foo)
eCSSToken_Ident, // mIdent
// Parola chiave at (es. @foo)
eCSSToken_AtKeyword, // mIdent
// Un numero CSS senza una percentuale
// o una dimensione;
// con percentuale;
// senza percentuale ma con una dimensione
eCSSToken_Number, // mNumber
eCSSToken_Percentage, // mNumber
eCSSToken_Dimension, // mNumber + mIdent
// Una stringa CSS (es. "foo" o 'foo')
eCSSToken_String, // mSymbol + mIdent + mSymbol
// Spazio bianco (es. " " o "/* abc */")
eCSSToken_WhiteSpace, // mIdent
// Un simbolo CSS (e.g. ':', ';', '+', ecc.)
eCSSToken_Symbol, // mSymbol
// Un ID CSS1 (es. #foo3)
eCSSToken_ID, // mIdent
// Come eCSSToken_ID,
// ma la parte che segue il '#' non è
// un identificatore CSS valido
// (es. inizia con una cifra
// è una stringa vuota,
//ecc.).
eCSSToken_Ref, // mIdent
eCSSToken_Function, // mIdent
eCSSToken_URL, // mIdent
eCSSToken_InvalidURL, // non importa
eCSSToken_HTMLComment,
// "<!--" o "-->"
eCSSToken_Includes, // "~="
eCSSToken_Dashmatch, // "|="
eCSSToken_Beginsmatch, // "^="
eCSSToken_Endsmatch, // "$="
eCSSToken_Containsmatch, // "*="
// Un token speciale che indica che
// c'è stato un errore nella
// tokenizzazione.
// È sempre una stringa priva di terminazione.
eCSSToken_Error // mSymbol + mIdent
};
In questo lungo elenco di token, riconosciamo i volti noti dei selettori di attributo CSS3:
eCSSToken_Dashmatch, // "|=" eCSSToken_Beginsmatch, // "^=" eCSSToken_Endsmatch, // "$=" eCSSToken_Containsmatch, // "*="
Notiamo anche il particolare trattamento riservato ai commenti all'interno dei fogli di stile:
// Spazio bianco (es. " " o "/* abc */") eCSSToken_WhiteSpace, // mIdent
Ricordiamo i noti problemi di Internet Explorer 6 (ed inferiori) nella gestione degli spazi e dei commenti.
Il float secondo Microsoft
Tra le risorse sui CSS della
reference di Microsoft,
ho trovato un'interessante annotazione sulla proprietà float:
div and span objects must have a width set for the float attribute to render. In Microsoft Internet Explorer 5, div and span objects are assigned a width by default and will render if a width is not specified.
Ciò è particolarmente interessante, perché ci permette di osservare il comportamento di
Internet Explorer 5, ossia l'assegnazione automatica di una larghezza agli elementi div e span privi
di una dichiarazione esplicita. Bisognerebbe stabilire se questa larghezza segue l'algoritmo shrink-to-fit o qualche
altro tipo di computazione. Singolare il fatto che non si parli anche di altri elementi. Altrettanto singolare e l'obbligo
di avere una larghezza esplicita.