Blog

Griglia Less in Magento2

Lettura 4 minuti

Il frontend di Magento2 ha una griglia? No. O meglio, non per il frontend, l’unica cosa che ha è un mixin per “facilitare” la struttura di layout classici a 1, 2 o 3 colonne. Ecco perché nella documentazione non c’è nulla a riguardo.

Come usare il mixin per il layout

Posto che saranno molto rari i casi i cui sarà necessario usarlo, il mixin che fa la magia si trova alla riga 107 di _lib/web/css/source/lib/layout.less

.lib-layout-column(@_total-columns, @_order, @_width)

Al mixin passiamo il numero totale delle colonne che compongono il layout (da 1 a max 3 colonne), l’ordine che la singola colonna occupa all’interno della griglia e la larghezza della stessa (in pixel, rem, pt o percentuale).

Magento2 applica una soluzione ibrida, utilizzando il buon vecchio floating per strutturare il layout e flexbox per definire l’ordine.

Ma cerchiamo di capire come funziona e come farlo funzionare.

Intanto, ciò che determina l’utilizzo di flex oppure no è la variabile @use-flex settata a true (o false) alla riga 10 del file _lib/web/css/source/lib/variables/_responsive.less.

Ma non basta.

Questo mixin va utilizzato per ogni colonna all’interno del div che comprende la griglia:

.div1 {
  .lib-layout-column(3, 2, 33.333%);
}
.div2 {
  .lib-layout-column(3, 3, 33.333%);
}
.div3 {
  .lib-layout-column(3, 1, 33.333%);
}

la quale regola per singola colonna viene compilata all’incirca così:

.div1 {
  width: 33.333%;
  display: inline-block;
  -ms-flex-order: 2;
  -webkit-order: 2;
  order: 2;
}
.div2 {
  width: 33.333%;
  float: right;
  -ms-flex-order: 3;
  -webkit-order: 3;
  order: 3;
}
.div3 {
  width: 33.333%;
  float: left;
  -ms-flex-order: 1;
  -webkit-order: 1;
  order: 1;
}

che distribuirà i div in questo modo e in questo ordine

Ma se non si dichiara nel div contenitore che si tratta di una griglia flex tramite il mixin #lib-layout-columns(); questi div vengono allineati tramite float e non flex (lasciando per altro il contenitore ad altezza zero perchè non c’è un clearfix applicato) simulando l’ordine flex, motivo per il quale funziona solo con un max di tre colonne. Se invece lo si dichiara, l’ordine usato per distribuirli utilizza flex.

Vediamo come:

.lib-layout-column(@_total-columns, @_order, @_width) {
   @_units: "px","%","em","rem","pt";
   ._lib-set-column-width(length(@_units), @_width);
   .lib-flex-degradation(@_total-columns, @_order);
   & when (@use-flex = true) {
       .lib-vendor-prefix-order(@_order);
   }
}

questo è il mixin usato sopra per generare le colonne. Usa il flex-degradation sempre mentre applica l’ordine di flexbox solo nella condizione in cui sia abilitato.

Ecco cosa fa la flex-degradation:

.lib-flex-degradation(@_total-columns, @_order) when (@_order = 1) {
   float: left;
}

nel caso l’ordine del div sia 1 a prescindere dal totale delle colonne dichiarate lo flotta a sinistra.

.lib-flex-degradation(@_total-columns, @_order) when (@_order = @_total-columns) {
   float: right;
}

se l’ordine invece corrisponde al totale colonne lo flotta a sinistra. Questo fa sì che, sia che ci siano 2 sia che ci siano 3 colonne, sarà flottato a sinistra.

Ma lo sarà anche con una colonna sola :/

E con quattro? Con quattro anche lo flotta a sinistra a ma cosa succede alle colonne centrali?

.lib-flex-degradation(@_total-columns, @_order) when (@_total-columns = 3) and (@_order = 2) {
   display: inline-block;
}

l’ultimo è lui, che appunto verifica che se il totale è 3 (non 4 e non più di 4) e l’ordine è 2 lo mette in display:inline simulando così gli eventuali ordini invertiti (sempre nel caso in cui flexbox non sia supportato). Ma questo funziona appunto soltanto sul secondo elemento di 3 motivo per cui per una griglia da 4 colonne o più (quella che si vorrebbe poter usare nel listing dei prodotti per esempio) non funziona perché questa condizione non verrebbe mai eseguita.

Per cui il tentativo di fallback sui float in assenza di flex è marginalmente coperto soltanto per la costruzione di un layout di max 3 colonne, motivo per cui si chiama lib-layout-column e non .lib-grid-column.

Con flex è chiaro che funziona, ma tu te la senti di usare solo flex?

Ma quindi, che griglia usa magento sul frontend?

Nessuna.

Sul frontend nessuna.

.page-products {
   .products-grid {
       .product-item {
           width: 100%/3;
       }
   }
}

Magento_Catalog/web/css/source/module/_listings.less

Questa.

Pare che invece ci sia una griglia nell’admin che qualcuno ha suggerito di portarsi a frontend: https://magento.stackexchange.com/questions/134723/how-to-use-magento-2s-less-grid-system.

Ma a questo punto, per copiarmi tutta quella roba, sarei più propensa a crearne una piccolina ad hoc.

Lorena Ramonda