Creazione di un componente di un pulsante

Una panoramica di base su come creare componenti <button> adattabili, accessibili e adattabili al colore.

In questo post voglio condividere le mie opinioni su come creare un elemento <button> adattabile e accessibile. Prova la demo e guarda il fonte

L'interazione con i pulsanti avviene tramite tastiera e mouse nei temi chiaro e scuro.

Se preferisci i video, ecco una versione di questo post su YouTube:

Panoramica

Supporto dei browser

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Origine

La <button> è stato creato per consentire l'interazione dell'utente. Il suo evento click viene attivato dalla tastiera, mouse, tocco, voce e altro ancora, con regole intelligenti relative di tempo. Inoltre, con alcuni stili predefiniti in ogni browser, per poterli usare direttamente senza personalizzazioni. Utilizza color-scheme per l'attivazione nei pulsanti chiari e scuri forniti dal browser.

Esistono anche diversi tipi di pulsanti, ciascuna mostrata nel precedente incorporamento di Codepen. Un <button> senza un tipo adattarsi in modo che rientri in un <form>, passando al tipo di invio.

<!-- buttons -->
<button></button>
<button type="submit"></button>
<button type="button"></button>
<button type="reset"></button>

<!-- button state -->
<button disabled></button>

<!-- input buttons -->
<input type="button" />
<input type="file">

Nella Sfida GUI di questo mese, ogni pulsante riceverà stili utili per differenziare visivamente l'intenzione. Reimposta pulsanti presenterà colori di avviso poiché sono distruttivi e invia pulsanti visualizzerà un testo con accenti blu in modo che appaia leggermente più promosso rispetto a quello standard pulsanti.

Anteprima dell&#39;insieme finale di tutti i tipi di pulsanti, mostrato in un modulo e non in un modulo, con interessanti aggiunte per i pulsanti con icona e quelli personalizzati.
. Anteprima dell'insieme finale di tutti i tipi di pulsanti, mostrato in un modulo e non in un modulo. con interessanti aggiunte per i pulsanti icona e i pulsanti personalizzati

I pulsanti hanno anche pseudo classi che il CSS possa usare per lo stile. Queste classi forniscono hook CSS per personalizzare aspetto del pulsante: :hover quando il mouse è sopra il pulsante, :active quando un mouse o la tastiera sta premendo :focus oppure :focus-visible per supportare gli stili con le tecnologie per la disabilità.

button:hover {}
button:active {}
button:focus {}
button:focus-visible {}
Anteprima dell&#39;insieme finale di tutti i tipi di pulsanti nel tema scuro.
Anteprima dell'insieme finale di tutti i tipi di pulsanti nel tema scuro

Aumento

Oltre ai tipi di pulsanti forniti dalla specifica HTML, ho aggiunto un parametro pulsante con un'icona e un pulsante con una classe personalizzata btn-custom.

<button>Default</button>
<input type="button" value="<input>"/>
<button>
  <svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true">
    <path d="..." />
  </svg>
  Icon
</button>
<button type="submit">Submit</button>
<button type="button">Type Button</button>
<button type="reset">Reset</button>
<button disabled>Disabled</button>
<button class="btn-custom">Custom</button>
<input type="file">

Quindi, per il test, ogni pulsante viene inserito all'interno di un modulo. In questo modo posso assicurarmi gli stili vengono aggiornati in modo appropriato rispetto al pulsante predefinito, che si comporta come un Invia. Inoltre, cambio la strategia basata sulle icone, passando da SVG in linea a SVG mascherato. per garantire che entrambi funzionino allo stesso modo.

<form>
  <button>Default</button>
  <input type="button" value="<input>"/>
  <button>Icon <span data-icon="cloud"></span></button>
  <button type="submit">Submit</button>
  <button type="button">Type Button</button>
  <button type="reset">Reset</button>
  <button disabled>Disabled</button>
  <button class="btn-custom btn-large" type="button">Large Custom</button>
  <input type="file">
</form>

A questo punto la matrice delle combinazioni è piuttosto faticosa. Pulsante Tra di grandi dimensioni, pseudo-classi ed essere all'interno o all'esterno di una forma, esistono oltre 20 combinazioni di pulsanti. La buona cosa che CSS può aiutarci a illustrare le chiaramente.

Accessibilità

Gli elementi dei pulsanti sono naturalmente accessibili, ma esistono alcuni miglioramenti.

Passa il mouse e imposta lo stato attivo insieme

Mi piace raggruppare :hover e :focus insieme all'elemento :is() pseudoselettore. Questo aiuta a garantire che le mie interfacce prendano sempre in considerazione la tastiera e stili tecnologici per la disabilità.

button:is(:hover, :focus) {
  
}
Prova una demo!

Anello di messa a fuoco interattiva

Mi piace animare l'anello di messa a fuoco per gli utenti della tastiera e delle tecnologie per la disabilità. IO ottenere questo risultato animando il contorno allontanandolo dal pulsante di 5 px, ma solo quando il pulsante non è attivo. Viene creato un effetto che porta l'anello di messa a fuoco torna alle dimensioni del pulsante quando viene premuto.

:where(button, input):where(:not(:active)):focus-visible {
  outline-offset: 5px;
}

Garanzia di trasmissione del contrasto di colore

Ci sono almeno quattro diverse combinazioni di colori, chiari e scuri che devono tenere in considerazione il contrasto di colore: pulsante, pulsante di invio, pulsante di ripristino pulsante disattivato. VisBug viene utilizzato qui per esamina e mostra tutti i punteggi in una volta sola:

Le icone vengono nascoste a persone che non possono vederle.

Quando si crea un pulsante icona, l'icona deve fornire un supporto visivo al il testo del pulsante. Ciò significa anche che l'icona non è importante per chi ha la vista o una perdita di dati. Fortunatamente il browser fornisce un modo per nascondere gli elementi allo screen reader in modo che le persone ipovedenti non siano disturbate dai pulsanti decorativi immagini:

<button>
  <svg … aria-hidden="true">...</svg>
  Icon Button
</button>
Chrome DevTools che mostra l&#39;albero dell&#39;accessibilità del pulsante. L&#39;albero ignora l&#39;immagine del pulsante perché aria-hidden è impostato su true.
Chrome DevTools che mostra l'albero dell'accessibilità del pulsante. L'albero ignora l'immagine del pulsante perché ha aria-hidden impostato su true
di Gemini Advanced.
.

Stili

Nella prossima sezione, indico innanzitutto un sistema di proprietà personalizzate per la gestione gli stili adattivi del pulsante. Con queste proprietà personalizzate posso iniziare selezionare elementi e personalizzarne l'aspetto.

Una strategia adattiva per le proprietà personalizzate

La strategia delle proprietà personalizzate utilizzata in questa verifica della GUI è molto simile utilizzata nella creazione di una combinazione di colori. Per un sistema adattivo di colori chiari e scuri, una proprietà personalizzata per ogni tema definiti e denominati di conseguenza. Quindi viene utilizzata un'unica proprietà personalizzata per contenere valore corrente del tema e assegnato a una proprietà CSS. In seguito, il singolo proprietà personalizzata può essere aggiornata con un valore diverso, quindi aggiorna il pulsante lo stile del testo.

button {
  --_bg-light: white;
  --_bg-dark: black;
  --_bg: var(--_bg-light);

  background-color: var(--_bg);
}

@media (prefers-color-scheme: dark) {
  button {
    --_bg: var(--_bg-dark);
  }
}

Mi piace il fatto che i temi chiaro e scuro siano chiari e dichiarativi. La le indiretta e l'astrazione vengono scaricate nella proprietà personalizzata --_bg, che ora è l'unico tipo "reattivo" proprietà; --_bg-light e --_bg-dark sono statico. È anche chiaro che il tema chiaro è il tema predefinito. oscuro viene applicato solo in modo condizionale.

Prepararsi alla coerenza del design

Il selettore condiviso

Il seguente selettore viene utilizzato per scegliere come target tutti i vari tipi di pulsanti ed è un po' faticoso all'inizio. :where() è per cui la personalizzazione del pulsante non richiede alcuna specificità. I pulsanti sono spesso adattato per scenari alternativi e il selettore :where() garantisce che l'attività è facile. All'interno di :where(), viene selezionato ogni tipo di pulsante, incluso il ::file-selector-button, che non può essere in uso all'interno di :is() o :where().

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"],
  input[type="file"]
),
:where(input[type="file"])::file-selector-button {
  
}

L'ambito di tutte le proprietà personalizzate sarà incluso all'interno di questo selettore. Tempo per la revisione tutte le proprietà personalizzate. In questo progetto vengono usate diverse proprietà personalizzate . Descriverò ciascun gruppo man mano che procediamo, quindi condividerò le informazioni contesti di movimento alla fine della sezione.

Colore intenso pulsante

I pulsanti e le icone di invio sono perfetti per dare un tocco di colore:

--_accent-light: hsl(210 100% 40%);
--_accent-dark: hsl(210 50% 70%);
--_accent: var(--_accent-light);

Colore testo del pulsante

I colori del testo dei pulsanti non sono bianco o nero, ma sono versioni scuri o chiare di --_accent utilizzando hsl() e rispettando la tonalità 210:

--_text-light: hsl(210 10% 30%);
--_text-dark: hsl(210 5% 95%);
--_text: var(--_text-light);

Colore sfondo pulsante

Gli sfondi dei pulsanti seguono lo stesso motivo hsl(), tranne che per il tema chiaro pulsanti: sono impostati sul bianco in modo che la loro superficie li faccia apparire vicino ai all'utente o davanti ad altre piattaforme:

--_bg-light: hsl(0 0% 100%);
--_bg-dark: hsl(210 9% 31%);
--_bg: var(--_bg-light);

Sfondo pulsante

Questo colore di sfondo serve per far apparire una superficie dietro altre superfici, per lo sfondo dell'input del file:

--_input-well-light: hsl(210 16% 87%);
--_input-well-dark: hsl(204 10% 10%);
--_input-well: var(--_input-well-light);

Spaziatura interna dei pulsanti

La spaziatura intorno al testo nel pulsante viene eseguita utilizzando lo ch unità, una lunghezza relativa alla dimensione del carattere. Ciò diventa fondamentale quando i pulsanti possono semplicemente sollevare font-size e le scale dei pulsanti in modo proporzionale:

--_padding-inline: 1.75ch;
--_padding-block: .75ch;

Bordo pulsante

Il raggio del bordo del pulsante è accantonato in una proprietà personalizzata, pertanto l'input del file può corrispondono agli altri pulsanti. I colori dei bordi seguono il colore adattivo stabilito di sistema:

--_border-radius: .5ch;

--_border-light: hsl(210 14% 89%);
--_border-dark: var(--_bg-dark);
--_border: var(--_border-light);

Effetto di evidenziazione al passaggio del mouse sul pulsante

Queste proprietà stabiliscono una proprietà delle dimensioni per la transizione al momento dell'interazione e il colore di evidenziazione segue il sistema di colori adattivi. Vedremo come questi interagiscono più avanti in questo post, ma queste ultime vengono usate per un box-shadow effetto:

--_highlight-size: 0;

--_highlight-light: hsl(210 10% 71% / 25%);
--_highlight-dark: hsl(210 10% 5% / 25%);
--_highlight: var(--_highlight-light);

Ombra testo pulsante

Ogni pulsante ha un sottile stile di ombra del testo. in modo che il testo si sovrapponga il pulsante, migliorando la leggibilità e aggiungendo un buon livello di perfezionamento della presentazione.

--_ink-shadow-light: 0 1px 0 var(--_border-light);
--_ink-shadow-dark: 0 1px 0 hsl(210 11% 15%);
--_ink-shadow: var(--_ink-shadow-light);

Icona del pulsante

Le icone hanno la dimensione di due caratteri grazie alla lunghezza relativa (ch unità) per far sì che l'icona venga ridimensionata proporzionalmente al testo del pulsante. La Il colore dell'icona si appoggia su --_accent-color per creare un'immagine adattivo e all'interno del tema colore.

--_icon-size: 2ch;
--_icon-color: var(--_accent);

Ombra pulsante

Affinché le ombre si adattino correttamente alla luce e all'oscurità, devono spostare colore e opacità. Le ombre con tema chiaro sono migliori quando sono discrete e colorate verso il colore della superficie su cui si sovrappongono. Le ombre del tema scuro devono essere più scure più saturi in modo da sovrapporre colori più scuri sulla superficie.

--_shadow-color-light: 220 3% 15%;
--_shadow-color-dark: 220 40% 2%;
--_shadow-color: var(--_shadow-color-light);

--_shadow-strength-light: 1%;
--_shadow-strength-dark: 25%;
--_shadow-strength: var(--_shadow-strength-light);

Con i colori adattivi e le forze posso combinare due profondità di ombre:

--_shadow-1: 0 1px 2px -1px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 9%));

--_shadow-2: 
  0 3px 5px -2px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 3%)),
  0 7px 14px -5px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 5%));

Inoltre, per conferire ai pulsanti un aspetto leggermente 3D, l'ombra di un riquadro 1px crea l'illusione:

--_shadow-depth-light: 0 1px var(--_border-light);
--_shadow-depth-dark: 0 1px var(--_bg-dark);
--_shadow-depth: var(--_shadow-depth-light);

Transizioni dei pulsanti

Seguendo lo schema dei colori adattivi, creo due proprietà statiche le opzioni di progettazione del sistema:

--_transition-motion-reduce: ;
--_transition-motion-ok:
  box-shadow 145ms ease,
  outline-offset 145ms ease
;
--_transition: var(--_transition-motion-reduce);

Tutte le proprietà insieme nel selettore

Tutte le proprietà personalizzate in un selettore

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"],
  input[type="file"]
),
:where(input[type="file"])::file-selector-button {
  --_accent-light: hsl(210 100% 40%);
  --_accent-dark: hsl(210 50% 70%);
  --_accent: var(--_accent-light);

--_text-light: hsl(210 10% 30%); --_text-dark: hsl(210 5% 95%); --_text: var(--_text-light);

--_bg-light: hsl(0 0% 100%); --_bg-dark: hsl(210 9% 31%); --_bg: var(--_bg-light);

--_input-well-light: hsl(210 16% 87%); --_input-well-dark: hsl(204 10% 10%); --_input-well: var(--_input-well-light);

--_padding-inline: 1.75ch; --_padding-block: .75ch;

--_border-radius: .5ch; --_border-light: hsl(210 14% 89%); --_border-dark: var(--_bg-dark); --_border: var(--_border-light);

--_highlight-size: 0; --_highlight-light: hsl(210 10% 71% / 25%); --_highlight-dark: hsl(210 10% 5% / 25%); --_highlight: var(--_highlight-light);

--_ink-shadow-light: 0 1px 0 hsl(210 14% 89%); --_ink-shadow-dark: 0 1px 0 hsl(210 11% 15%); --_ink-shadow: var(--_ink-shadow-light);

--_icon-size: 2ch; --_icon-color-light: var(--_accent-light); --_icon-color-dark: var(--_accent-dark); --_icon-color: var(--accent, var(--_icon-color-light));

--_shadow-color-light: 220 3% 15%; --_shadow-color-dark: 220 40% 2%; --_shadow-color: var(--_shadow-color-light); --_shadow-strength-light: 1%; --_shadow-strength-dark: 25%; --_shadow-strength: var(--_shadow-strength-light); --_shadow-1: 0 1px 2px -1px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 9%)); --_shadow-2: 0 3px 5px -2px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 3%)), 0 7px 14px -5px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 5%)) ;

--_shadow-depth-light: hsl(210 14% 89%); --_shadow-depth-dark: var(--_bg-dark); --_shadow-depth: var(--_shadow-depth-light);

--_transition-motion-reduce: ; --_transition-motion-ok: box-shadow 145ms ease, outline-offset 145ms ease ; --_transition: var(--_transition-motion-reduce); }

I pulsanti predefiniti vengono visualizzati con il tema chiaro e scuro uno accanto all&#39;altro.

Adattamenti del tema scuro

Il valore del pattern di oggetti statici -light e -dark diventa chiaro quando gli oggetti di scena con il tema scuro sono impostati:

@media (prefers-color-scheme: dark) {
  :where(
    button,
    input[type="button"],
    input[type="submit"],
    input[type="reset"],
    input[type="file"]
  ),
  :where(input[type="file"])::file-selector-button {
    --_bg: var(--_bg-dark);
    --_text: var(--_text-dark);
    --_border: var(--_border-dark);
    --_accent: var(--_accent-dark);
    --_highlight: var(--_highlight-dark);
    --_input-well: var(--_input-well-dark);
    --_ink-shadow: var(--_ink-shadow-dark);
    --_shadow-depth: var(--_shadow-depth-dark);
    --_shadow-color: var(--_shadow-color-dark);
    --_shadow-strength: var(--_shadow-strength-dark);
  }
}

Non solo legge bene, ma gli utenti di questi pulsanti personalizzati possono utilizzare oggetti essenziali e con la certezza che si adatteranno in modo appropriato alle preferenze dell'utente.

Adattamenti del movimento ridotti

Se l'utente in visita è idoneo al movimento, assegna --_transition a var(--_transition-motion-ok):

@media (prefers-reduced-motion: no-preference) {
  :where(
    button,
    input[type="button"],
    input[type="submit"],
    input[type="reset"],
    input[type="file"]
  ),
  :where(input[type="file"])::file-selector-button {
    --_transition: var(--_transition-motion-ok);
  }
}

Alcuni stili condivisi

Per i pulsanti e gli input, i caratteri devono essere impostati su inherit in modo che corrispondano altri caratteri della pagina; altrimenti verranno definiti dal browser. Anche questo si applica a letter-spacing. Se imposti line-height su 1.5, viene impostata la letterbox per dare al testo un po' di spazio sopra e sotto:

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"],
  input[type="file"]
),
:where(input[type="file"])::file-selector-button {
  /* …CSS variables */

  font: inherit;
  letter-spacing: inherit;
  line-height: 1.5;
  border-radius: var(--_border-radius);
}

Screenshot che mostra i pulsanti dopo l&#39;applicazione degli stili precedenti.

Stili dei pulsanti

Regolazione del selettore

Il selettore input[type="file"] non è la parte del pulsante dell'input, lo pseudo-elemento ::file-selector-button è, quindi ho rimosso input[type="file"] dall'elenco:

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"],
  input[type="file"]
),
:where(input[type="file"])::file-selector-button {
  
}

Regolazioni di cursore e tocco

Innanzitutto stile il cursore sullo stile pointer, che aiuta il pulsante a indicare per far capire agli utenti che è interattiva. Poi aggiungo touch-action: manipulation a non dover attendere e osservare un potenziale doppio clic. In questo modo sono più veloci:

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  cursor: pointer;
  touch-action: manipulation;
}

Colori e bordi

Successivamente, personalizzo la dimensione del carattere, lo sfondo, i colori del testo e del bordo utilizzando delle proprietà personalizzate adattive stabilite in precedenza:

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  

  font-size: var(--_size, 1rem);
  font-weight: 700;
  background: var(--_bg);
  color: var(--_text);
  border: 2px solid var(--_border);
}

Screenshot che mostra i pulsanti dopo l&#39;applicazione degli stili precedenti.

Ombre

Ai pulsanti vengono applicate ottime tecniche. La text-shadow è che si adatta a chiari e scuri, creando un piacevole aspetto discreto testo ben posizionato sopra lo sfondo. Per box-shadow, sono assegnate tre ombre. La prima, --_shadow-2, è una normale ombra di un riquadro. La seconda ombra è un trucco per l'occhio che fa sembrare il pulsante un po' smussato. L'ultima ombra è per l'evidenziazione al passaggio del mouse, inizialmente a 0, ma le dimensioni verranno assegnate in un secondo momento e sarà sottoposto a transizione, in modo che venga visualizzato a crescere dal pulsante.

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  

  box-shadow: 
    var(--_shadow-2),
    var(--_shadow-depth),
    0 0 0 var(--_highlight-size) var(--_highlight)
  ;
  text-shadow: var(--_ink-shadow);
}

Screenshot che mostra i pulsanti dopo l&#39;applicazione degli stili precedenti.

Layout

Ho assegnato al pulsante un layout flexbox, e nello specifico un layout inline-flex adatto ai suoi contenuti. Poi centro il testo e allineare verticalmente e orizzontalmente gli elementi secondari center. In questo modo, icone e altri gli elementi del pulsante devono essere allineati correttamente.

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  

  display: inline-flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}

Screenshot che mostra i pulsanti dopo l&#39;applicazione degli stili precedenti.

Spaziatura

Per la spaziatura dei pulsanti, utilizzavo gap per mantenere i fratelli da tocchi e logici proprietà per la spaziatura interna la spaziatura funziona per tutti i layout di testo.

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  

  gap: 1ch;
  padding-block: var(--_padding-block);
  padding-inline: var(--_padding-inline);
}

Screenshot che mostra i pulsanti dopo l&#39;applicazione degli stili precedenti.

UX con tocco e mouse

La prossima sezione è dedicata principalmente agli utenti touch sui dispositivi mobili. Il primo proprietà, user-select, è rivolto a tutti gli utenti. impedisce al testo di evidenziare il testo del pulsante. Si tratta per lo più visibile sui dispositivi touch quando si tocca e si tiene premuto un pulsante e evidenzia il testo del pulsante.

In genere ho notato che non è l'esperienza utente con i pulsanti integrati app, quindi lo disattivo impostando user-select su Nessuna. Tocca Colori di evidenziazione (-webkit-tap-highlight-color) e i menu contestuali del sistema operativo (-webkit-touch-callout) sono altre funzionalità dei pulsanti molto incentrate sul web che non sono in linea con i le aspettative degli utenti del pulsante, quindi li rimuovo anch'esso.

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  

  user-select: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
}

Transizioni

La variabile adattiva --_transition è assegnata alla proprietà transition:

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  

  transition: var(--_transition);
}

Quando passi il mouse sopra e l'utente non sta premendo attivamente, regola l'evidenziazione dell'ombra. per conferire un aspetto accattivante che sembra crescere dall'interno Pulsante:

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
):where(:not(:active):hover) {
  --_highlight-size: .5rem;
}

Quando è attivo lo stato attivo, aumenta l'offset del contorno della messa a fuoco rispetto al pulsante, assegnandogli anche un aspetto accattivante che sembra crescere dall'interno del pulsante:

:where(button, input):where(:not(:active)):focus-visible {
  outline-offset: 5px;
}

Icone

Per le icone di gestione, al selettore è stato aggiunto un selettore :where() per il formato SVG diretto secondari o elementi con l'attributo personalizzato data-icon. Le dimensioni dell'icona sono impostate alla proprietà personalizzata usando le proprietà logiche in linea e a blocchi. Colore tratto così come un drop-shadow in base ai text-shadow. flex-shrink è impostata su 0, quindi l'icona non è mai schiacciato. Infine seleziono le icone a linee e qui assegno questi stili con Limiti di riga e unioni di riga di fill: none e round:

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
) > :where(svg, [data-icon]) {
  block-size: var(--_icon-size);
  inline-size: var(--_icon-size);
  stroke: var(--_icon-color);
  filter: drop-shadow(var(--_ink-shadow));

  flex-shrink: 0;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

Screenshot che mostra i pulsanti dopo l&#39;applicazione degli stili precedenti.

Personalizzazione dei pulsanti di invio

Volevo che i pulsanti venissero inviati in modo lievemente promosso e ho ottenuto rendendo il colore del testo dei pulsanti come colore di contrasto:

:where(
  [type="submit"], 
  form button:not([type],[disabled])
) {
  --_text: var(--_accent);
}

Screenshot che mostra i pulsanti dopo l&#39;applicazione degli stili precedenti.

Personalizza i pulsanti di ripristino

Volevo che i pulsanti avessero alcuni segnali di avviso integrati per avvisare gli utenti i loro comportamenti potenzialmente distruttivi. Ho anche scelto di applicare uno stile al tema chiaro pulsante con più accenti rossi rispetto al tema scuro. La personalizzazione viene eseguita modificando il colore di base chiaro o scuro appropriato e il pulsante aggiorna lo stile:

:where([type="reset"]) {
  --_border-light: hsl(0 100% 83%);
  --_highlight-light: hsl(0 100% 89% / 20%);
  --_text-light: hsl(0 80% 50%);
  --_text-dark: hsl(0 100% 89%);
}

Ho anche pensato che sarebbe stato utile che il colore dei contorni della messa a fuoco corrispondesse all'accento rosso. Il colore del testo adatta il rosso scuro al rosso chiaro. Creo il colore dei contorni corrispondono alla parola chiave currentColor:

:where([type="reset"]):focus-visible {
  outline-color: currentColor;
}

Screenshot che mostra i pulsanti dopo l&#39;applicazione degli stili precedenti.

Personalizza pulsanti disattivati

È troppo comune che i pulsanti disattivati abbiano un contrasto di colore scarso durante la prova a ridurre il pulsante disattivato in modo che appaia meno attivo. li ho testati tutti set di colori e si è assicurato che fossero superati, impostando il valore di luminosità HSL fino a quando superato in DevTools o VisBug.

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
)[disabled] {
  --_bg: none;
  --_text-light: hsl(210 7% 40%);
  --_text-dark: hsl(210 11% 71%);

  cursor: not-allowed;
  box-shadow: var(--_shadow-1);
}

Screenshot che mostra i pulsanti dopo l&#39;applicazione degli stili precedenti.

Personalizzazione dei pulsanti di immissione dei file

Il pulsante di input del file è un contenitore di un intervallo e un pulsante. Il CSS è in grado di definire un po' lo stile del container di input e del pulsante nidificato, ma l'intervallo. Al contenitore è stato assegnato un valore max-inline-size, quindi non potrà aumentare di dimensioni necessario, mentre inline-size: 100% si consentirà di ridurne e adattarsi e container sono più piccoli di quanto sono. Il colore di sfondo è impostato sul colore adattivo che è più scuro di altre superfici, quindi guarda dietro il pulsante di selezione dei file.

:where(input[type="file"]) {
  inline-size: 100%;
  max-inline-size: max-content;
  background-color: var(--_input-well);
}

I pulsanti del selettore file e del tipo di input sono forniti specificamente appearance: none per rimuovere gli stili forniti dal browser che non lo erano sovrascritto dagli altri stili di pulsante.

:where(input[type="button"]),
:where(input[type="file"])::file-selector-button {
  appearance: none;
}

Infine, il margine viene aggiunto alla sezione inline-end del pulsante per spingere il testo dell'intervallo lontano dal pulsante, creando spazio.

:where(input[type="file"])::file-selector-button {
  margin-inline-end: var(--_padding-inline);
}

Screenshot che mostra i pulsanti dopo l&#39;applicazione degli stili precedenti.

Eccezioni speciali relative al tema scuro

Ho assegnato ai pulsanti di azione principali uno sfondo più scuro per creare un contrasto più elevato testo, conferendo loro un aspetto leggermente più promosso.

@media (prefers-color-scheme: dark) {
  :where(
    [type="submit"],
    [type="reset"],
    [disabled],
    form button:not([type="button"])
  ) {
    --_bg: var(--_input-well);
  }
}

Screenshot che mostra i pulsanti dopo l&#39;applicazione degli stili precedenti.

Creazione delle varianti

Per divertimento, e dato che è pratico, ho scelto di mostrare come creare varianti di prodotto. Una variante è molto vivace, in modo simile alla frequenza dei pulsanti principali look. Un'altra variante è grande. L'ultima variante ha un'icona con riempimento a gradiente.

Pulsante dai colori vivaci

Per ottenere questo stile di pulsante, ho sovrascritto gli oggetti di scena di base direttamente con colori. Anche se è stato facile e veloce, rimuove tutti gli oggetti e gli oggetti adattivi la stessa cosa per i temi chiari e scuri.

.btn-custom {
  --_bg: linear-gradient(hsl(228 94% 67%), hsl(228 81% 59%));
  --_border: hsl(228 89% 63%);
  --_text: hsl(228 89% 100%);
  --_ink-shadow: 0 1px 0 hsl(228 57% 50%);
  --_highlight: hsl(228 94% 67% / 20%);
}

Il pulsante personalizzato viene mostrato in modalità chiaro e scuro. È di colore blu molto intenso, come in genere i pulsanti di azione principali.

Pulsante grande

Questo stile del pulsante si ottiene modificando la proprietà personalizzata --_size. Spaziatura interna e altri elementi dello spazio sono relativi a questa dimensione, con conseguente aumento proporzionalmente alle nuove dimensioni.

.btn-large {
  --_size: 1.5rem;
}

Il pulsante grande viene mostrato accanto al pulsante personalizzato, circa 150 volte più grande.

Pulsante icona

Questo effetto icona non ha nulla a che fare con gli stili dei pulsanti, ma mostrare come farlo con poche proprietà CSS e l'efficacia del pulsante gestisce le icone che non sono SVG in linea.

[data-icon="cloud"] {
  --icon-cloud: url("https://api.iconify.design/mdi:apple-icloud.svg") center / contain no-repeat;

  -webkit-mask: var(--icon-cloud);
  mask: var(--icon-cloud);
  background: linear-gradient(to bottom, var(--_accent-dark), var(--_accent-light));
}

Un pulsante con un&#39;icona viene mostrato con temi chiari e scuri.

Conclusione

Ora che sai come ci ho fatto, come faresti‽ 🙂

Diversificaamo i nostri approcci e impariamo tutti i modi per creare sul web.

Crea una demo, twittami con i link e la aggiungerò alla sezione dei remix della community qui sotto.

Remix della community

Ancora niente da visualizzare qui.

Risorse