A webalkalmazás készítése a TailwindCSS segítségével nagyszerű, mivel lehetővé teszi, hogy könnyedén megírja az összes stílust, és rendszert biztosít az összetevők konzisztenciájának megőrzéséhez. Ugyanakkor az is fontos, hogy az alkalmazásban használt színekkel összhangban legyen.

Ezt többféleképpen is elérheti:

  1. Kényszerítsen egy stílus útmutatót a fejlesztőknek, hogy ugyanazokat az előre elkészített színeket használják a TailwindCSS-könyvtárból (sajnos előfordulhat, hogy ez nem lehetséges, ha az alkalmazás testreszabott színeket igényel)
  2. Az összes egyéni szín és árnyalat manuális meghatározása a TailwindCSS konfiguráción keresztül (korlátozott felhasználási eset vagy időigényes)
  3. Dinamikus paletta létrehozása korlátozott színkészletből (de hogyan lehet ezt megtenni? És elérhető?)

Ebben a cikkben egy olyan projektet fogok megosztani, amely az utolsó módszert használja a TailwindCSS elérhető színpalettájának létrehozására.

Hogyan határozzunk meg egy palettát

A kerék újrafeltalálásának elkerülése érdekében az „Anyagtervezési dokumentációban” javasolt tematikus módszert választottam. Ez a következőképpen definiált palettaobjektummá válik:

{
  primary: "#006E90",
  on-primary: '#ffffff',
  secondary: "#99C24D",
  on-secondary: '#000000',
  accent: "#F18F01",
  on-accent: '#000000',
  background: "#ffffff",
  on-background: '#000000',
  disabled: "#dadada",
  on-disabled: '#000000',
  success: "#2fa81b",
  on-success: '#000000',
  info: "#0284c7",
  on-info: '#000000',
  warning: "#fdd230",
  on-warning: '#000000',
  error: "#be1931",
  on-error: '#ffffff'
}

Vannak:

  • Tartalomváltozatok: elsődleges, másodlagos, ékezetes,és háttér
  • Állapotváltozatok: letiltva, sikeres, információ, figyelmeztetés és hiba.

Minden változathoz megfelelő kontrasztszín szükséges, amelyet az on-* előtaggal neveznek el. Ha például meghatározunk egy „elsődleges”gombot, a gombon belüli szövegnek „elsődleges” színűnek kell lennie.

Ez a megközelítés közvetlenül megvalósítható a TailwindCSS téma testreszabásában, de ily módon kihagyunk minden árnyalatot ezekhez a színekhez (50, 100, 200, 300, 400, 500, 600, 700, 900), és ha ezeket az árnyalatokat manuálisan adjuk hozzá, nehézkes lenne az egyes árnyalatok kontrasztjait kezelni.

Hogyan készítsünk árnyalatokat

Árnyék létrehozásához szükségünk van egy "szín" nevű apró könyvtárra, amely hasznos módszereket tartalmaz a színek keverésére és manipulálására. A cél az, hogy minden színhez különböző átlátszatlansággal rendelkező árnyalatot állítsunk elő.

Ha közvetlenül használjuk az átlátszatlanságot, akkor a kapott szín nem lesz konzisztens a különböző háttereken, ezért csak a „vizuális átlátszóságot” kell módosítanunk. Az alábbiakban egy példa látható, hogy ez mit jelent:

Az opacitás használatának másik korlátja, hogy csak „világosíthatja” a színt, de nem teheti sötétebbé.

Ennek elérése érdekében a colors könyvtárat használjuk az új árnyalat létrehozására úgy, hogy a kiválasztott átlátszatlanság mellett fehéret keverünk az aktuális színnel, hogy „világosítsuk”, és ugyanígy feketével „sötétítsük”:

const Color = require("color");

const lighten = (clr, val) =>
  Color(clr).mix(Color("white"), val).rgb().string();

const darken = (clr, val) => 
  Color(clr).mix(Color("black"), val).rgb().string();

A val a 0–1 tartományban választott opacitáscsökkentést jelenti, tehát a 0,2 80%-os átlátszóságot jelent a fehérhez vagy a feketéhez képest. Példa a függvények használatára:

lighten("#006E90", 0.2) // rgb(51, 139, 166) or #338ba6

Most létrehozhatunk egy objektumot a TailwindCSS összes szabványos árnyalatával:

// palette[variant] could be the value of primary, secondary, etc..

{
  DEFAULT: palette[variant],
  50: lighten(palette[variant], 0.9),
  100: lighten(palette[variant], 0.8),
  200: lighten(palette[variant], 0.6),
  300: lighten(palette[variant], 0.4),
  400: lighten(palette[variant], 0.2),
  500: palette[variant],
  600: darken(palette[variant], 0.2),
  700: darken(palette[variant], 0.4),
  800: darken(palette[variant], 0.6),
  900: darken(palette[variant], 0.8),
}

Csak egy utolsó problémát kell megoldanunk: ha az árnyalat túl sötét, lehet, hogy a kontrasztváltozat legyen „fehér”, ha pedig túl világos, akkor a kontrasztváltozat legyen „fekete”, különben a palettánk soha nem lesz elérhető.

Hogyan lehet kontrasztváltozatokat generálni?

A könyvtár színe még ebben az esetben is segítségünkre lehet az .isLight() módszerrel, amely a "W3C kontrasztarányról szóló ajánlásán" alapul.

Ezzel a módszerrel beállíthatunk egy feketés értéket, ha az isLight() igaz értéket ad vissza, vagy ha fehéres értéket ad vissza:

Color(palette[shade]).isLight() ? "#000000" : "#ffffff"

Ezt az általunk meghatározott változatok minden egyes árnyalatára alkalmazni kell, így az eredményül kapott objektum valami ilyesmi lehet:

{
  "primary": "...",
  "primary-50": "...",
  ...
  "primary-800": "...",
  "primary-900": "...",
  "on-primary": "...",
  "on-primary-50": "...",
  ...
  "on-primary-800": "...",
  "on-primary-900": "...",
  "secondary": "...",
  "secondary-50": "...",
  ... 
}

Most már láthatja, hogy őrültség lenne manuálisan beírni ezeket a mezőket!

Tehát mi a végső konfiguráció ehhez?

Ha szeretné kipróbálni magát, közzétettem a GitHubon egy React alkalmazást a Vite segítségével, hogy megjelenítse az összes generált árnyalatot:



A tailwind.config.cjs fő konfigurációja a következő:

const Color = require("color");

const lighten = (clr, val) =>
  Color(clr).mix(Color("white"), val).rgb().string();

const darken = (clr, val) => 
  Color(clr).mix(Color("black"), val).rgb().string();

const generateContrasts = (variant, palette) => ({
  [variant]: palette,
  [`on-${variant}`]: Object.keys(palette).reduce(
    (enhancedPalette, shade) => ({
      ...enhancedPalette,
      [shade]: Color(palette[shade]).isLight() ? "#000000" : "#ffffff",
    }),
    {}
  ),
});

const palette = {
  primary: "#006E90",
  secondary: "#99C24D",
  accent: "#F18F01",
  background: "#ffffff",
  disabled: "#dadada",
  success: "#2fa81b",
  info: "#0284c7",
  warning: "#fdd230",
  error: "#be1931",
};

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./src/**/*.{html,js,ts,tsx}"],
  theme: {
    extend: {
      colors: Object.keys(palette).reduce(
        (colors, variant) => ({
          ...colors,
          ...generateContrasts(variant, {
            DEFAULT: palette[variant],
            50: lighten(palette[variant], 0.9),
            100: lighten(palette[variant], 0.8),
            200: lighten(palette[variant], 0.6),
            300: lighten(palette[variant], 0.4),
            400: lighten(palette[variant], 0.2),
            500: palette[variant],
            600: darken(palette[variant], 0.2),
            700: darken(palette[variant], 0.4),
            800: darken(palette[variant], 0.6),
            900: darken(palette[variant], 0.8),
          }),
        }),
        {}
      ),
    },
  },
  plugins: [],
};

Ezzel a konfigurációval csak a fő paletta színét kell meghatároznia a palettaobjektumban, ez minden!

Remélem, mint mindig, ez segíthet Önnek, és szívesen fogadunk minden ezzel kapcsolatos visszajelzést!

Level Up kódolás

Köszönjük, hogy közösségünk tagja vagy! Mielőtt mész:

  • 👏 Tapsolj a történetért és kövesd a szerzőt 👉
  • 📰 Tekintse meg a Level Up Coding kiadvány további tartalmát
  • 💰 Ingyenes kódolási interjú tanfolyam ⇒ Tanfolyam megtekintése
  • 🔔 Kövess minket: Twitter | LinkedIn | "Hírlevél"

🚀👉 Csatlakozzon a Level Up tehetséggondozó csapathoz, és találjon egy csodálatos munkát