Cum să configurați schemele de culori ale aplicației cu proprietăți personalizate CSS

Publicat: 2022-03-10
Rezumat rapid ↬ În acest articol, Artur Basak introduce o abordare modernă a modului de a configura proprietăți personalizate CSS care să răspundă la culorile aplicației. Ideea de a împărți culorile în trei niveluri poate fi destul de utilă: o paletă (sau o schemă), culori funcționale (sau temă) și culori componente (domeniu local).

Variabilele sunt un instrument de bază care ajută la organizarea culorilor într-un proiect. Multă vreme, inginerii front-end au folosit variabile de preprocesor pentru a configura culorile unui proiect. Dar acum, mulți dezvoltatori preferă mecanismul nativ modern pentru organizarea variabilelor de culoare: CSS Custom Properties. Cel mai important avantaj al acestora față de variabilele preprocesorului este că funcționează în timp real, nu în etapa de compilare a proiectului și au suport pentru modelul în cascadă care vă permite să utilizați moștenirea și redefinirea valorilor din mers.

Când încercați să organizați o schemă de culori pentru aplicație, puteți oricând să plasați toate proprietățile personalizate care se referă la culoare în secțiunea rădăcină, să le denumiți și să le utilizați în toate locurile necesare.

Vezi stiloul [Proprietăți personalizate pentru culori](https://codepen.io/smashingmag/pen/RwaNqxW) de Artur Basak.

Vezi proprietățile personalizate ale stiloului pentru culori de Artur Basak.

Aceasta este o opțiune, dar vă ajută să rezolvați problemele legate de tematica aplicației, etichetarea albă, reîmprospătarea mărcii sau organizarea unui mod deschis sau întunecat? Ce se întâmplă dacă trebuie să ajustați schema de culori pentru a crește contrastul? Cu abordarea actuală, va trebui să actualizați fiecare valoare din variabilele dvs.

În acest articol, vreau să sugerez o abordare mai flexibilă și mai rezistentă cu privire la modul de împărțire a variabilelor de culoare folosind proprietăți personalizate, care pot rezolva multe dintre aceste probleme.

Mai multe după săritură! Continuați să citiți mai jos ↓

Configurați paleta de culori

Colorarea oricărui site web începe cu configurarea unei scheme de culori. O astfel de schemă se bazează pe roata de culori. De obicei, doar câteva culori primare formează baza unei palete, restul sunt culori derivate - tonuri și tonuri medii. Cel mai adesea, paleta este statică și nu se modifică în timp ce aplicația web rulează.

Conform teoriei culorilor, există doar câteva opțiuni pentru schemele de culori:

  • Schemă monocromatică (o culoare primară)
  • Schemă complementară (două culori primare)
  • Schema triadei (trei culori primare)
  • Schema tetradică (patru culori primare)
  • Model adiacent (două sau trei culori primare)

Pentru exemplul meu, voi genera o schemă de culori triadă folosind serviciul Paletton:

Roată de culori cu schema triadică stabilită: variație de verde, albastru și roșu.
Serviciu Paletton: Schema de culori triadică. (Previzualizare mare)

Acum am trei culori principale. Pe baza acestora, voi calcula tonurile și tonurile medii (formatul HSL în combinație cu funcția calc este un instrument foarte util pentru aceasta). Schimbând valoarea luminozității, pot genera mai multe culori suplimentare pentru paletă.

Vedeți Pen [HSL Palette](https://codepen.io/smashingmag/pen/OJNPaQW) de Artur Basak.

Vezi Paleta Pen HSL de Artur Basak.

Acum, dacă paleta este modificată, atunci va fi necesar să se schimbe doar valoarea culorilor primare. Restul va fi recalculat automat.

Dacă preferați formatele HEX sau RGB, atunci nu contează; se poate forma o paletă în etapa de compilare a proiectului cu funcțiile corespunzătoare ale preprocesorului (de exemplu cu SCSS și funcția color-adjust ). După cum am menționat anterior, acest strat este în mare parte static; este extrem de rar ca paleta să fie schimbată într-o aplicație care rulează. De aceea îl putem calcula cu preprocesoare.

Notă : De asemenea, recomand să generați atât HEX literal, cât și RGB pentru fiecare culoare. Acest lucru va permite să jucați cu canalul alfa în viitor.

Vezi stiloul [SCSS Palette](https://codepen.io/smashingmag/pen/oNxgQqv) de Artur Basak.

Vezi Paleta Pen SCSS de Artur Basak.

Nivelul paletei este singurul nivel în care culoarea este codificată direct în numele variabilelor, adică putem identifica în mod unic culoarea citind numele.

Definiți tema sau culorile funcționale

Odată ce paleta este gata, următorul pas este nivelul de culori funcționale . La acest nivel, valoarea culorii nu este atât de importantă ca scopul ei, funcția pe care o îndeplinește și ce anume colorează. De exemplu, culoarea principală sau a mărcii aplicației, culoarea chenarului, culoarea textului pe un fundal întunecat, culoarea textului pe un fundal deschis, culoarea de fundal a butoanelor, culoarea linkului, culoarea linkului hover, culoarea textului indicativ și așa mai departe .

Acestea sunt lucruri extrem de comune pentru aproape orice site web sau aplicație. Putem spune că astfel de culori sunt responsabile pentru o anumită temă de culoare a aplicației. De asemenea, valorile unor astfel de variabile sunt preluate strict din paletă. Astfel, putem schimba cu ușurință temele aplicației prin simpla operare cu palete de culori diferite.

Mai jos, am creat trei comenzi tipice pentru UI: un buton, un link și un câmp de introducere. Ele sunt colorate folosind variabile funcționale care conțin valori din paleta pe care am generat-o anterior mai sus. Principala variabilă funcțională care este responsabilă pentru tema aplicației (marca condiționată) este variabila de culoare primară.

Folosind cele trei butoane din partea de sus, puteți schimba temele (schimbați culoarea mărcii pentru comenzi). Modificarea are loc prin utilizarea API-ului CSSOM adecvat (setProperty).

Vezi stiloul [Culori funcționale](https://codepen.io/smashingmag/pen/poyvQLL) de Artur Basak.

Vezi Pen Functional Colors de Artur Basak.

Această abordare este convenabilă nu numai pentru tematică, ci și pentru configurarea paginilor web individuale. De exemplu, pe site-ul web zubry.by, am folosit o foaie de stil comună și o variabilă funcțională --page-color pentru a colora sigla, titlurile, controalele și selecția de text pentru toate paginile. Și în stilurile proprii ale fiecărei pagini, tocmai am redefinit această variabilă pentru a seta paginii culoarea primară individuală.

3 pagini web ale site-ului ZUBRY.BY: pagina de timbre, pagina de cărți poștale și pagina de felicitări.
Site-ul web ZUBRY.BY unde fiecare pagină are culoare primară individuală. (Previzualizare mare)

Utilizați culorile componente

Proiectele web mari conțin întotdeauna descompunere; împărțim totul în componente mici și le reutilizam în multe locuri. Fiecare componentă are de obicei propriul stil, ceea ce înseamnă că nu contează ce am folosit pentru a descompune modulele BEM sau CSS sau altă abordare; este important ca fiecare astfel de bucată de cod să poată fi numită domeniu local și reutilizată.

În general, văd rostul utilizării variabilelor de culoare la nivel de componentă în două cazuri.

Primul este atunci când componentele care, conform ghidului de stil al aplicației, sunt repetate cu setări diferite, de exemplu butoane pentru nevoi diferite, cum ar fi butonul principal (de marcă), butonul secundar, terțiar și așa mai departe.

Diferite stiluri de butoane pentru aplicația Tispr.
Ghid de stil al aplicației Tispr. Butoane. (Previzualizare mare)

Al doilea este atunci când componentele care au mai multe stări cu culori diferite, de exemplu, trecerea la buton, stările active și de focalizare; stări normale și nevalide pentru câmpul de intrare sau selectare și așa mai departe.

Un caz mai rar în care variabilele componente pot fi utile este funcționalitatea unei „etichete albe”. „Eticheta albă” este o caracteristică de serviciu care permite utilizatorului să personalizeze sau să marcheze o parte a interfeței cu utilizatorul pentru a îmbunătăți experiența de interacțiune cu clienții săi. De exemplu, documentele electronice pe care un utilizator le partajează clienților săi printr-un serviciu sau șabloane de e-mail. În acest caz, variabilele la nivel de componentă vor ajuta la configurarea anumitor componente separat de restul temei de culoare a aplicației.

În exemplul de mai jos, am adăugat acum controale pentru personalizarea culorilor butonului principal (marca). Folosind variabilele de culoare ale nivelului de componentă, putem configura controalele UI separat unele de altele.

Vezi stiloul [Component Colors](https://codepen.io/smashingmag/pen/LYNEXdw) de Artur Basak.

Vezi culorile componentelor stiloului de Artur Basak.

Cum să determinați ce nivel are o variabilă?

Am dat peste întrebarea cum să înțelegem ce poate fi pus în rădăcină (temă sau nivel funcțional) și ce să lași la nivelul unei componente. Aceasta este o întrebare excelentă la care este dificil să răspunzi fără a vedea situația cu care lucrezi.

Din păcate, aceeași abordare ca și în programare nu funcționează cu culori și stiluri, dacă vedem trei bucăți identice de cod, atunci trebuie să le refactorăm.

Culoarea se poate repeta de la componentă la componentă, dar asta nu înseamnă că este o regulă. Nu poate exista nicio relație între astfel de componente. De exemplu, chenarul câmpului de introducere și fundalul butonului primar. Da, în exemplul meu de mai sus, acesta este cazul, dar să verificăm următorul exemplu:

Vezi stiloul [Color Split: Only Palette](https://codepen.io/smashingmag/pen/YzqPRLX) de Artur Basak.

Vedeți Pen Color Split: Only Palette de Artur Basak.

Culoarea gri închis se repetă - acesta este chenarul câmpului de introducere, culoarea de umplere a pictogramei de închidere și fundalul butonului secundar. Dar aceste componente nu sunt în niciun fel legate între ele. Dacă culoarea marginii câmpului de introducere se schimbă, atunci nu vom schimba fundalul butonului secundar. Pentru un astfel de caz trebuie să păstrăm aici doar variabila din paletă.

Comenzi UI: butoane, link, cap și texte obișnuite, câmp de introducere
Exemplu de ghid de stil de aplicație. (Previzualizare mare)

Ce zici de verde? O putem defini clar ca culoarea primară sau a mărcii, cel mai probabil, dacă culoarea butonului principal se schimbă, atunci se va schimba și culoarea linkului și a antetului primului nivel.

Dar roșu? Starea nevalidă a câmpurilor de introducere, mesajele de eroare și butoanele distructive vor avea aceeași culoare la nivelul întregului aplicație. Acesta este un model. Acum pot defini mai multe variabile funcționale comune în secțiunea rădăcină:

Vezi stiloul [Color Split: Functional Level](https://codepen.io/smashingmag/pen/MWyYzGX) de Artur Basak.

Vedeți Pen Colour Split: Functional Level de Artur Basak.

În ceea ce privește nivelul de culori ale componentelor, putem identifica cu ușurință componentele care pot fi personalizate folosind proprietăți personalizate.

Butonul se repetă cu setări diferite, culoarea de fundal și textul pentru diferite cazuri de utilizare se schimbă - caz primar, secundar, terțiar, distructiv sau negativ.

Câmpul de introducere are două stări — incorectă și normală, în care culorile de fundal și marginile diferă. Și așa, să punem aceste setări în variabile de culoare la nivelul componentelor corespunzătoare.

Pentru restul componentelor, nu este necesară definirea variabilelor de culoare locale, aceasta va fi redundantă.

Vedeți Pen [Color Split: Component Level](https://codepen.io/smashingmag/pen/BaKyGVR) de Artur Basak.

Vedeți Pen Color Split: Component Level de Artur Basak.

Trebuie să vă scufundați în limbajul model al proiectului dvs., care este, probabil, dezvoltat de echipa de proiectare și UX. Inginerii trebuie să înțeleagă pe deplin întregul concept al unui limbaj vizual, doar atunci putem determina ce este comun și care ar trebui să trăiască la nivel funcțional și ce ar trebui să rămână în sfera locală de vizibilitate.

Dar nu totul este atât de complicat, sunt lucruri evidente. Fundalul general al paginii, fundalul și culoarea textului principal, în majoritatea cazurilor, acesta este ceea ce stabilește tema aplicației dvs. Este extrem de convenabil să colectați astfel de lucruri care sunt responsabile pentru configurarea unui anumit mod (cum ar fi modul întunecat sau luminos).

De ce să nu puneți totul în secțiunea rădăcină?

Am avut o astfel de experiență. Pe proiectul Lition, echipa și cu mine ne-am confruntat cu faptul că trebuia să sprijinim IE11 pentru aplicația web, dar nu și pentru site și aterizări. A fost folosit un UI Kit comun între proiecte și am decis să punem toate variabilele în rădăcină, acest lucru ne va permite să le redefinim la orice nivel.

Și, de asemenea, cu această abordare pentru aplicația web și cazul IE11, pur și simplu am trecut codul prin următorul plugin post-procesor și am transformat aceste variabile în literale pentru toate componentele UI din proiect. Acest truc este posibil doar dacă toate variabilele au fost definite în secțiunea rădăcină, deoarece post-procesorul nu poate înțelege specificul modelului în cascadă.

Pagina principală a site-ului web Lition cu instrumente de dezvoltare a browserului deschise
Site-ul web Lition SSR. Toate variabilele din secțiunea rădăcină. (Previzualizare mare)

Acum înțeleg că aceasta nu a fost calea corectă. În primul rând, dacă puneți culori componente în secțiunea rădăcină, atunci rupeți principiul separării preocupărilor. Ca rezultat, puteți ajunge cu CSS redundant în foaia de stil. De exemplu, aveți folderul de componente în care fiecare componentă are propriile stiluri. Aveți, de asemenea, o foaie de stil comună în care descrieți variabilele de culoare în secțiunea rădăcină. Decizi să eliminați componenta butonului; în acest caz, trebuie să vă amintiți să eliminați și variabilele asociate butonului din fișierul de stiluri comune.

În al doilea rând, aceasta nu este cea mai bună soluție în ceea ce privește performanța. Da, o schimbare de culoare determină doar procesul de revopsire, nu reflux/aspect, acest lucru în sine nu este prea costisitor, dar atunci când faceți unele modificări la cel mai înalt nivel, veți folosi mai multe resurse pentru a verifica întregul arbore decât atunci când acestea schimbările au loc într-o zonă locală mică. Recomand să citiți benchmark-ul de performanță al variabilelor CSS de la Lisi Linhart pentru mai multe detalii.

Pe actualul meu proiect Tispr, echipa și cu mine folosim split și nu dump totul în rădăcină, la nivel înalt doar o paletă și culori funcționale. De asemenea, nu ne este frică de IE11, deoarece această problemă este rezolvată de polifill-ul corespunzător. Doar instalați modulul npm ie11-custom-properties și importați biblioteca în pachetul dvs. JS de aplicație:

 // Use ES6 syntax import "ie11-custom-properties"; // or CommonJS require('ie11-custom-properties');

Sau adăugați modul după eticheta de script:

 <script async src="./node_modules/ie11-custom-properties/ie11CustomProperties.js">

De asemenea, puteți adăuga biblioteca fără npm prin CDN. Lucrarea acestui polyfill se bazează pe faptul că IE11 are suport minim pentru proprietăți personalizate, unde proprietățile pot fi definite și citite pe baza cascadei. Acest lucru nu este posibil cu proprietăți care încep cu liniuțe duble, dar eventual cu o singură liniuță (mecanismul similar cu prefixele de furnizor). Puteți citi mai multe despre acest lucru în documentația depozitului, precum și să vă familiarizați cu unele limite. Alte browsere vor ignora acest polyfill.

Mai jos este o paletă a aplicației web Tispr, precum și controalele funcționalității „etichetă albă” pentru documentele electronice (cum ar fi contracte de utilizator, facturi sau propuneri).

Grilă cu următoarele coloane: culoare, numele culorii, culoare HEX, culoare RGB.
Ghid de stil Tispr: Paleta de culori. (Previzualizare mare)
Componentă de interfață personalizată a selectorului de culori
Tispr Styleguide: Brand Picker pentru funcționalitatea White Label. (Previzualizare mare)

De ce să nu stocați variabilele de culoare pe partea JavaScript?

O altă întrebare rezonabilă: de ce să nu stocați paleta și variabilele funcției în codul JavaScript? Aceasta poate fi, de asemenea, schimbată dinamic și ulterior redefinite culorile prin stiluri inline. Aceasta ar putea fi o opțiune, dar cel mai probabil această abordare ar fi mai puțin optimă, deoarece trebuie să aveți acces la anumite elemente și să le schimbați proprietățile de culoare. Cu variabilele CSS, vei modifica doar o singură proprietate, adică valoarea variabilei.

În JavaScript, nu există funcții native sau API pentru lucrul cu culorile. În Modulul de culoare CSS 5, vor exista multe oportunități de a crea culori derivate sau de a le calcula cumva. Din perspectiva viitorului, proprietățile personalizate CSS sunt mai bogate și mai flexibile decât variabilele JS. De asemenea, cu variabilele JS, nu va exista posibilitatea de a utiliza moștenirea în cascadă și acesta este principalul dezavantaj.

Concluzie

Împărțirea culorilor în trei niveluri (paletă, funcțional și component) vă poate ajuta să fiți mai adaptabil la schimbări și noile cerințe în timp ce lucrați la un proiect. Consider că proprietățile personalizate CSS sunt instrumentul potrivit pentru organizarea împărțirii culorilor - nu contează ce folosiți pentru stil: CSS pur, preprocesoare sau abordare CSS-in-JS.

Am ajuns la această abordare prin propria experiență, dar nu sunt singur. Sara Soueidan a descris în articolul său o abordare similară în care a împărțit variabilele în niveluri globale și componente.

De asemenea, aș dori să vă sugerez să citiți articolul lui Lea Verou în care ea descrie posibile cazuri de aplicare a variabilelor CSS (nu doar din punct de vedere al culorii).