Tra le principali novità introdotte dai CSS3 molte hanno a che fare con la gestione del background. L'aggiunta di proprietà come background-clip
, background-origin
e background-size
, insieme alla possibilità da tanto attesa di poter definire sfondi multipli per un elemento, hanno enormemente ampliato il livello di flessibilità nell'utilizzo di questa fondamentale funzione dei CSS.
Eppure, rimangono situazioni particolari per le quali la specifica non offre al momento soluzioni standard, ovvero definite nel core del linguaggio. Discuteremo in questo articolo proprio di un caso di questo tipo.
Lo scenario è quello rappresentato nella demo di cui mostriamo qui sotto il dettaglio più significativo. Si tratta di aggiungere per fini decorativi un oggetto sullo sfondo che vada a collocarsi oltre i bordi dell'elemento.
Abbiamo un box a cui è stato applicato uno sfondo a righe che emula l'aspetto di una pagina di quaderno. Nell'angolo inferiore destro abbiamo inserito l'immagine di un timbro postale. Si noti che il timbro esce dai confini del box, rimanendo interamente visibile, su un livello superiore rispetto a quello del box.
Usando le proprietà standard dei CSS, questo effetto non si può ottenere, anche se non sembrerebbe così complicato. La logica e la conoscenza delle proprietà CSS3 per gli sfondi, infatti, ci porterebbero a procedere in questo modo:
- si crea il box;
- si applicano ad esso due immagini di sfondo;
- si usa
background-position
per collocare il timbro in quella posizione.
Procediamo e verifichiamo.
Nel primo esempio inseriamo così i due sfondi:
background: url(timbro.png) no-repeat, url(righe.png);
Da notare solo che è necessario inserire prima il riferimento all'immagine del timbro perché essa dovrà apparire su un livello superiore rispetto a quello dello sfondo a righe.
Non avendo dato nessuna indicazione sulla posizione del timbro, esso apparirà nell'angolo superiore sinistro, come da default per la proprietà background-position
.
Ora dobbiamo spostarlo in basso a destra e perciò usiamo (esempio 2) questa regola:
background: url(timbro.png) 100% 100% no-repeat, url(righe.png);
Con il risultato che ci si attende:
Ma ricordate? Noi vogliamo che il timbro appaia come se fosse all'esterno del box, almeno in parte, e che sia interamente visibile!
La prima cosa che ci viene in mente è di usare valori negativi per spingere lo sfondo verso l'esterno (esempio 3):
background: url(timbro.png) -50px -50px no-repeat, url(righe.png);
L'esito è scontato:
Come viene spiegato in questo articolo di Alessandro Fulciniti:
A valore positivo per la coordinata x corrisponde una traslazione verso destra; mentre a un valore positivo per la y corrisponde una traslazione verso il basso, sempre rispetto all'origine.[…]
Analogamente, valori negativi della x corrispondono a traslazioni dello sfondo verso sinistra, mentre valori negativi della y corrispondono a traslazioni verso l'alto. L'effetto è quindi quello di traslare l'immagine di sfondo, o una parte di essa, all'esterno dell'elemento a cui è assegnata.
I problemi, come testimonia lo screenshot, sono però due. Lo spostamento verso l'esterno avviene a partire dall'angolo superiore sinistro e lo sfondo così trattato è visibile solo in parte.
Per risolvere il primo inconveniente potrebbe venirci incontro un'aggiunta recente alla specifica CSS3 che consente di impostare per la posizione degli sfondi quattro valori, due per le unità di misura e due per gli angoli di riferimento che non sono più limitati alla combinazione top/left (esempio 4):
background: url(timbro.png) right -50px bottom -50px no-repeat, url(righe.png);
Come si vede, abbiamo spostato lo sfondo di -50px e -50px rispetto all'angolo inferiore destro (right
e bottom
). Un'ottima aggiunta, non c'è dubbio, ma non risolutiva per noi. Come si evince dallo screenshot relativo al quarto esempio, su Opera 11.0, uno dei browser che supporta questa sintassi, lo sfondo rimane invisibile nella parte spostata verso l'esterno con i valori negativi:
La tecnica che ci consente di ottenere il risultato che desideriamo ricorre ad un semplice hack basato sul contenuto generato ed è stata presentata sul suo sito da Nicholas Gallagher.
Nell'esempio 5 abbiamo usato queste regole (riportiamo solo la parte di codice rilevante):
#container {
background: url(righe.png);
position: relative;
}
#container:before {
content:"";
position:absolute;
bottom:-40px;
right:-75px;
width:202px;
height:84px;
background:url(timbro.png);
}
Al box con id #container
abbiamo applicato come sfondo solo l'immagine con le righe. Poi, attraverso il posizionamento assoluto del contenuto generato, abbiamo inserito facilmente al posto giusto il timbro, impostato come sfondo. Da rilevare come le dimensioni del contenuto generato (width
e height
) corrispondano a quelle dell'immagine del timbro (202x84px).
In pratica, come sottolinea Gallagher, questa tecnica non fa che emulare il posizionamento dello sfondo, aggiungendo un ulteriore livello per il background che è svincolato dall'elemento contenitore.
Se poi vogliamo che il falso sfondo così applicato appaia anche sotto al testo, useremo nel modo opportuno la proprietà z-index
(esempio 6):
#container {
background: url(righe.png);
position: relative;
z-index: 1;
}
#container:before {
content:"";
position:absolute;
top:-20px;
right:-55px;
width:202px;
height:84px;
background:url(timbro.png);
z-index: -1;
}
Tutti gli esempi sono disponibili per il download.
Approfondimenti