jQuery: bordi rotondi sulle immagini per sovrapposizione

giovedì 30 ottobre, 2008

A 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


CSS

Sappiamo che, a parte IE, è possibile realizzare dei bordi arrotondati semplicemente sfruttando alcune specifiche CSS proprie dei singoli browser, come ad esempio:

CSS:
  1. /* Rounded Corners */
  2. div#roundBorders {
  3. border-radius: 9px; /* CSS 3 */
  4. -moz-border-radius: 9px; /* Firefox */
  5. -webkit-border-radius: 9px; /* Safari */
  6. }

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.

image

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:

JavaScript:
  1. /**
  2.  * jQuery Round Borders
  3.  *
  4.  * Crea un effetto bordo arrotondado su alcuni o tutti gli angoli di una immagine
  5.  * tramite sovrapposizione.
  6.  *
  7.  * @author           Giovambattista Fazioli
  8.  * @email            g.fazioli@undolog.com
  9.  * @web              http://www.undolog.com
  10.  *
  11.  * @usage
  12.  *    $('myimageid').roundBorders(
  13.  *                        {
  14.  *                            image:   'path/myborder.png',
  15.  *                            radius:  16,
  16.  *                            corners: 'tl br'
  17.  *                        }
  18.  *    );
  19.  *
  20.  *
  21.  */
  22.  
  23. (function($) {
  24.     jQuery.fn.roundBorders = function(settings){
  25.         return this.each(
  26.             function() {
  27.                 var $this       = $(this);
  28.                 var hash        = 'ba4aae84ef81'; // paganini not repeat
  29.                
  30.                 if( !$this.hasClass( hash ) ) {
  31.                
  32.                     $this.css('display','block');
  33.                    
  34.                     var defaults = {
  35.                         radius:       settings.radius     || 16,
  36.                         image:        settings.image      || 'border.png',
  37.                         width:        settings.width      || $this.attr('width'),
  38.                         height:       settings.height     || $this.attr('height'),
  39.                         center:       settings.center     || 'no',
  40.                         corners:      settings.corners    || 'tl tr bl br'
  41.                     };
  42.                    
  43.                     var ra    = defaults.radius;
  44.                     var ww    = defaults.width;
  45.                     var hh    = defaults.height;
  46.                     var im    = defaults.image;
  47.                     var to    = -hh;
  48.                     var tr    = ww-ra;
  49.                     var bl    = to+hh-ra;
  50.                     var cc    = (defaults.center == 'no')?'':'margin:0 auto';
  51.                    
  52.                     var out   = '';
  53.                     var cr    = defaults.corners.split(' ');
  54.                     var co    = {};
  55.                    
  56.                     co.tl    = '<div style="background:url('+im+') no-repeat;position:absolute;width:'+ra+'px;height:'+ra+'px;margin:'+to+'px 0 0 0"></div>';
  57.                     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>';
  58.                     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>';
  59.                     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>';
  60.                    
  61.                     for(var o in cr) if(co[cr[o]]) out += co[cr[o]];
  62.                    
  63.                     $this
  64.                         .wrap('<div style="width:'+ww+'px;height:'+hh+'px;'+cc+'"></div>')
  65.                         .after( out ).addClass( hash ).fadeIn('slow');
  66.                 }
  67.             }
  68.         );
  69.     }
  70. })(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:

Scarica l'immagine in formato PSD
(scarica il file PSD o PNG)

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:

image

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).

Post correlati

Questo articolo ti è stato utile?: Per nientePocoAbbastanzaMoltoMoltissimo
Loading ... Loading ...

Un commento a: “jQuery: bordi rotondi sulle immagini per sovrapposizione”

  1. 17 gen, 2010 gairo:

    -- 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.

Lascia un commento

TAG XHTML PERMESSI: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> INSERIMENTO CODICE:
<pre></pre>         // blocco generico
[code][/code]       // blocco generico
[as][/as]           // Actionscript
[css][/css]         // CSS Style Sheet
[html][/html]       // HTML
[js][/js]           // Javascript
[objc][/objc]       // Objective-C
[php][/php]         // PHP
[sql][/sql]         // SQL