Da qualche anno a questa parte l'uso dei Fogli di stile è diventato una norma nel web publishing per cui, a meno di non usare un template engine tipo smarty, ci troveremo volenti o nolenti ad inserire parti di CSS all'interno del nostro codice "sporcandolo". Cerchiamo allora, per quanto è possibile, di inserire i CSS con il minimo impatto possibile.
Css inline
Inserire i CSS inline per un dato elemento della pagina può essere molto complicato, soprattutto se le proprietà da assegnare all'elemento sono molte e dipendenti da alcune condizioni (in presenza quindi di molti costrutti IF
).
In questi casi è consigliabile utilizzare una funzione molto semplice a cui va passato un array associativo: le chiavi di questo array saranno le proprietà CSS da impostare e i valori quello da assegnare a tale proprietà. La funzione si occuperà inoltre di stampare l'attributo html style solo nel caso in cui l'array sia popolato.
<?php
function getStyle( $s ){
if( is_array($s) AND !empty($s) ){
$toReturn = ' style="'
foreach( $s AS $k=>$v ){
$toReturn .= $k . ':' . $v . ';';
}
$toReturn{strlen($toReturn)-1} = '"';
return $toReturn;
}
return '';
}
$hide = array('display'=>'none');
$ie = (strpos('Opera')!==false) OR (strpos('MSIE')===false) ? $hide : '';
$others = $ie=='' ? $hide : '';
echo 'Stai usando ';
echo '<span' . getStyle($ie) . '>Internet Explorer</span>';
echo '<span' . getStyle($others) . '>un browser diverso da Internet Explorer</span>';
?>
In questo caso si trattava di un esempio privo di utilità ma questa funzione può essere usata ad esempio per creare degli hack mirati verso un browser che decida di non seguire gli standard.
Css del documento
I CSS inoltre possono essere inseriti in testa alla pagina per specificare delle regole valide solo per essa. Per evitare di dover andare manualmente a modificare il CSS in ogni file ogni volta che si presenta una modifica, possiamo arrangiarci a rendere "esterno anche questo": usiamo un database e poche righe di codice.
Creiamo un database con tre tabelle:
CREATE TABLE stile (
id smallint(5) unsigned NOT NULL auto_increment,
identificativo varchar(255) NOT NULL,
css text NOT NULL,
ordine smallint(3) unsigned NOT NULL,
semprevalido smallint(1) unsigned NOT NULL,
PRIMARY KEY (id),
KEY tutto (semprevalido)
);
CREATE TABLE pagina (
stile smallint(5) unsigned NOT NULL,
pagina varchar(255) NOT NULL,
UNIQUE stile (stile, pagina)
);
CREATE TABLE zona (
stile smallint(5) unsigned NOT NULL,
zona varchar(255) NOT NULL,
UNIQUE stile (stile, zona)
);
Quindi basterà riempire il database inserendo nella tabella stile l'identificativo della classe, del tag o l'id, il codice CSS, l'ordine con cui mostrare il codice e 1 o 0 seconda che si desideri mostrare questo codice in ogni pagina o solo in alcune pagine particolari.
Nella tabella pagina si dovranno inserire le regole di inclusione degli stili specifici per pagina dove stile
è l'id numerico rilasciato dalla tabella stile e pagina
è l'url della pagina interessata.
Nella tabella zona invece dovremo inserire le regole di inclusione degli stili specifici per zona del sito web quindi stile sarà sempre l'id numerico dello stile e zona una parola per identificare la zona. Infine estraiamo i dati dal database con questa query:
$pagina = $_SERVER['REQUEST_URI'];
$zona = 'news';
$sql = sprintf("SELECT s.identificativo, s.css
FROM stile AS s, pagina AS p, zona AS z
WHERE s.semprevalido = 1 OR
(p.stile = s.id AND p.pagina = '%s') OR
(z.stile = s.id AND z.zona = '%s')
ORDER BY s.semprevalido DESC, s.ordine ASC",
mysql_real_escape_string($pagina),
mysql_real_escape_string($zona));
$rs = @mysql_query($sql);
while( $row = @mysql_fetch_assoc($rs) ){
echo $row['identificativo'] . ': ' . $row['css'] . ';' . "n";
}
Css esterni creati dinamicamente
Infine abbiamo anche la possibilità di interagine con i file CSS esterni al documento siano essi dei veri e propri file CSS oppure dei file PHP con il corretto content-type.
Prendiamo il primo caso: la prima possibilità che abbiamo consiste nell'utilizzare il PHP per importare nella pagina un determinato file CSS a seconda che l'utente provenga da un paese piuttosto che da un altro, sia su una particolare pagina, abbia un particolare browser o abbia eseguito un login. In questi casi non dobbiamo fare altro che andare a cercare all'interno di una delle variabili di sistema (o nel nostro sistema di login in quel caso) e inviare a video il nome del file CSS da includere di conseguenza.
La parte interessante della gestione esterna dei CSS invece riguarda la creazione dinamica degli stessi: uno script PHP può agire da CSS ed essere interpretato correttamente dai browser. Questo significa che siamo in grado di creare una grande varietà di CSS creati al volo in base allo specifico utente che ci troviamo di fronte.
Per far funzionare questa tecnica dobbiamo semplicemente inserire all'inizio dello script, prima che venga inviato ogni altro output, l'indicazione del giusto tipo di file:
<?php
header("Content-type: text/css");
?>
A questo punto possiamo inserire nel nostro foglio CSS dinamico tutte le istruzioni che vogliamo, modificandole a nostro piacimento. Ad esempio possiamo scegliere di rendere rosso lo sfondo il primo giorno del mese:
body{
background:<?php echo date(d)==1 ? 'red' : 'white'; ?>
}
L'unico accorgimento che dobbiamo prendere è quello di aggiungere un codice casuale all'inclusione del CSS. Questo per evitare che il CSS venga messo in cache dal browser mentre dovrebbe essere dinamico.
<style type="text/css">
@import css.php?<?php echo md5(mt_rand()); ?>
</style>
In alternativa potremmo fare in modo di richiamare il file in questione con un codice particolare che identifichi realmente la situazione permettendo al browser di mettere in cache versioni diverse del CSS in base alle situazioni presenti.
Anche con i CSS esterni possiamo utilizzare la tecnica della creazione di un CSS dinamico in base alla pagina di richiesta (o alla zona del sito di cui fa parte), facendo attenzione ad inserire un sistema di caching per evitare di dover rigenerare continuamente un file accedendo al database quando in realtà esso resterebbe sempre lo stesso.
Un'applicazione utile: i titoli con l'image replacement
Concludo questo articolo con un'applicazione pratica delle tecniche ibride viste fino ad ora e vediamo come rendere più facile il lavoro di image replacement per i titoli.
Innanzitutto prepariamo la base su cui andremo ad operare creando nel CSS della pagina una classe "titoletto" che si occuperà di prendere lo spazio necessario al titolo grafico che sostituirà quello testuale. Il codice di questa classe varierà secondo la tecnica di image replacement scelta ma all'incirca dovrebbe essere qualcosa del genere:
.titoletto{
width:300px; height:50px; t; background-repeat:no-repeat; text-indent:-9999em
}
A questo punto aggiungiamo una funzione utile a velocizzare il lavoro, richiamiamo la classe per il nostro titolo e aggiungiamo con la funzione vista all'inizio dell'articolo le immagini che andranno a sostituire il testo (che immaginiamo essere presente in alcune variabili).
<?php
function getTitle($title, $tag = 'h2'){
if( $title ){
$s = array('background-image'=>"url('/title.php?t=" . urlencode($title) . "')");
$toReturn = '<' . $tag . ' class="titoletto"' . getStyle($s) . '>';
$toReturn .= $title;
$toReturn .= '</' . $tag . '>';
}
return '';
}
$titolo_1 = 'Archivio';
$titolo_2 = 'Calendario';
$titolo_3 = 'Ricerca';
echo getTitle($titolo_1);
echo getTitle($titolo_2);
echo getTitle($titolo_3, 'h3');
?>
Non ci resta quindi che creare il titolo in formato grafico con le librerie gd:
<?php // title.php
$t = (isset($_GET['t']) AND $_GET['t']) ? urldecode($_GET['t']) : '';
$im = imagecreatetruecolor(300, 50);
$grey = imagecolorallocate($im, 200, 200, 200);
imagefill($im, 0, 0, $grey);
if( $t ){
$black = imagecolorallocate($im, 0, 0, 0);
imagestring($im, 3, 5, 5, $t, $black);
}
header("Content-type: image/png");
imagepng($im);
imagedestroy($im);
?>
In questo modo siamo in grado di aggiungere tutti i titoli grafici che desideriamo alla nostra pagina senza dover riscrivere ogni volta il codice CSS necessario.
Si potrebbe aggiungere per rendere il tutto più interessante la gestione del caching per le immagini e un sistema di supporto alla molteplicità di CSS permettendo quindi di aggiungere diversi stili selezionabili dall'utente al nostro sito web mantenendo il codice PHP inalterato modificando invece la resa grafica dei titoli perché si adattino meglio alle diverse skin.