La creazione di CSS moderni e mantenibili per i temi WordPress comporta diverse difficoltà per gli sviluppatori. L’utilizzo di Sass (Syntactically Awesome Style Sheets) come preprocessore CSS può aiutare a organizzare, mantenere e scalare gli stili in modo più efficace.

Tuttavia, la build di un workflow Sass efficiente che si adatti in modo naturale allo sviluppo di WordPress richiede una pianificazione accurata e conoscenze tecniche.

Questa guida mostra come impostare un workflow Sass professionale per lo sviluppo di temi WordPress. Tratta di moderni strumenti di build, organizzazione intelligente dei file e prassi di distribuzione che aumentano la produttività e mantengono gli stili mantenibili.

Informazioni sull’utilizzo di Sass per lo sviluppo di WordPress

Lo sviluppo professionale di WordPress spesso si basa su strumenti e flussi di lavoro che vanno oltre le funzionalità native della piattaforma. Sass può svolgere un ruolo fondamentale nella gestione della complessità dei CSS grazie a variabili, nidificazione, mixin, importazioni e funzioni integrate.

La home page del sito web del linguaggio di programmazione Sass presenta il logo Sass in rosa, un menu di navigazione e lo slogan “CSS con i superpoteri”. Di seguito è riportato un testo descrittivo di Sass. Il design include un'illustrazione di occhiali color verde acqua e sezioni che evidenziano le funzionalità e i vantaggi di Sass.
Il sito web di Sass.

Sass offre diversi vantaggi per lo sviluppo di temi. Un tipico tema WordPress include stili per numerosi componenti e parti di template. Invece di gestire tutto in un unico e ingombrante foglio di stile, Sass offre un’architettura modulare che favorisce la manutenibilità e la scalabilità attraverso una struttura programmatica.

L’approccio strutturato di Sass va al di là di quello che offre il CSS standard e si allinea bene con le esigenze stilistiche specifiche di WordPress. A differenza dello style.css di WordPress, Sass permette di creare fogli di stile modulari e specifici per ogni scopo, vengono compilati in file CSS ottimizzati in base ad un semplice workflow:

  1. Un processo di build durante il quale compilare i file Sass in CSS.
  2. Una struttura di file per organizzare gli stili in modo gestibile nel tempo.
  3. Strumenti di sviluppo per il testing locale e il controllo qualità.
  4. Strategie di distribuzione che permettono di apportare modifiche agli ambienti di staging e di produzione.

La modalità di implementazione di questo workflow dipende dalle preferenze del team in termini di strumenti, stack tecnico e complessità del progetto. Ma la maggior parte delle configurazioni di WordPress basate su Sass segue alcune pratiche comuni: configurare le mappe dei sorgenti per il debug, controllare i file durante lo sviluppo e ottimizzare l’output per la produzione.

Una configurazione tipica separa i file sorgenti di Sass dalle risorse compilate, rendendo più facile la manutenzione della base di codice e fornendo un output pulito al browser.

3 metodi per compilare Sass nei progetti WordPress

La base di ogni workflow Sass è il processo di compilazione che trasforma i file Sass in CSS pronti per il browser. Ci sono diversi modi per implementare questo processo in WordPress.

1. Utilizzando i plugin: l’approccio semplice

Il modo più accessibile per utilizzare Sass in un tema WordPress è attraverso i plugin. Questa soluzione è ideale se si è agli inizi o se si sta lavorando a un piccolo progetto che non richiede una pipeline di build completa.

Ad esempio, WP-Sass gestisce la compilazione attraverso gli action hook nativi di WordPress all’interno di wp-config.php, monitorando la directory Sass del tema per le modifiche:

<?php

// Include the class (unless you are using the script as a plugin)
require_once( 'wp-sass/wp-sass.php' );

// enqueue a .less style sheet
if ( ! is_admin() )
    wp_enqueue_style( 'style', get_stylesheet_directory_uri() . '/style.scss' );
else
    wp_enqueue_style( 'admin', get_stylesheet_directory_uri() . '/admin.sass.php' );

// you can also use .less files as mce editor style sheets
add_editor_style( 'editor-style.sass' );

?>

Un’altra soluzione, Sassify, è un po’ datata e adotta un approccio diverso: si aggancia alle API di WordPress per gestire la compilazione di Sass, i percorsi di output e le impostazioni di compressione.

Le soluzioni basate su plugin sono semplici, ma presentano alcuni limiti:

  • Sovraccarico e calo delle prestazioni. Questi plugin compilano Sass sul server, il che può consumare molte risorse.
  • Opzioni di compilazione limitate. La maggior parte dei plugin Sass offre una compilazione di base ma manca di funzionalità essenziali. Ad esempio, spesso il supporto per le mappe di origine è limitato, mancano le funzionalità di impostazione automatica dei prefissi e altro.
  • Considerazioni sulla sicurezza. L’esecuzione di un compilatore sul server di produzione può aumentare la superficie di attacco, soprattutto se il plugin non riceve una manutenzione regolare.
  • Problemi di controllo della versione. I file CSS compilati spesso si trovano nella directory del tema, il che complica il lavoro su Git. In teoria, le risorse compilate dovrebbero rimanere fuori dal repo.

Tuttavia, nonostante questi limiti, un plugin è comunque una buona opzione in alcune situazioni. Ad esempio, per siti di piccole dimensioni con esigenze di stile minime, per affidare un progetto a un cliente che non ha le competenze tecniche per lavorare con Sass a un livello più avanzato o per lavorare con vincoli di risorse per lo sviluppo.

2. Utilizzo di script NPM: La soluzione equilibrata

Per chi desidera maggiore controllo e flessibilità, gli script NPM possono essere una valida alternativa ai plugin. La compilazione di Sass è un lavoro ideale per NPM, in quanto si raggiunge un equilibrio tra semplicità e capacità. Offre miglioramenti sostanziali rispetto ai plugin per lo sviluppo di temi senza la complessità di task runner completi:

  • Mantenendo la compilazione separata dall’esecuzione di WordPress, si elimina l’overhead delle prestazioni del server.
  • Si ha un controllo preciso su ogni fase del processo di compilazione.
  • Il file package.json assicura che tutti i membri del team utilizzino lo stesso processo di build.
  • Gli script npm si integrano perfettamente con le pipeline CI/CD.

Sebbene questo approccio renda necessaria una più attenta configurazione iniziale rispetto ai plugin, offre una soluzione più solida e scalabile per lo sviluppo di temi professionali.

Configurazione della compilazione di Sass con NPM

Iniziamo creando un file package.json. Possiamo farlo eseguendo:

npm init -y

Poi installiamo Dart Sass:

npm install sass --save-dev

Successivamente, aggiungiamo questi script al package.json:

{
  "name": "your-theme-name",
  "version": "1.0.0",
  "description": "A WordPress theme with Sass",
  "scripts": {
    "sass": "sass src/sass/main.scss:assets/css/main.css",
    "sass:watch": "sass --watch src/sass/main.scss:assets/css/main.css",
    "build": "sass src/sass/main.scss:assets/css/main.css --style=compressed"
  },
  "devDependencies": {
    "sass": "^1.58.3"
  }
}

Questa configurazione fornisce tre utili script:

  • npm run sass compila i file Sass una volta sola.
  • sass:watch controlla le modifiche e ricompila se necessario.
  • build compila i file Sass per la produzione con compressione.

Per supportare i browser più vecchi, aggiungiamo l’Autoprefixer tramite PostCSS:

npm install postcss postcss-cli autoprefixer --save-dev

Aggiorniamo gli script di package.json:

{
  "scripts": {
    "sass": "sass src/sass/main.scss:assets/css/main.css",
    "prefix": "postcss assets/css/main.css --use autoprefixer -o assets/css/main.css",
    "build": "npm run sass && npm run prefix"
  },
  "devDependencies": {
    "autoprefixer": "^10.4.13",
    "postcss": "^8.4.21",
    "postcss-cli": "^10.1.0",
    "sass": "^1.58.3"
  },
  "browserslist": [
    "last 2 versions",
    "> 1%"
  ]
}

Per facilitare il debug, aggiungi le mappe dei sorgenti:

{
  "scripts": {
    "sass": "sass src/sass/main.scss:assets/css/main.css --source-map",
    "sass:watch": "sass --watch src/sass/main.scss:assets/css/main.css --source-map"
  }
}

Infine, per utilizzare il CSS compilato in WordPress, inseriamo nel file functions.php il CSS compilato:

function theme_enqueue_styles() {
    $style_path = '/assets/css/main.css';
    $full_path = get_template_directory() . $style_path;
    
    wp_enqueue_style(
        'theme-styles',
        get_template_directory_uri() . $style_path,
        array(),
        file_exists($full_path) ? filemtime($full_path) : false
    );
}
add_action('wp_enqueue_scripts', 'theme_enqueue_styles');

Questa funzione carica il CSS compilato e aggiunge la funzione di cache busting automatico utilizzando l’ora di modifica del file come numero di versione.

3. Utilizzare Gulp: La soluzione completa

Gulp è un potente task runner, ottimo nell’automaxione di processi di build complessi. Per lo sviluppo di temi WordPress con estese esigenze di stile, può essere la soluzione più completa.
Permette di gestire la compilazione di Sass, la sincronizzazione del browser e tutto il resto. Perché Gulp?

  • Gulp gestisce quasi tutti gli aspetti del processo di build, come la compilazione, l’ottimizzazione e la distribuzione.
  • Permette di eseguire più attività contemporaneamente, riducendo così i tempi di build.
  • L’ecosistema offre strumenti per qualsiasi esigenza di build.
  • L’integrazione con BrowserSync offre un feedback immediato durante lo sviluppo.

Sebbene Gulp abbia una curva di apprendimento più ripida rispetto ad altre soluzioni, i vantaggi che offre lo fanno preferire a molti.

Configurare Gulp per i temi WordPress

Per iniziare, è necessario installare Gulp insieme a diversi plugin che gestiscono task specifici:

# Initialize your project
npm init -y

# Install Gulp and related packages
npm install --save-dev gulp gulp-sass sass gulp-autoprefixer gulp-sourcemaps browser-sync gulp-cssnano

Bisognerebbe anche creare un gulpfile.js nella directory principale del tema. QUesto file gestisce diversi passaggi. Questa prima parte permette di importare tutti gli strumenti necessari:

// 1. Import dependencies
const { src, dest, watch, series, parallel } = require('gulp');
const sass = require('gulp-sass')(require('sass'));
const autoprefixer = require('gulp-autoprefixer');
const sourcemaps = require('gulp-sourcemaps');
const browserSync = require('browser-sync').create();
const cssnano = require('gulp-cssnano');

Ogni pacchetto ha uno scopo specifico:

  • gulp: il task runner principale.
  • gulp-sass e sass: compila Sass in CSS.
  • gulp-autoprefixer: aggiunge i prefissi dei provider per la compatibilità con i browser.
  • gulp-sourcemaps: genera mappe sorgenti per il debug.
  • browser-sync: aggiorna i browser durante lo sviluppo.
  • gulp-cssnano: inifica il CSS per la produzione.

Da qui si possono definire i percorsi dei file di origine e di destinazione e creare una funzione per compilare Sass:

// 2. Define file paths
const files = {
  sassPath: './src/sass/**/*.scss',
  cssPath: './assets/css/'
}

// 3. Sass development task with sourcemaps
function scssTask() {
  return src(files.sassPath)
    .pipe(sourcemaps.init())
    .pipe(sass().on('error', sass.logError))
    .pipe(autoprefixer())
    .pipe(sourcemaps.write('./'))
    .pipe(dest(files.cssPath))
    .pipe(browserSync.stream());
}

Questa funzione essenzialmente trova tutti i file Sass, inizializza le sourcemap per il debug e compila Sass in CSS (con gestione degli errori). Aggiunge inoltre i prefissi dei provider per la compatibilità con i browser, scrive le sourcemap, salva il CSS compilato e aggiorna il browser con le modifiche. Nel complesso, fa un sacco di lavoro!

Bisogna anche pensare a creare una funzione di compilazione pronta per la produzione, un task watcher e una funzione di esportazione:

// 4. Sass production task with minification
function scssBuildTask() {
  return src(files.sassPath)
    .pipe(sass().on('error', sass.logError))
    .pipe(autoprefixer())
    .pipe(cssnano())
    .pipe(dest(files.cssPath));
}

// 5. Watch task for development
function watchTask() {
  browserSync.init({
    proxy: 'localhost:8888' // Change this to match your local development URL
  });
  
  watch(files.sassPath, scssTask);
  watch('./**/*.php').on('change', browserSync.reload);
}

// 6. Export tasks
exports.default = series(scssTask, watchTask);
exports.build = scssBuildTask;

Questa versione di produzione omette le sourcemap e aggiunge la minificazione per ottimizzare le dimensioni dei file. Nel complesso, la configurazione permette di eseguire npx gulp per lo sviluppo (con l’osservazione dei file e l’aggiornamento del browser) e npx gulp build per le build di produzione.

Migliorare il workflow di Gulp

Per i progetti più grandi, potremmo separare gli stili per scopi diversi. Ecco un esempio:

// Define paths for different style types
const paths = {
  scss: {
    src: './src/sass/**/*.scss',
    dest: './assets/css/'
  },
  editorScss: {
    src: './src/sass/editor/**/*.scss',
    dest: './assets/css/'
  }
}

// Main styles task
function mainStyles() {
  return src('./src/sass/main.scss')
    .pipe(sourcemaps.init())
    .pipe(sass().on('error', sass.logError))
    .pipe(autoprefixer())
    .pipe(sourcemaps.write('./'))
    .pipe(dest(paths.scss.dest))
    .pipe(browserSync.stream());
}

// Editor styles task
function editorStyles() {
  return src('./src/sass/editor-style.scss')
    .pipe(sourcemaps.init())
    .pipe(sass().on('error', sass.logError))
    .pipe(autoprefixer())
    .pipe(sourcemaps.write('./'))
    .pipe(dest(paths.scss.dest))
    .pipe(browserSync.stream());
}

Nel caso di temi complessi con molti file Sass, bisognerebbe anche ottimizzare le prestazioni di compilazione mettendo nella cache i file elaborati per evitare una ricompilazione non necessaria, tracciando le dipendenze Sass per ricompilare solo i file interessati e altro ancora. Tuttavia, questo esula dallo scopo di questo post.

Altri strumenti di build da prendere in considerazione

Anche se la maggior parte degli sviluppatori si affida agli script NPM o a Gulp, si possono trovare valide alternative che offrono vantaggi specifici per lo sviluppo di temi WordPress. Vite e Webpack sono due soluzioni molto utilizzate.

Webpack eccelle nel raggruppare JavaScript e risorse, il che è ideale se il tema ha un’architettura basata su componenti o framework JavaScript. Il suo punto di forza è la capacità di creare bundle ottimizzati attraverso la suddivisione del codice e il “tree shaking” (scuotimento dell’albero), utile per temi complessi e ricchi di JavaScript.

Vite è uno strumento di compilazione più recente che privilegia la velocità dello sviluppo grazie ad un approccio innovativo al caricamento dei moduli. Il suo server di sviluppo offre una sostituzione quasi istantanea dei moduli. Si tratta di una soluzione veloce per implementare lo sviluppo iterativo. Anche se la sua integrazione con i workflow di WordPress continua ad evolvere, è una soluzione interessante se si può sfruttarla per lo sviluppo dei temi.

Per progetti più semplici o per preferenze personali, la CLI di Sass ha un approccio diretto senza strumenti aggiuntivi:

# Install Sass globally
npm install -g sass

# Compile Sass files
sass --watch src/sass/main.scss:assets/css/main.css

Sebbene la build manuale non abbia le caratteristiche di automazione e integrazione degli strumenti di compilazione dedicati, ha il vantaggio della semplicità. Questo approccio funziona bene per temi semplici con esigenze di stile immediate, prototipi veloci o progetti di piccole dimensioni. Potrebbe anche essere adatto a chi preferisce strumenti minimalisti.

Come strutturare e organizzare un progetto di sviluppo WordPress con Sass

Al di là del processo di build, organizzare correttamente i file Sass è essenziale per la manutenibilità e la collaborazione. Una struttura ben pianificata permette di navigare più facilmente nel codice, oltre che aggiornare e scalare con la crescita del tema.

Il modello 7-1: Organizzazione modulare per temi complessi

Lo schema 7-1 è una prassi tipica per organizzare i file Sass in progetti di grandi dimensioni. Divide il codice dello stile in sette cartelle tematiche più un file principale (main.scss) che importa tutto.

Questo schema crea una separazione logica che permette di trovare e aggiornare stili specifici in modo semplice e rapido. Ecco una panoramica della struttura:

  • Abstracts. Contiene gli helper che non producono direttamente CSS, le variabili per i colori, la tipografia e la spaziatura, le funzioni per i calcoli e la logica, i mixin per i modelli di stile riutilizzabili e i segnaposto per gli stili estendibili.
  • Base. Include gli stili fondamentali e predefiniti, le regole tipografiche, le classi di utilità e i selettori di elementi (senza classi). Permette anche di reimpostare o normalizzare i CSS.
  • Componenti. Contiene componenti dell’interfaccia utente riutilizzabili come pulsanti, moduli e schede, menu di navigazione, widget, barre laterali e formati multimediali (come immagini e video).
  • Layout. Qui si definiscono gli elementi strutturali, come l’intestazione e il footer, i sistemi a griglia, le strutture dei container e la disposizione delle barre laterali.
  • Pagine. Contiene gli stili specifici delle pagine, le specializzazioni della home page, i layout dei singoli post, le varianti delle pagine di archivio e le landing page speciali.
  • Temi. In questa sezione sono presenti diversi temi o modalità visive. Qui si trovano i temi chiari e scuri, le variazioni stagionali, le personalizzazioni dell’area amministrativa e i temi specifici del brand.
  • Vendor. L’ultima sezione è quella in cui vengono archiviati gli stili di terze parti, gli override dei plugin, le personalizzazioni del framework e lo stile dei componenti esterni.

Il file principale (in genere main.scss) importa tutti i componenti parziali in un ordine specifico:

// Abstracts
@import 'abstracts/variables';
@import 'abstracts/mixins';
// Vendors (early to allow overriding)
@import 'vendors/normalize';
// Base styles
@import 'base/reset';
@import 'base/typography';
// Layout
@import 'layouts/header';
@import 'layouts/grid';
// Components
@import 'components/buttons';
@import 'components/forms';
// Page-specific styles
@import 'pages/home';
@import 'pages/blog';
// Themes
@import 'themes/admin';

Questo approccio modulare permette di evitare la “zuppa di CSS” che spesso affligge i progetti più grandi. È un sistema manutenibile che si adatta alla complessità del tema.

Struttura incentrata sui blocchi: Organizzazione moderna per l’editor a blocchi e l’editor del sito

Se il tema è incentrato sull’editor a blocchi, una struttura che dia priorità a questi componenti ha spesso più senso. In questo modo è possibile allineare l’organizzazione di Sass con il modello di contenuti basato sui blocchi di WordPress.

La struttura è più semplice rispetto al modello 7-1:

  • Core. Qui si trovano gli stili e le configurazioni di base, come le variabili, i mixin, gli helper, lo stile degli elementi di base e i blocchi principali di WordPress.
  • Blocchi. Qui si trovano le varianti personalizzate dei blocchi, gli stili estesi dei blocchi principali e gli stili dei block pattern.
  • Template. Qui aggiungeremo i template di post singoli, i template di archivio e i template di pagina personalizzati.
  • Utilità. Si tratta di classi e strumenti di aiuto come le utilità di spaziatura, le classi della tipografia e le utilità di colore o sfondo.

Questa struttura supporta la natura modulare dello sviluppo con i blocchi e permette di mantenere la coerenza tra le varianti e i template.

Considerazioni specifiche per WordPress sull’organizzazione di Sass

Nell’organizzazione di Sass per i temi WordPress, meritano attenzione alcune considerazioni specifiche per la piattaforma. La gerarchia dei template di WordPress stabilisce quali file PHP utilizzare per i diversi tipi di contenuto.

Rispecchiare questa gerarchia nell’organizzazione di Sass crea connessioni intuitive tra i template PHP e gli stili associati. Per questo motivo, bisognerebbe prendere in considerazione l’idea di organizzare gli stili specifici delle pagine in modo che corrispondano alla struttura dei template di WordPress:

// _archive.scss
.archive {
  // Base archive styles
  
  &.category {
    // Category archive styles
  }
    
  &.tag {
    // Tag archive styles
  }
    
  &.author {
    // Author archive styles
  }
}

In questo modo è immediatamente chiaro quali stili si applicano a specifici template e permette di gestire e aggiornare il sito in modo più semplice.

Organizzazione della compatibilità dei plugin

I plugin spesso introducono i propri stili e il tema potrebbe doverli sovrascrivere. Invece di distribuire sovrascritture nei file, dovremmo pensare di isolarle:

Ad esempio, l’integrazione di WooCommerce potrebbe assumere una delle seguenti strutture:

vendors/woocommerce/
├── _general.scss          // Base WooCommerce styles
├── _buttons.scss          // WooCommerce button styles
├── _forms.scss            // WooCommerce form styles
├── _shop.scss             // Shop page styles
└── _single-product.scss   // Single product page styles

Questa organizzazione permette di aggiornare gli stili di compatibilità dei plugin quando il plugin viene aggiornato, mantiene la separazione tra gli stili del tema e quelli del plugin e permette di trovare rapidamente gli stili specifici dei plugin.

Inoltre, è consigliato sempre nel namespace le sovrascritture per evitare conflitti tra stili:

// _woocommerce.scss
.woocommerce {
  .products {
    // Custom product grid styles
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 2rem;
  }
    
  .single-product {
    // Single product page styles
    .price {
      font-size: 1.5rem;
      color: $price-color;
    }
  }
}

Questo approccio evita che gli stili dei plugin si infiltrino nel design core del tema, fornendo al contempo dei chiari override laddove servono.

Stile dell’editor e del pannello di amministrazione

Spesso si ha bisogno di creare uno stile sia per il front-end che per l’interfaccia dell’editor a blocchi. Per questo, possiamo creare una struttura dedicata agli stili specifici per il pannello di amministrazione:

admin/
├── _editor.scss         // Block editor styles
├── _login.scss          // Login page customization
└── _dashboard.scss      // Dashboard customizations

Per il supporto dell’editor a blocchi, va compilato un foglio di stile separato e si esegue l’enqueue in questo modo:

function theme_editor_styles() {
  add_theme_support('editor-styles');
  add_editor_style('assets/css/editor.css');
}
add_action('after_setup_theme', 'theme_editor_styles');

In questo modo il contesto dell’editor rimane pulito, coerente e visivamente allineato con il front-end.

Implementazione del responsive design

I temi WordPress devono funzionare su dispositivi di diverse dimensioni, quindi è necessario seguire un approccio sistematico al design reattivo. In questo caso l’uso dei mixin di Sass può creare un sistema coerente e gestibile nel tempo:

// Breakpoint mixin
@mixin respond-to($breakpoint) {
  @if $breakpoint == "sm" {
    @media (min-width: 576px) { @content; }
  }
  @else if $breakpoint == "md" {
    @media (min-width: 768px) { @content; }
  }
  @else if $breakpoint == "lg" {
    @media (min-width: 992px) { @content; }
  }
}

Mantenendo la reattività degli stili contestualmente alle definizioni di base, si crea una base di codice più gestibile che mostra chiaramente come i componenti si adattano ai vari breakpoint.

Configurare un ambiente di sviluppo locale

Lo sviluppo locale è fondamentale quando si lavora con WordPress e diventa ancora più importante quando si utilizzano strumenti come Sass. La corretta configurazione dell’ambiente di sviluppo locale permette una rapida iterazione, offre un feedback in tempo reale e una connessione perfetta tra il processo di build di Sass e il sito WordPress.

DevKinsta è un ottimo strumento per creare un ambiente di sviluppo locale personalizzabile in base alle proprie esigenze e l’installazione e la configurazione sono semplici.

Un'illustrazione digitale stilizzata nei toni del blu che raffigura delle mani intente a utilizzare un computer. Una mano sta digitando su una tastiera mentre l'altra indica il monitor del computer che mostra una lettera
Il logo di DevKinsta.

Utilizzare Gulp per configurare la compilazione di Sass all’interno della directory del tema è la soluzione più semplice. Per prima cosa, apriamo la cartella del tema, poi inizializziamo NPM e installiamo le dipendenze come abbiamo spiegato in precedenza.

Quindi creiamo un file gulpfile.js con BrowserSync configurato per il sito DevKinsta:

const { src, dest, watch, series } = require('gulp');
const sass = require('gulp-sass')(require('sass'));
const autoprefixer = require('gulp-autoprefixer');
const sourcemaps = require('gulp-sourcemaps');
const browserSync = require('browser-sync').create();

// Get your DevKinsta site URL from the dashboard
const siteURL = 'your-site-name.local';

function scssTask() {
  return src('./src/sass/**/*.scss')
    .pipe(sourcemaps.init())
    .pipe(sass().on('error', sass.logError))
    .pipe(autoprefixer())
    .pipe(sourcemaps.write('./'))
    .pipe(dest('./assets/css/'))
    .pipe(browserSync.stream());
}

function watchTask() {
  browserSync.init({
    proxy: siteURL,
    notify: false
  });
  
  watch('./src/sass/**/*.scss', scssTask);
  watch('./**/*.php').on('change', browserSync.reload);
}

exports.default = series(scssTask, watchTask);

Quindi impostiamo la struttura dei file:

mkdir -p src/sass/{abstracts,base,components,layouts,pages,themes,vendors}
touch src/sass/main.scss

Ora siamo pronti per eseguire npx gulp. Ogni volta che un file Sass o PHP viene modificato, gli stili verranno compilati, iniettati nel browser e se necessario aggiornati.

Dallo sviluppo alla produzione

Una volta sviluppato il tema in locale, abbiamo bisogno di una strategia affidabile per distribuirlo negli ambienti di staging e di produzione.

Con Kinsta questo passaggio è molto semplice, grazie agli ambienti di staging integrati che si sincronizzano direttamente con DevKinsta. Con pochi clic, è possibile trasferire il tema dall’ambiente locale a quello di staging:

L'interfaccia di MyKinsta mostra in alto i pulsanti Push environment (Invia all'ambiente), Open WP Admin (Apri WP Admin) e Visit site (Visita il sito). Sotto c'è una sezione beige con il testo Push to Live (Invia in produzione) e un pulsante verde a forma di pillola con l'etichetta Live. L'interfaccia mostra anche una sezione dedicata agli aggiornamenti.
L’opzione del menu a discesa Push to Live nella dashboard di MyKinsta.

In questo modo i file sorgente CSS e Sass compilati vengono trasferiti in modo sicuro allo staging. I team con esigenze di distribuzione più avanzate possono automatizzare le distribuzioni di staging con Gulp. Ecco un esempio:

const { src, parallel, series } = require('gulp');
const rsync = require('gulp-rsync');

// Clean and build tasks defined earlier

// Deployment task
function deployToStaging() {
  return src('dist/**')
    .pipe(rsync({
      root: 'dist/',
      hostname: 'your-kinsta-sftp-host',
      destination: 'public/wp-content/themes/your-theme/',
      archive: true,
      silent: false,
      compress: true
    }));
}

// Export the deployment task
exports.deploy = series(
  parallel(cleanStyles, cleanScripts),
  parallel(styles, scripts),
  deployToStaging
);

Dopo il deploy in staging, bisogna comunque effettuare dei test approfonditi per assicurarsi che il CSS compilato con Sass funzioni correttamente:

  1. Test visivo. In questo caso, bisogna verificare che tutti gli stili vengano applicati come previsto nelle diverse pagine.
  2. Test reattivo. Verifica che tutti i breakpoint funzionino correttamente.
  3. Test delle prestazioni. Google PageSpeed Insights, Lighthouse e altri strumenti permettono di verificare il caricamento del CSS.
  4. Verifica cross-browser. Bisogna ricordarsi di eseguire i test su diversi browser per individuare eventuali problemi di compatibilità.

Durante i test, va prestata particolare attenzione ai percorsi, alle impostazioni della cache e ai permessi sui file, perché causano spesso problemi di distribuzione. Poi possiamo distribuire il tema in produzione. Il push selettivo di Kinsta permette di distribuire con facilità, mantenendo il controllo su ciò che viene distribuito.

La finestra di dialogo Push to Live che appare quando si esegue il deployment da un ambiente di staging all'interno di MyKinsta. La finestra modale mostra le opzioni relative a ciò che si desidera trasferire dallo staging alla produzione, con caselle di controllo per File, Database ed esecuzione di una ricerca e sostituzione. Un menu a tendina mostra che è selezionato Tutti i file e le cartelle, e c'è una nota che indica che MyKinsta creerà un backup automatico dell'ambiente live.
La funzionalità di push selettivo di Kinsta.

Anche in questo caso bisogna assicurarsi che il CSS venga ottimizzato correttamente prima di distribuirlo. Ci sono diversi modi per farlo, come la minificazione, l’organizzazione dei file e il cache busting.

Creare integrazioni efficaci con il Block Editor

Oggi, lo sviluppo di WordPress è incentrato sull’editor a blocchi e un buon stile assicura la coerenza tra l’editing e il front-end.

Ad esempio, invece di organizzare gli stili in base ai template di pagina, possiamo considerare un’organizzazione centrata sui blocchi. Possiamo iniziare creando partial Sass dedicati per ogni tipo di blocco:

blocks/
├── _paragraph.scss      // Paragraph block styles
├── _heading.scss        // Heading block styles
├── _image.scss          // Image block styles
├── _gallery.scss        // Gallery block styles
└── _custom-block.scss   // Custom block styles

In questo modo è più facile mantenere gli stili man mano che procede lo sviluppo del core di WordPress e la libreria di blocchi del tema cresce. Gli stili di ogni blocco possono essere contenuti in modo ordinato e aggiornati in modo indipendente.

All’interno dei file di ogni blocco, cerchiamo di stabilire delle chiare convenzioni di denominazione in linea con le classi dei blocchi di WordPress:

// _paragraph.scss
.wp-block-paragraph {
  // Base paragraph block styles
  font-family: $body-font;
  line-height: 1.6;
  
  // Block variations
  &.is-style-lead {
    font-size: 1.2em;
    font-weight: 300;
  }
  
  &.has-background {
    padding: 1.5rem;
  }
}

Questo approccio crea una relazione diretta tra i controlli dell’editor dei blocchi e gli stili risultanti, rendendo il tema più gestibile.

Per mantenere l’esperienza di editing sincronizzata con il front-end, compiliamo fogli di stile separati e condividiamo le variabili tra i diversi fogli di stile:

// In your gulpfile.js
function themeStyles() {
  return src('./src/sass/main.scss')
    .pipe(sass().on('error', sass.logError))
    .pipe(autoprefixer())
    .pipe(dest('./assets/css/'));
}

function editorStyles() {
  return src('./src/sass/editor.scss')
    .pipe(sass().on('error', sass.logError))
    .pipe(autoprefixer())
    .pipe(dest('./assets/css/'));
}

Richiediamo questi stili dell’editor specificamente per il contesto dell’editor a blocchi:

function theme_editor_styles() {
  add_theme_support('editor-styles');
  add_editor_style('assets/css/editor.css');
}
add_action('after_setup_theme', 'theme_editor_styles');

Per mantenere la coerenza visiva, possiamo utilizzare variabili e mixin condivisi in entrambi i fogli di stile:

// abstracts/_variables.scss
$primary-color: #0073aa;
$secondary-color: #23282d;
$heading-font: 'Helvetica Neue', Helvetica, Arial, sans-serif;
$body-font: 'Georgia', serif;
// Import in both main.scss and editor.scss

Questo approccio fa in modo che i colori, la tipografia e la spaziatura rimangano coerenti tra l’esperienza di modifica e quella di visualizzazione.

Integrazione con theme.json

I temi a blocchi definiscono le impostazioni globali che riguardano sia l’editor che il front-end nel file theme.json. Allineando le variabili Sass con le impostazioni del theme.json possiamo creare un sistema coeso. Ad esempio:

{
  "version": 2,
  "settings": {
    "color": {
      "palette": [
        {
          "name": "Primary",
          "slug": "primary",
          "color": "#0073aa"
        }
      ]
    }
  }
}

Possiamo inserire queste variabili nei file Sass:

// Match theme.json values
$color-primary: #0073aa;

// Generate matching custom properties
:root {
  --wp--preset--color--primary: #{$color-primary};
}

Questa semplice sincronizzazione farà sì che gli stili personalizzati siano in armonia con i controlli integrati e il sistema di stili globali dell’editor dei blocchi.

Ottimizzazione delle prestazioni con Sass

L’ottimizzazione delle prestazioni è un aspetto fondamentale per chi sviluppa temi WordPress professionali. Oltre alla compilazione di base, i workflow Sass possono introdurre diverse altre tecniche per migliorare la velocità di caricamento e l’esperienza utente (UX).

Implementare i CSS critici per aumentare la velocità di caricamento

L’ottimizzazione del CSS critico è una tecnica che estrae e inserisce in linea il CSS minimo di cui il sito ha bisogno per rendere il contenuto “above the fold”. I percorsi di rendering critici in generale sono importanti quando si sviluppa per WordPress; l’ottimizzazione dei CSS critici può ridurre i tempi di caricamento percepiti grazie alla riduzione dei CSS che bloccano il rendering.

Scrivere CSS critici è un’abilità di per sé – l’aggiunta di Sass aumenterà la difficoltà. Iniziamo creando un file Sass separato specifico per gli stili critici e configuriamo il processo di build in modo da compilare questo file separatamente:

// critical.scss - Only include styles for above-the-fold content
@import 'abstracts/variables';
@import 'abstracts/mixins';

// Only essential styles
@import 'base/reset';
@import 'layouts/header';
@import 'components/navigation';

function criticalStyles() {
  return src('./src/sass/critical.scss')
    .pipe(sass().on('error', sass.logError))
    .pipe(autoprefixer())
    .pipe(cssnano())
    .pipe(dest('./assets/css/'));
}

Per implementare questo CSS critico nel tema, dobbiamo semplicemente inserirlo in linea nei tag head mentre carichiamo in modo asincrono il CSS di riempimento:

function add_critical_css() {
  $critical_css = file_get_contents(get_template_directory() . 
    '/assets/css/critical.css');
  echo '' . $critical_css . '';
  
  // Async load full CSS
  echo '';
}
add_action('wp_head', 'add_critical_css', 1);

Questa tecnica consente di visualizzare il contenuto più rapidamente mentre il resto degli stili viene caricato in background. Tuttavia, non tutte le pagine hanno bisogno di tutti gli stili del tema. Caricando in base al template o al tipo di contenuto corrente possiamo aumentare ulteriormente le prestazioni.

Possiamo farlo caricando il CSS specifico del template all’interno del file functions.php del tema:

function load_template_specific_css() {
  // Base styles for all pages
  wp_enqueue_style('main-styles', 
    get_template_directory_uri() . '/assets/css/main.css');
    
  // Product page specific styles
  if (is_singular('product')) {
    wp_enqueue_style('product-styles', 
      get_template_directory_uri() . '/assets/css/product.css');
  } 
  // Archive page specific styles
  elseif (is_archive()) {
    wp_enqueue_style('archive-styles', 
      get_template_directory_uri() . '/assets/css/archive.css');
  }
}
add_action('wp_enqueue_scripts', 'load_template_specific_css');

Questo approccio riduce il carico di CSS di ogni pagina, riduce i tempi di caricamento e mantiene alta la qualità del design.

Implementare un controllo intelligente della cache

La gestione della cache ha sempre dei vantaggi per l’utente finale, che ottiene gli stili più recenti e sfrutta la cache per le risorse invariate. Tramite Sass, è possibile controllare automaticamente la cache all’interno dell’interrogazione degli stili del tema:

function enqueue_styles_with_cache_busting() {
  $css_file = get_template_directory() . '/assets/css/main.css';
  $version = filemtime($css_file);
  
  wp_enqueue_style('main-styles', 
    get_template_directory_uri() . '/assets/css/main.css', 
    array(), $version);
}
add_action('wp_enqueue_scripts', 'enqueue_styles_with_cache_busting');

L’ora di modifica del file viene utilizzata come numero di versione, il che garantisce che i browser mettano in cache il CSS solo fino a quando non viene modificato, per poi scaricare automaticamente la versione aggiornata.

Gestire le mappe sorgente in modo sicuro

Le mappe sorgente sono preziose durante lo sviluppo, ma possono esporre il codice sorgente Sass in produzione. In questo caso potrebbe essere utile implementare una gestione delle mappe sorgente specifica per l’ambiente:

// In your gulpfile.js
const isProduction = process.env.NODE_ENV === 'production';

function styles() {
  return src('./src/sass/main.scss')
    .pipe(gulpif(!isProduction, sourcemaps.init()))
    .pipe(sass().on('error', sass.logError))
    .pipe(autoprefixer())
    .pipe(gulpif(!isProduction, sourcemaps.write('./')))
    .pipe(dest('./assets/css/'));
}

Per un debug controllato in produzione, potremmo fornire le mappe sorgenti solo agli amministratori:

function conditional_source_maps() {
  // Only for administrators with debug parameter
  if (current_user_can('manage_options') && isset($_GET['debug_css'])) {
    wp_enqueue_style('debug-maps', 
      get_template_directory_uri() . '/assets/css/main.css.map');
  }
}
add_action('wp_enqueue_scripts', 'conditional_source_maps', 999);

In questo modo si mantengono i vantaggi delle mappe sorgenti per il debugging e si protegge il codice sorgente da un’esposizione non necessaria: un grande vantaggio per tutti.

Creare workflow di team efficaci

Flussi di lavoro e standard coerenti sono essenziali per qualsiasi team che lavori su temi WordPress con Sass. Per quanto riguarda i flussi di lavoro specifici di Sass, bisognerebbe cercare di stabilire standard chiari in alcune aree principali.

Ad esempio, cerchiamo di definire convenzioni di denominazione e pattern coerenti per variabili, mixin e classi:

// Variables: use kebab-case with descriptive prefixes
$color-primary: #0073aa;
$font-heading: 'Helvetica Neue', sans-serif;
$spacing-base: 1rem;

// Mixins: verb-based naming
@mixin create-gradient($start, $end) {
  background: linear-gradient(to bottom, $start, $end);
}

// Classes: BEM convention
.card {
  &__header { /* header styles */ }
  &__body { /* body styles */ }
  &--featured { /* featured variant */ }
}

È una buona idea anche standardizzare il modo in cui i nuovi file entrano a far parte del progetto. Ecco alcuni esempi di standard che potremmo implementare:

  • I nuovi componenti vengono inseriti nella directory components.
  • Ogni componente avrà un proprio file.
  • Tutti i file useranno lo stesso ordine di importazione.
  • I parziali inizieranno sempre con un trattino basso.

Definiamo anche i requisiti per i commenti al codice e la documentazione. Possiamo “codificare” questi standard in un file di configurazione .stylelintrc per automatizzarne l’applicazione:

{
  "extends": "stylelint-config-standard-scss",
  "rules": {
    "indentation": 2,
    "selector-class-pattern": "^[a-z][a-z0-9-]*$",
    "max-nesting-depth": 3,
    "selector-max-compound-selectors": 4
  }
}

Le revisioni del codice sono importanti per Sass perché piccole modifiche possono avere effetti di vasta portata sull’aspetto del tema. I processi di revisione dovrebbero riguardare in modo specifico lo stile:

  • Conformità alla guida di stile. Assicuriamoci che i nuovi stili siano conformi all’attuale sistema di design del progetto.
  • Considerazioni sulle prestazioni. Esaminiamo tutti gli output CSS per individuare eventuali opportunità di ottimizzazione.
  • Compatibilità cross-browser. Verifichiamo che gli stili creati funzionino su tutti i browser richiesti.

Naturalmente, bisognerebbe includere questi aspetti specifici di Sass nelle checklist di revisione del codice del team per mantenere standard elevati in tutta la code base.

Strategie di controllo della versione per progetti Sass

Ci sono diverse considerazioni specifiche per Sass nell’ambito del controllo di versione che meritano la nostra attenzione. Una decisione importante riguarda il commit del CSS compilato. Ci sono due scuole di pensiero su questo punto:

  • Non eseguire il commit del CSS mantiene pulita la repo ma richiede passaggi di compilazione durante la distribuzione.
  • Il commit del CSS aumenterà le dimensioni della repo, ma garantirà anche che i file che distribuiamo corrispondano esattamente a quelli che abbiamo testato.

Se decidiamo di non fare il commit dei file compilati, dovremo assicurarci che questi ricevano la giusta esclusione all’interno del file .gitignore:

# .gitignore
.sass-cache/
*.css.map
*.scss.map
node_modules/
/assets/css/

Infine, esaminiamo la struttura dei branch per il lavoro sullo stile e pensiamo come gestire le modifiche allo stile per i nuovi componenti (come i branch delle funzionalità), le variazioni visive (che potrebbero utilizzare i branch dei temi) e i principali aggiornamenti del design (magari utilizzando branch specifici per lo stile).

Riepilogo

Un moderno workflow Sass può trasformare lo sviluppo di un tema WordPress da una sfida a un processo strutturato e gestibile nel tempo.

Tra gli elementi principali di un workflow Sass efficace ci sono un processo di build semplice ma capace, un’organizzazione accurata dei file, ottimizzazione delle prestazioni e solidi flussi di lavoro di gruppo. Con l’evoluzione del Block Editor, un’implementazione flessibile e solida di Sass permette di adattarsi e di ottenere risultati elevati.

E se cerchi un hosting WordPress che supporti questo tipo di workflow – dall’accesso SSH e WP-CLI agli ambienti di staging ad un solo clic, Kinsta offre una piattaforma facile da usare per gli sviluppatori, sviluppata per supportare gli strumenti più moderni.

Jeremy Holcombe Kinsta

Content & Marketing Editor presso Kinsta, web developer di WordPress e content writer. Al di fuori di tutto ciò che riguarda WordPress, mi piacciono la spiaggia, il golf e il cinema. Ho anche i problemi di tutte le persone più alte della media ;).