CSS razionalizzati con CleanCSS

Durante lo sviluppo di siti web con layout complessi, è facile perdere il controllo dei fogli di stile che si possono evolvere in complessità più rapidamente dei pokémon.

PokèCSS

Nel tentativo di arginare il problema nel mio ultimo progetto (sviluppato in python) ho deciso di provare CleverCSS. Una libreria python per scrivere CSS “alla python” in maniera più organizzata e con l’aggiunta di molte funzionalità. La soluzione non è stata però ottimale dato che le funzionalità aggiunte da CleverCSS andavano spesso a intralciare con la loro sintassi alcune regole, sputando eccezioni fin troppo spesso.

La mia soluzione è stata la riscrittura del parser di CleverCSS senza tutte le sue funzionalità avanzate che di fatto non mi sono mai servite. Il risultato è CleanCSS, inizialmente scritta per python e poi portata anche per PHP.

La sintassi

Vediamo un semplice CSS con alcune regole

#header, #footer {
        margin: 0;
        padding: 0;
        font-family: Verdana, sans-serif
        font-size: .9em
}

#header li,
#footer li {
        padding: 0.4em;
        margin: 0.8em 0 0.8em;
}

#header li a,
#footer li a {
        color: black;
}

In questo esempio gli elementi LI sono gerarchicamente legati agli elementi #header e #footer (e gli A a loro volta ai LI) ma la sintassi dei CSS non ci aiuta a visualizzare questo rapporto tra le regole.

Ecco come possiamo definire le stesse regole in un CCSS (CleanCSS ricordate?)

#header, #footer:
        margin: 0
        padding: 0
        font->
                family: Verdana, sans-serif
                size: .9em

        li:
                padding: 0.4em
                margin: 0.8em 0 0.8em

                a:
                        color: black

Come potete notare CleanCSS eredita dal linguaggio Python la sua sintassi indentata. L’indentazione gioca un ruolo fondamentale definendo la gerarchia del codice e deve essere omogenea. Il rapporto tra gli elementi è ora lampante ed è più facile mantenere organizzato, oltre che compatto, il codice anche dopo molte modifiche.

Oltre alla sintassi indentata e alla struttura gerarchica, CleanCSS supporta altre due sintassi particolari.

E’ possibile spezzare proprietà CSS che hanno un trattino nel nome come segue:

div:
        font->
                family: sans-serif
                size: 10pt
        border->
                radius: 5px
                color: black

Che diventa:

div {
        font-family: sans-serif;
        font-size: 10pt;
        border-radius: 5px;
        border-color: black;
}

Ed è possibile specificare che una sotto-regola deve “attaccarsi” alla regola padre usando il prefisso &. Ad esempio:

a:
        &:hover:
                color: red
        &:focus:
                color: blue
input:
        font-weight: bold
        &[type=text]:
                font-size: 10px

Che diventa:

a:hover {
        color: red;
}
a:focus {
        color: blue;
}
input {
        font-weight: bold;
}
input[type=text] {
        font-size: 10px;
}

Come si usa?

Il funzionamento è semplice. Basta dare in pasto il sorgente in formato ccss a CleanCSS e la libreria provvederà a convertirlo nel formato CSS che verrà poi servito al browser. E’ però consigliabile fare cache del CSS risultante in modo da non dover operare la conversione ad ogni richiesta, ad esempio pubblicando una versione statica del file convertito o con altri sistemi come memcached.

Come fare cache va al di là dello scopo di questo articolo e viene quindi lasciato come compito al lettore.

PHP

require_once('cleancss.php');
header('Content-Type: text/css');
echo CleanCSS::convert('file.ccss');

Oppure usando il metodo output che si occupa anche di impostare gli header corretti.

require_once('cleancss.php');
CleanCSS::output('file.ccss');

Python

[python]import cleancss
print cleancss.convert(‘file.ccss’);[/python]

Oppure da riga di comando.

python -m cleancss file.ccss > file.css

Come lo installo

La versione PHP si installa semplicemente copiando il file cleancss.php che trovate su github all’interno di una cartella nel include_path.

La versione Python è disponibile anch’essa su github o su PyPI. Ma se usate pip, è sufficiente il comando:

pip install cleancss