Bottoni responsive con jQuery e CSS

Bottoni responsive con jQuery e CSS

Un semplice plug-in in jQuery e una media query in CSS per dare a tutti gli elementi di un contenitore la stessa larghezza e renderli responsive.

Intro

La larghezza degli elementi di un contenitore in HTML5, ad esempio dei <button> dentro un <div>, viene normalmente calcolata dinamicamente dal browser sulla larghezza del contenuto.

Quindi un gruppo di bottoni, a meno di una regola nel CSS, apparirà di default così:

Bottoni default

Bottoni di dimensioni diverse

Ma anche nel caso fissassimo la proprietà width dei bottoni nel foglio di stile dovremmo procedere per tentativi ed errori per trovare la larghezza giusta.

Come fare? Vi farò vedere ora come estrarre con Javascript la larghezza del maggiore tra i bottoni e assegnarla anche agli altri, aggiungendo una media query nel CSS per rendere il tutto responsive.

HTML e CSS

Il nostro mark-up di partenza è molto semplice:

<div class="organize">
   <button>Get Started</button>
   <button>Download</button>
   <button>See</button>
</div>

Con CSS diamo un minimo di stile ai nostri bottoni:

button {
   background: rgb(28, 184, 65);
   color: white;
   border-radius: 4px;
   text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
   font: inherit;
}

button:hover {
   text-decoration:none;
   color: black;
}

Quindi creiamo una classe che dovrà estendere le proprietà a tutti gli elementi presenti nel div:

div.organize * {
   display: block;
   margin:5px 0;
   width:100%;
}

A questo punto i bottoni appariranno così:

Bottoni per Mobile

Bottoni per Mobile

Che è una visione comoda per il MOBILE ma non ha senso su di uno schermo con una larghezza maggiore di 40em/640px, come quello di un Tablet o un PC. Quindi aggiungeremo una media query per adattare la larghezza dei bottoni al device in uso:

@media screen and (min-width: 40em) {
   div.organize *{
      display: inline-block;
      width:auto;
    }
}

Cosa succede? Per tutti gli schermi oltre i 40em (equivalenti a 640px) di larghezza:

  • la proprietà display passa da block a inline-block,
  • la larghezza da 100% a auto.

inline-block permette a un tag di mantenere le caratteristiche di un elemento block ma esso viene fatto scorrere a destra e allineato orizzontalmente, in questo caso funziona meglio di float:left perché ci permette di avere un’altezza fissa e non dobbiamo ricorrere ad alcun workaround tipo clearfix.

Il risultato su PC sarà:

Bottoni default

Bottoni per pc

Javascript

A questo punto per adattare anche a risoluzioni oltre i 40em la larghezza dei bottoni scriveremo un piccolo pug-in per jQuery il cui scheletro è il seguente:

(function ( $ ) {
   $.fn.getSameWidth = function (){
      (.... qui andrà la funzione..)
   };
}( jQuery ));

Per prima cosa creiamo un array vuoto e importiamo in una variabile il selettore che sceglieremo per l’elemento da trasformare:

var w=[];
var selector = this;

Aggiungiamo all’array le larghezze di tutti gli elementi figli del selettore:

$(selector).children().each(function(){
   var val = $(this).outerWidth();
   w.push(val);
});

Estraiamo dall’array il valore più alto usando la funzione Math:

var maxw = Math.max.apply(Math, w);

Cambiamo il valore della larghezza se ha proprietà inline-block nel CSS:

if($(selector).children().css('display')=='inline-block'){
   $(selector).children().css('width', maxw);
}

Rendiamo la funzione ricorsiva al ridimensionamento della finestra:

$(window).resize(function () {
   $(selector).children().removeAttr( "style" );
   $(selector).getSameWidth();
});

Mettendo tutto assieme il plug-in apparirà così:

(function ( $ ) {
   $.fn.getSameWidth = function (){
      var w=[];
      var selector = this;
      $(selector).children().each(function(){
         var val = $(this).outerWidth();
         w.push(val);
     });
     var maxw = Math.max.apply(Math, w);
     if($(selector).children().css('display')=='inline-block'){
        $(selector).children().css('width', maxw);
     }
     $(window).resize(function () {
        $(selector).children().removeAttr( "style" );
        $(selector).getSameWidth();
     });
   };
}( jQuery ));

Per usarlo lo salviamo in in un file di nome: samewidth.jquery.js. e lo richiamiamo nell’HTML dopo jQuery e prima della chiusura del body:

<script src="samewidth.jquery.js"></script>

Quindi il trigger con il selettore, nel nostro caso la classe same-width:

<script>$(document).ready(function(){
 $('.same-width').getSameWidth();
});
</script>

Non ci resta che aggiornare l’html aggiungendo la classe al div, così:

<div class="organize same-width">
   <button>Get Started</button>
   <button>Download</button>
   <button>See</button>
</div>

Il risultato sarà:

Samewidth Buttons

Samewidth Buttons

I tre bottoni sono della stessa larghezza calcolata sul primo che è quello con il testo più ingombrante.

Conclusioni

Lo script in jQuery e la classe CSS si adattano a qualunque elemento si voglia organizzare nel contenitore <div>, il calcolo dinamico delle larghezze ci permette, grazie all’oggetto Math di JS, di non dover cercare una nuova misura all’inserimento di un nuovo elemento, come un nuovo bottone o una nuova sezione.

Con circa 20 righe di codice abbiamo reso i nostri bottoni nifty & responsive e automatizzato l’ottimizzazione della nostra interfaccia.
L’intero codice sorgente con una live version sono disponibili su github: