Lo styling permette di definire l’aspetto di un sito web e di creare un branding elegante e coeso. Sebbene molti approcci utilizzino i fogli di stile a cascata (CSS) per creare lo stile delle pagine web, le soluzioni basate su JavaScript sono più flessibili e offrono un maggiore controllo rispetto ai CSS standard.

Un metodo molto diffuso è quello di utilizzare i fogli di stile JavaScript (JSS), che permette di scrivere gli stili CSS in JavaScript. JSS presenta diversi vantaggi, tra cui l’utilizzo di variabili, espressioni JavaScript e funzioni per creare stili e temi dinamici.

Questo articolo spiega come funziona JSS, i suoi vantaggi e come utilizzarlo nelle applicazioni JavaScript. Inoltre parla di stile dinamico, tematizzazione e ottimizzazione delle prestazioni. È possibile usare JSS con molti tipi di applicazioni, ma in questo articolo ci concentreremo su JSS per React.

Cos’è JSS?

Con JSS si possono scrivere gli stili CSS come oggetti JavaScript e utilizzare questi oggetti come nomi di classi negli elementi o nei componenti. JSS è indipendente dal framework, quindi è possibile usarlo in JavaScript puro o con framework come React e Angular.

JSS presenta diversi vantaggi rispetto allo stile CSS tradizionale:

  • Stile dinamico: con JSS è possibile manipolare gli stili in base alle interazioni dell’utente o a valori come i props o il contesto. Le funzioni JavaScript aiutano a generare dinamicamente gli stili nel browser in base allo stato dell’applicazione, ai dati esterni o alle API del browser.
  • Migliori funzionalità di tematizzazione: si possono creare stili specifici per un particolare tema utilizzando JSS. Ad esempio, potrete creare stili per un tema chiaro e scuro e poi applicare questi stili specifici all’intera applicazione in base alle preferenze dell’utente. Se utilizzate React, il pacchetto React-JSS supporta la propagazione dei temi basata sul contesto. Potete definire e gestire il tema in un unico punto prima di passare le informazioni sul tema lungo l’albero dei componenti utilizzando un fornitore di temi.
  • Migliore manutenibilità: definendo gli stili in oggetti JavaScript, potete raggruppare gli stili correlati in un’unica posizione e importarli nell’applicazione quando necessario. Questo approccio riduce la duplicazione del codice e ne migliora l’organizzazione, rendendo più facile la manutenzione degli stili nel tempo.
  • CSS reali: JSS genera CSS reali anziché stili in linea che possono essere disordinati e difficili da gestire. JSS utilizza nomi di classi univoci per impostazione predefinita, il che aiuta a evitare collisioni di denominazione causate dalla natura globale dei CSS.

Come scrivere gli stili con JSS

Questo articolo si basa su un progetto React. Utilizza il pacchetto react-jss, che integra JSS con React utilizzando l’API Hooks. react-jss viene fornito con i plugin predefiniti e permette di utilizzare JSS con una configurazione minima.

Sintassi di base e uso di JSS in React

Per utilizzare JSS in React, dovrete innanzitutto installare il pacchetto react-jss utilizzando un gestore di pacchetti come npm o Yarn.

La sintassi per scrivere gli stili in JSS prevede la definizione di regole CSS per elementi specifici all’interno di un oggetto JavaScript. Ad esempio, il codice seguente definisce gli stili per un pulsante in un’applicazione React.


const styles = {
      button: {
            padding: "10px 20px",
            background: "#f7df1e",
            textAlign: "center",
            border:"none"
      }
};

Nota: le proprietà CSS sono in camelcase.

Per applicare questi stili a un elemento HTML:

  1. Generate le classi passando gli stili al metodo createUseStyles()</code method from react-jss:
import { createUseStyles } from "react-jss";
const styles = {
       button: {
             padding: "10px 20px",
             background: "#f7df1e",
             textAlign: "center",
             border:"none"
       }
};
const useStyles = createUseStyles(styles);
  1. Applicate il CSS all’elemento pulsante utilizzando il nome della classe generata:
const App = () = > {
      const classes = useStyles();
      return (
            < button className={classes.button} > </button >
      );
};

Questo codice crea un componente React e applica gli stili nell’oggetto styles.

Come gestire le pseudo-classi, le media query e i keyframe

JSS supporta tutte le funzioni CSS esistenti, comprese le pseudo-classi, le media queries e i keyframes. Per definire gli stili di queste caratteristiche, usa la stessa sintassi delle normali regole di stile CSS.

Pseudo-classi

Ad esempio, supponiamo di voler aggiungere una pseudo-classe hover al pulsante per cambiare il colore dello sfondo quando l’utente ci passa sopra con il mouse. Il codice seguente implementa questa pseudo-classe in modo che lo sfondo del pulsante diventi verde chiaro al passaggio del mouse:

const styles = {
      button: {
            padding: "10px 20px",
            background: "#f7df1e",
            textAlign: "center",
            border:"none",
            '&:hover': {
                  backgroundColor: 'lightgreen',
            }
     }
};

Keyframes

Allo stesso modo, potete applicare un’animazione keyframe a un componente utilizzando la regola @keyframes. Ad esempio, di seguito è riportato un oggetto di stile per un componente che ruota.

const styles = {
       '@keyframes spin': {
             '0%': {
                   transform: 'rotate(0deg)',
             },
             '100%': {
                   transform: 'rotate(360deg)',
             },
       },
       spinner: {
              width: "100px",
              height: "100px",
              backgroundColor: "lightgreen",
              animation: '$spin 1s linear infinite',
       },
}

All’interno della funzione stili, avete definito un’animazione keyframe denominata spin utilizzando la regola @keyframes. Quindi, create una classe chiamata spinner che applica l’animazione utilizzando la sintassi $ per fare riferimento all’animazione keyframe.

Media query

Anche le media query utilizzano la solita sintassi CSS in JSS. Ad esempio, per modificare la dimensione del carattere di un pulsante in una determinata dimensione dello schermo, usate i seguenti stili:

const styles = {
      button: {
            fontSize: "12px",
            '@media (max-width: 768px)': {
                  fontSize: '34px',
            },
      }
};

Come avete appena visto, scrivere stili in JSS non è poi così diverso dallo scrivere semplici CSS. Tuttavia, il suo vantaggio è che potete sfruttare la potenza di JavaScript per rendere gli stili dinamici.

Stili dinamici con JSS

Stile dinamico significa creare degli stili che cambiano in risposta a condizioni specifiche. In React, gli stili possono cambiare in base a valori come lo stato, gli oggetti di scena e il contesto del componente.

Come creare stili dinamici con JSS

In JSS è possibile applicare in modo condizionale gli stili agli elementi con espressioni JavaScript per creare regole di stile dinamiche.

Supponiamo di avere un pulsante che riceve un oggetto chiamato bgColor. Il suo valore è il colore di sfondo del pulsante. Per creare una regola di stile che cambi il colore di sfondo del pulsante in base al prop, passate il prop al metodo useStyles.

import { createUseStyles } from "react-jss"

const styles = {
      button: {
            padding: "10px 20px",
            background: props = >props.bgColor,
            textAlign: "center",
            border:"none"
      }
};
const Button = ({...props}) => {
  
      const useStyles = createUseStyles(styles);
      const classes = useStyles({...props});
      return (
            <button className={classes.button}>Button </button>
      );
};

Poi, potete fare riferimento ai prop nell’oggetto styles. L’esempio precedente fa riferimento a props.bgColor.

Potete passare il colore di sfondo che desiderate quando renderizzate il componente. Il componente qui sotto renderizza due componenti Button con i colori di sfondo lightgreen e yellow.

export default function App() {
  return (
    <div >
      <Button bgColor="lightgreen" />
      <div style={{ marginTop: "10px" }}></div>
      <Button bgColor="yellow" />
    </div>
  );
}
Due pulsanti stilizzati dinamicamente con JSS
Due pulsanti stilizzati dinamicamente con JSS

Ogni volta che eseguite il rendering del componente Button, potete stilizzare lo sfondo a vostro piacimento.

Potete anche cambiare gli stili in base allo stato del componente. Supponiamo di avere un menu di navigazione con diversi link. Per evidenziare il link della pagina corrente, definite un valore di stato chiamato isActive che tiene traccia del fatto che un link del menu sia attivo.

Potete quindi utilizzare un operatore ternario JavaScript per verificare il valore di isActive, impostando il colore del link in blu se lo stato è true e in rosso se false.

const styles = {
      a: {
             color: ({ isActive }) => isActive ? 'blue' : 'red',
             padding: '10px',
      },
};

Ora i link attivi diventano blu, mentre quelli inattivi diventano rossi.

Allo stesso modo, potete creare uno stile dinamico basato sul contesto. Potete creare uno stile per un elemento, come UserContext, in base al valore di un contesto che memorizza lo stato online dell’utente.

const { online } = useContext(UserContext);
const styles = {
      status: {
            background: online ? 'lightgreen' : '',
            width: '20px',
            height: '20px',
            borderRadius: "50%",
            display: online ? 'flex' : 'hidden'
      },
};

In questo esempio, l’elemento ha uno sfondo verde se l’utente è online. Impostate la proprietà display a flex se l’utente è online e a hidden se l’utente è offline.

Casi d’uso dello stile dinamico

Lo stile dinamico è una potente funzione di JSS che ha molti casi d’uso:

  • Theming: potete definire degli stili basati su un oggetto tema, ad esempio un tema chiaro e un tema scuro, e passarli ai componenti come valore di prop o di contesto.
  • Rendering condizionato: JSS permette di definire gli stili in base a valori specifici. Potete creare stili che si applicano solo in determinate condizioni, ad esempio quando un pulsante è disabilitato, un campo di testo è in stato di errore, un menu di navigazione laterale è aperto o quando un utente è online.
  • Design reattivo: potete utilizzare lo stile dinamico in JSS per modificare lo stile di un elemento in base alla larghezza del viewport. Ad esempio, potete definire una serie di stili per un breakpoint specifico utilizzando le media queries e applicarli in modo condizionato in base alle dimensioni dello schermo.

Come usare i temi con JSS

Utilizzate i temi per creare un’interfaccia utente coerente in tutta l’applicazione. È facile creare temi in JSS: basta definire un oggetto tema con valori di stile globali, come colori, tipografia e spaziatura. Ad esempio:

const theme = {
      colors: {
            primary: '#007bff',
            secondary: '#6c757d',
            light: '#f8f9fa',
            dark: '#343a40',
       },
       typography: {
             fontFamily: 'Helvetica, Arial, sans-serif',
             fontSize: '16px',
             fontWeight: 'normal',
       },
       spacing: {
             small: '16px',
             medium: '24px',
             large: '32px',
       },
};

Per applicare i temi ai componenti, usate i context provider. La libreria JSS fornisce un componente ThemeProvider che potete avvolgere intorno ai componenti che devono accedere al tema.

L’esempio seguente avvolge il componente Button con il componente ThemeProvider e passa l’oggetto theme come prop.

import { ThemeProvider } from "react-jss";
const App = () => (
      <ThemeProvider theme={theme}>
            <Button />
      </ThemeProvider>
)

Potete accedere al tema nel componente Button utilizzando un hook useTheme() e passarlo all’oggetto useStyles. L’esempio seguente utilizza gli stili definiti nell’oggetto tema per creare un pulsante primario.

import { useTheme } from “react-jss”

const useStyles = createUseStyles({
  primaryButton: {
    background: ({ theme }) => theme.colors.primary,
    font: ({ theme }) => theme.typography.fontFamily,
    fontSize: ({ theme }) => theme.typography.fontSize,
    padding: ({ theme }) => theme.spacing.medium
  }
});

const Button = () => {
      const theme = useTheme()
      const classes = useStyles({theme})
      return (
            <div>
              <button className={classes.primaryButton}> Primary Button </button>
            </div>

      )
}

Il pulsante dovrebbe assomigliare all’immagine sottostante, con un testo nero su un pulsante rettangolare blu.

Uno stile di pulsante primario basato sul tema.
Uno stile di pulsante primario basato sul tema.

Cambiando uno dei valori dell’oggetto tema, verrebbero automaticamente attivati nuovi stili da applicare a tutti i componenti avvolti dal componente ThemeProvider. Se cambiate il valore del colore primario in lightgreen, anche il colore del pulsante diventa verde chiaro, come nell’immagine qui sotto.

Il colore primario del pulsante si adatta al tema.
Il colore primario del pulsante si adatta al tema.

Ecco alcune linee guida da seguire per la creazione dei temi:

  • Definire l’oggetto tema in un file separato per mantenere il codice organizzato e facile da mantenere.
  • Usare nomi descrittivi per i valori di stile per rendere l’oggetto tema facile da leggere e da aggiornare.
  • Usare le variabili CSS per definire i valori usati spesso nel CSS.
  • Creare dei valori predefiniti per tutte le proprietà di stile per mantenere un design coerente in tutta l’applicazione.
  • Testare accuratamente i temi per assicurarsi che funzionino come previsto su tutti i dispositivi e i browser.

Seguendo queste best practice, creerete un tema semplice da usare e facile da aggiornare man mano che l’applicazione cresce.

Prestazioni e ottimizzazione

JSS è una soluzione di styling performante. Con JSS, solo gli stili attualmente utilizzati sullo schermo vengono aggiunti al Document Object Model (DOM), riducendo così le dimensioni del DOM e velocizzando il rendering. Inoltre JSS memorizza nella cache gli stili renderizzati, il che significa che JSS compila il CSS solo una volta, migliorando ulteriormente le prestazioni.

Potete usufruire di ulteriori ottimizzazioni delle prestazioni utilizzando il pacchetto react-jss invece del pacchetto JSS principale. Ad esempio, react-jss rimuove i fogli di stile quando il componente viene smontato. Inoltre, gestisce l’estrazione critica dei CSS ed estrae gli stili solo dai componenti renderizzati. In questo modo il pacchetto react-jss riduce le dimensioni del bundle CSS e migliora i tempi di caricamento.

Per ridurre ulteriormente le dimensioni del bundle CSS, usate il code splitting per caricare solo il CSS di cui ha bisogno una pagina o un componente specifico. Una libreria come loadable-components può semplificare le operazioni di code splitting.

JSS permette anche di generare CSS lato server. Potete aggregare e convertire in stringa il CSS allegato utilizzando la classe di registro StyleSheet di JSS, quindi inviare i componenti renderizzati e la stringa CSS al client. Dopo l’avvio dell’applicazione, il CSS statico non è più necessario e potrete rimuoverlo, riducendo le dimensioni del bundle.

Riepilogo

Abbiamo visto le basi della sintassi JSS, come creare e applicare oggetti di stile ai componenti e come creare stili dinamici. Adesso sappiamo anche come utilizzare il componente ThemeProvider per applicare temi e migliorare le prestazioni in JSS. Ora potete usare JSS per creare stili riutilizzabili, manutenibili e dinamici che si adattano a varie condizioni.