back to top

Sass: la direttiva @extend e i placeholder

La direttiva @extend di Sass permette di ereditare blocchi di dichiarazioni da regole già esistenti come mostrato nell’esempio sottostante:

/* file style.scss */
.btn {
  text-transform: uppercase;
  border-radius: 3px;
  box-shadow: 0 3px 6px rgba(0,0,0,0.18);
  padding: 8px 12px;
  border: none;
  font-size: 12px;
  width: 100px;
}

.btn--red {
  @extend .btn;
  background-color: #f74a34;
  color: #fff;
}

.btn--blue {
  @extend .btn;
  background-color: deepskyblue;
  color: #fff;
}

Abbiamo una classe base ‘btn’ e due varianti ‘btn–red’ e ‘btn–blue’. Le due classi ‘btn–blue’ e ‘btn–blue’ estendono la classe ‘btn’ ereditando il blocco di dichiarazioni in essa presenti. Nel frammento di codice sottostante è possibile osservare qual è il codice generato.

/* file style.css */
.btn, .btn--red, .btn--blue {
  text-transform: uppercase;
  border-radius: 3px;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.18);
  padding: 8px 12px;
  border: none;
  font-size: 12px;
  width: 100px;
}

.btn--red {
  background-color: #f74a34;
  color: #fff;
}

.btn--blue {
  background-color: deepskyblue;
  color: #fff;
}

Supponendo di avere un elemento in un file HTML, possiamo ora applicare una delle due classi ‘btn–red’ o ‘btn–blue’ senza dover aggiungere anche la classe ‘btn’.

<!-- index.html -->
<button class="btn--red">OK</button>

La direttiva @extend può essere molto utile per ereditare dei blocchi di dichiarazioni da regole importate da altri file. Il problema però della direttiva @import è che vengono comunque prelevate tutte le regole presenti in un file importato.

/* file style.scss */
@import "buttons";

.btn--success {
  @extend .btn--green;
}

Nel file style.scss importiamo il file _buttons.scss e creiamo una regola per la classe btn–success in cui estendiamo la classe btn–green.

/* file _buttons.scss */
.btn {
  text-transform: uppercase;
  border-radius: 3px;
  box-shadow: 0 3px 6px rgba(0,0,0,0.18);
  padding: 8px 12px;
  border: none;
  font-size: 12px;
  width: 100px;
    
  &--red {
    @extend .btn;
    background-color: #f74a34;
    color: #fff;
  }
  
  &--yellow {
    @extend .btn;
    background-color: #f7e434;
    color: #333;
  }

  &--blue {
    @extend .btn;
    background-color: deepskyblue;
    color: #fff;
  }

  &--green {
    @extend .btn;
    background-color: #00b176;
    color: #fff;
  }
}

Il risultato è mostrato sotto e come possiamo notare sono state importate tutte le regole anche quelle non necessarie.

/* file style.css */
.btn, .btn--red, .btn--yellow, .btn--blue, .btn--green, .btn--success {
  text-transform: uppercase;
  border-radius: 3px;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.18);
  padding: 8px 12px;
  border: none;
  font-size: 12px;
  width: 100px;
}

.btn--red {
  background-color: #f74a34;
  color: #fff;
}

.btn--yellow {
  background-color: #f7e434;
  color: #333;
}

.btn--blue {
  background-color: deepskyblue;
  color: #fff;
}

.btn--green, .btn--success {
  background-color: #00b176;
  color: #fff;
}

Per risolvere questo tipo di problemi possiamo usare un tipo speciale di selettore presente in Sass che prende il nome di ‘Placeholder selector’ e che viene creato anteponendo il simbolo ‘%’ a un certo nome. Si tratta di un selettore simile ai selettori di classe e id, eccetto che i simboli ‘.’ (per le classi) e ‘#’ (per gli id) vengono sostituiti da ‘%’.

/* file style.scss */
@import "buttons";

.btn--success {
  @extend %btn--green;
}

Nel file style.scss creiamo una regola per la classe btn–success che estende %btn–green (Abbiamo quindi usato un Placeholder selector). Usiamo un meccanismo simile anche nel file _buttons.scss che riportiamo sotto.

/* file _buttons.scss */
%btn {
  text-transform: uppercase;
  border-radius: 3px;
  box-shadow: 0 3px 6px rgba(0,0,0,0.18);
  padding: 8px 12px;
  border: none;
  font-size: 12px;
  width: 100px;
    
  &--red {
    @extend %btn;
    background-color: #f74a34;
    color: #fff;
  }
  
  &--yellow {
    @extend %btn;
    background-color: #f7e434;
    color: #333;
  }

  &--blue {
    @extend %btn;
    background-color: deepskyblue;
    color: #fff;
  }

  &--green {
    @extend %btn;
    background-color: #00b176;
    color: #fff;
  }
}

Il file generato è quindi quello riportato sotto in cui vengono rimosse le regole superflue.

/* file style.css */
.btn--success {
  text-transform: uppercase;
  border-radius: 3px;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.18);
  padding: 8px 12px;
  border: none;
  font-size: 12px;
  width: 100px;
}

.btn--success {
  background-color: #00b176;
  color: #fff;
}
PubblicitÃ