jQuery: bordi rotondi sulle immagini per sovrapposizione
giovedì 30 ottobre, 2008A causa dei diversi rendering tra i vari browser, che vedono sicuramente Microsoft Internet Explorer in testa, bisogna sempre ricorrere ad artifizi particolari per applicare effetti che, ormai, dovrebbero rappresentare uno standard. I pluri-discussi bordi arrotondati sono un classico esempio del "disastro" prodotto dalla completa incapacità di realizzare uno standard serio sul rendering delle pagine HTML/CSS. Esistono in rete numerosissime soluzioni che permettono di ottenere "effetti" (effetti che esonerano dall'HTML attuale come bordi arrotondati, effetti ombra, riflessioni, etc...) con patch sui fogli di stili, particolari trucchi con l'uso di div innestati, librerie Javascript, uso delle canvas, etc...
A titolo puramente didattico vorrei illustrare un'ulteriore tecnica (cross-browser) per applicare dei bordi arrotondati a delle immagini:
Demo e sorgenti
- Progetto completo su Google Code
- demo
- jquery.roundborders.js
- immagine in formato Photoshop
- immagine in formato PNG
CSS
Sappiamo che, a parte IE, è possibile realizzare dei bordi arrotondati semplicemente sfruttando alcune specifiche CSS proprie dei singoli browser, come ad esempio:
-
/* Rounded Corners */
-
div#roundBorders {
-
border-radius: 9px; /* CSS 3 */
-
-moz-border-radius: 9px; /* Firefox */
-
-webkit-border-radius: 9px; /* Safari */
-
}
Nota: mi permetto qui di sottolineare quanto assurdo sia questo stato di cose. Se ogni browser inizia a definirsi i propri stili CSS il coas più totale è alle porte. Inoltre uno standard è tale quando è "identico" per tutti, altrimenti che standard è? Non è davvero possibile accettare questo stato di cose, ritrovarsi che per impostare un bordo di 4px ci voglio 8 linee di codice CSS.
Questa procedura, tuttavia, nonostante risolva la questione "bordi" non funziona sulle immagini. Così una possibile soluzione è quella di applicare, ad uno dei qualsiasi angoli di una immmagine o a tutti e quattro, un'alra immagine costruita in modo da "simulare" un bordo arrotondato. In pratica andremo a sovrapporre le immagini del bordo alla nostra immagine "target", fruttando la capacità dei file GIF e PNG di essere resi con la trasparenza.
> Pro
- funziona su tutti i browser (FireFox, Opera, Safari, Chrome, Flock, IE 7)
- comodo quando serve un'intervento rapido e mirato
- completa personalizzazione dell'immagine che rappresenta i bordi, con la possibilità di personalizzare ogni singolo bordo
- Javascript compatto e parametrizzabile: possibilità di scegliere su quali angoli dell'immagine agire
- non necessita di fogli di stile (CSS)
> Contro
- la dimensione del bordo e il colore dipendono dall'immagine: bordi diversi e sfondi diversi richiedono immagini diverse
- richiede Javascript attivo
La tecnica
Per applicare i quattro bordi agli angoli di un'immagine sfrutteremo jQuery per "avvolgere" il tag img con un div contenitore. Subito sotto il tag img inseriremo quattro div, posizionati in modalità assoluta, che corrisponderanno ai nostri angoli. Lo script jQuery jquery.roundborders.js è costruito come estensione, plugin, e il metodo roundBorders() accetta una serie di opzioni tra cui gli angoli su cui effettuare il bordo morbido. Ne segue che al massimo verranno aggiunti cinque div: un contenitore più i quattro angoli.

I quattro div mostrati nell'immagine qui sopra si andranno a sovrapporre all'immagine quando imposteremo lo stile position in absolute. Poi, tramite l'uso del margin, verranno posizionati uno ad uno ai quattro angoli dell'immagine. Ecco il codice di jquery.roundborders.js:
-
/**
-
* jQuery Round Borders
-
*
-
* Crea un effetto bordo arrotondado su alcuni o tutti gli angoli di una immagine
-
* tramite sovrapposizione.
-
*
-
* @author Giovambattista Fazioli
-
* @email g.fazioli@undolog.com
-
* @web http://www.undolog.com
-
*
-
* @usage
-
* $('myimageid').roundBorders(
-
* {
-
* image: 'path/myborder.png',
-
* radius: 16,
-
* corners: 'tl br'
-
* }
-
* );
-
*
-
*
-
*/
-
-
(function($) {
-
jQuery.fn.roundBorders = function(settings){
-
return this.each(
-
function() {
-
var $this = $(this);
-
var hash = 'ba4aae84ef81'; // paganini not repeat
-
-
if( !$this.hasClass( hash ) ) {
-
-
$this.css('display','block');
-
-
var defaults = {
-
radius: settings.radius || 16,
-
image: settings.image || 'border.png',
-
width: settings.width || $this.attr('width'),
-
height: settings.height || $this.attr('height'),
-
center: settings.center || 'no',
-
corners: settings.corners || 'tl tr bl br'
-
};
-
-
var ra = defaults.radius;
-
var ww = defaults.width;
-
var hh = defaults.height;
-
var im = defaults.image;
-
var to = -hh;
-
var tr = ww-ra;
-
var bl = to+hh-ra;
-
var cc = (defaults.center == 'no')?'':'margin:0 auto';
-
-
var out = '';
-
var cr = defaults.corners.split(' ');
-
var co = {};
-
-
co.tl = '<div style="background:url('+im+') no-repeat;position:absolute;width:'+ra+'px;height:'+ra+'px;margin:'+to+'px 0 0 0"></div>';
-
co.tr = '<div style="background:url('+im+') -'+ra+'px 0px no-repeat;position:absolute;width:'+ra+'px;height:'+ra+'px;margin:'+to+'px 0 0 '+tr+'px"></div>';
-
co.bl = '<div style="background:url('+im+') -'+(ra*2)+'px 0px no-repeat;position:absolute;width:'+ra+'px;height:'+ra+'px;margin:'+bl+'px 0 0 0"></div>';
-
co.br = '<div style="background:url('+im+') -'+(ra*3)+'px 0px no-repeat;position:absolute;width:'+ra+'px;height:'+ra+'px;margin:'+bl+'px 0 0 '+tr+'px"></div>';
-
-
for(var o in cr) if(co[cr[o]]) out += co[cr[o]];
-
-
$this
-
.wrap('<div style="width:'+ww+'px;height:'+hh+'px;'+cc+'"></div>')
-
.after( out ).addClass( hash ).fadeIn('slow');
-
}
-
}
-
);
-
}
-
})(jQuery);
Immagine dei bordi
Come anticipato precedentemente, uno dei "contro" di questa tecnica risiede nella necessità di creare un'immagine che rappresenti i nostri bordi. Questo svantaggio, tuttavia, può trasformarsi in un vantaggio se abbiamo necessità di creare bordi complessi e non semplicemente degli "arrotondamenti" classici. Comunque sia vediamo come deve essere realizzata l'immagine per dei bordi semplici. Nel nostro esempio vogliamo creare un bordo arrotondato di 16px. Sfrutteremo poi una caratteristica degli stili in modo da "fondere" i nostri quattro bordi in un'unica immagine. In questo modo avremo una singola immagine di 64x16 pixel, come mostrato qui sotto:
Ogni box rappresenta un angolo e ha la dimensione di 16x16 pixel. Lo sfondo nera rappresenta il colore trasparente mentre il bianco è il coloro dello sfondo dove si trova la nostra immagine. Se il vostro sito ha uno sfondo diverso basta sostituire il bianco con il colore del vostro sito. L'immagine risulterà quindi:
L'ordine degli angoli è obbligatorio: top left (angolo in alto a sinistra), top right (angolo in alto a destra), bottom left (angolo in basso a sinistra) e bottom right (angolo in basso a destra).











19

-- citazione: --
"Nota: mi permetto qui di sottolineare quanto assurdo sia questo stato di cose. Se ogni browser inizia a definirsi i propri stili CSS il coas più totale è alle porte. Inoltre uno standard è tale quando è "identico" per tutti, altrimenti che standard è? Non è davvero possibile accettare questo stato di cose, ritrovarsi che per impostare un bordo di 4px ci voglio 8 linee di codice CSS."
-- fine citazione --
Quoto al 100% sarebbe proprio ora che chi fa gli standard fosse anche seguito e se ci sono nuove implementazioni tutti si uniformino con i successivi aggiornamenti dei browser.