Tworzenie schematu kolorów

Podstawowy przegląd sposobu tworzenia dynamicznego i konfigurowalnego schematu kolorów

W tym poście chcę podzielić się sposobami zarządzania wieloma schematami kolorów w kodzie CSS. Wypróbuj wersję demonstracyjną

Demo

Jeśli wolisz film, oto wersja tego posta w YouTube:

Omówienie

Utworzymy system kolorów z uwzględnieniem dostępności za pomocą właściwości niestandardowych i elementu calc(), aby strona internetowa dostosowywała się do preferencji użytkownika, a jednocześnie minimalizowała konieczność tworzenia. Zaczynamy od podstawowego koloru marki i tworzymy na jego podstawie system wariantów: 2 kolory tekstu, 4 kolory powierzchni i pasujący cień.

W tym przewodniku na początku definiujemy wszystkie kolory dla każdego schematu kolorów. Do zmiany strony są używane dopiero na samym końcu.

Marka

Często kolor marki jest już ustalony i przesyłany jako hex lub rgb. Ta praca konkursowa w zakresie interfejsu GUI ma podstawowy kolor marki #0af. Po pierwsze, w przypadku tego systemu kolorów wartość szesnastkowa musi zostać przekonwertowana na hsl.

* {
  --brand: #0af;
  --brand: hsl(200 100% 50%);
}

Aby umożliwić przyciemnienie lub rozjaśnienie koloru marki, np. o 20%, 3 kanały wartości koloru hsl muszą zostać wyodrębnione w osobne właściwości niestandardowe, tak jak w tym przykładzie:

* {
  --brand-hue: 200;
  --brand-saturation: 100%;
  --brand-lightness: 50%;
}

CSS może wykonywać operacje na tych właściwościach kolorów, na przykład calc(var(--brand-lightness) - 20%), aby zmniejszyć wartość jasności o 20%. Jest to podstawa tworzenia schematu kolorów, ponieważ CSS może zachować wszystkie kolory w tej samej rodzinie odcieni, dostosowując nasycenie i jasność hsl.

Jasny motyw

Każda wersja koloru będzie oznaczona odpowiednim schematem. W tym przypadku każdy kolor będzie miał dołączony znak -light.

podgląd wyników końcowych w jasnym motywie

Marka

Zaczynając od koloru marki, odtworzyliśmy go, owijając właściwości niestandardowe --brand-hue, --brand-saturation i --brand-lightness w nawiasach funkcji hsl () bez żadnych obliczeń:

* {
  --brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
}

Kolory tekstu

Następnie musisz dobrać kolory tekstu. W jasnym motywie tekst powinien być bardzo ciemny. Zwróć uwagę, że jasność tych kolorów jest niska i nie przekracza 50%.

* {
  --text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
  --text2-light: hsl(var(--brand-hue) 30% 30%);
}

--text1-light, ponieważ jest bardzo ciemny przy jasności 10%, zachowuje nasycenie 100%, dzięki czemu kolor marki może przebijać przez ciemny granat.

--text2-light nie jest tak ciemny jak pierwszy kolor, co jest dobre, bo jest to kolor dodatkowy. Jest też mniej nasycony.

Kolory powierzchni

Kolory powierzchni to tła, obramowania i inne powierzchnie ozdobne, na których znajduje się tekst. W jasnym motywie są to jasne kolory, w przeciwieństwie do kolorów tekstu, które są ciemne. Aby utworzyć jasne kolory za pomocą modelu hsl, użyjemy wyższych wartości procentowych w trzeciej wartości jasności. Zmniejszym też nasycenie, aby jasne szarości nie były zbyt przyciemnione.

* {
  --surface1-light: hsl(var(--brand-hue) 25% 90%);
  --surface2-light: hsl(var(--brand-hue) 20% 99%);
  --surface3-light: hsl(var(--brand-hue) 20% 92%);
  --surface4-light: hsl(var(--brand-hue) 20% 85%);
}

Utworzono 4 kolory powierzchni, ponieważ kolory dekoracyjne wymagają zwykle większej liczby wariantów, np. w przypadku interaktywnych momentów, takich jak :focus lub :hover, lub w celu stworzenia wyglądu warstw papieru. W takich sytuacjach warto zastosować przejście z --surface2-light na --surface3-light, aby po najechaniu kursorem na ikonę zwiększyć kontrast (z jasności 99% na 92%, czyli ściemnienie).

Cienie

Cienie w schemacie kolorów są niesamowite, ale dodają efektowi naturalności i pomagają wyróżnić go na tle nierealistycznych cieni na czarnym tle. Aby to zrobić, kolor cienia będzie korzystać z właściwości niestandardowej odcień, będzie nieco nasycony, ale nadal bardzo ciemny. Zasadniczo tworzymy bardzo ciemny cień o lekko niebieskim zabarwieniu.

* {
  --surface-shadow-light: var(--brand-hue) 10% 20%;
  --shadow-strength-light: .02;
}

Funkcja --surface-shadow-light nie jest ujęta w funkcji hsl. Dzieje się tak, ponieważ wartość --shadow-strength zostanie połączona, aby uzyskać pewną przezroczystość, a CSS potrzebuje tych elementów, aby przeprowadzić obliczenia. Aby dowiedzieć się więcej, przejdź do sekcji o promienistym cieniu.

Jasne kolory razem

Nie musisz szukać, jak powstały jasne kolory, ponieważ wszystkie są w jednym miejscu w pliku CSS.

* {
  --brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
  --text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
  --text2-light: hsl(var(--brand-hue) 30% 30%);
  --surface1-light: hsl(var(--brand-hue) 25% 90%);
  --surface2-light: hsl(var(--brand-hue) 20% 99%);
  --surface3-light: hsl(var(--brand-hue) 20% 92%);
  --surface4-light: hsl(var(--brand-hue) 20% 85%);
  --surface-shadow-light: var(--brand-hue) 10% calc(var(--brand-lightness) / 5);
  --shadow-strength-light: .02;
}
Zrzut ekranu pokazujący wszystkie jasne kolory
Sandbox na CodePen

Ciemny motyw

Większość marek nie zaczyna od ciemnego motywu. Jest to wariant ich głównego motywu, który jest zwykle jaśniejszy. Z kolei użytkownicy często wybierają ciemny motyw w różnych kontekstach, np. w nocy. Z tych powodów w przypadku ciemnych motywów należy pamiętać o 2 rzeczach:

  1. Użytkownicy będą używać tego motywu w ciemności, więc przetestuj go w ciemności.
  2. Kolory powinny być stonowane, aby nie wibrowały na ekranie z powodu zbyt intensywnego koloru.

podgląd końcowego wyniku ciemnego motywu

Marka

Jasny motyw używa 3 wartości kanałów kolorów sRGB marki bez zmian. Motyw ciemny nie używa tych wartości. Nasycenie jest zmniejszone o połowę, a jasność o 50%.

* {
  --brand-dark: hsl(
    var(--brand-hue)
    calc(var(--brand-saturation) / 2)
    calc(var(--brand-lightness) / 1.5)
  );
}

Kolory tekstu

W ciemnym motywie kolory tekstu powinny być jasne. Te kolory mają wysokie wartości jasności, co powoduje, że są one bliższe bieli.

* {
  --text1-dark: hsl(var(--brand-hue) 15% 85%);
  --text2-dark: hsl(var(--brand-hue) 5% 65%);
}

Kolory powierzchni

W ciemnym motywie kolory powierzchni powinny być ciemne. Te kolory mają niską jasność i nasycenie, przy czym pierwsza powierzchnia jest najciemniejsza (10%).

* {
  --surface1-dark: hsl(var(--brand-hue) 10% 10%);
  --surface2-dark: hsl(var(--brand-hue) 10% 15%);
  --surface3-dark: hsl(var(--brand-hue) 5%  20%);
  --surface4-dark: hsl(var(--brand-hue) 5% 25%);
}

Cienie

W ciemnym motywie cienie mogą być bardzo trudne do zauważenia. To ma sens, ponieważ trudno jest przyciemnić coś, co jest już dość ciemne. Właśnie w tym przypadku --shadow-strength-dark jest bardzo przydatne, ponieważ pozwala przyciemnić cienie przez zmianę jednej zmiennej.

* {
  --surface-shadow-dark: var(--brand-hue) 50% 3%;
  --shadow-strength-dark: .8;
}

Zwróć też uwagę na nasycenie cienia. Czy widzisz kolory, gdy patrzysz na interfejs? Spróbuj usunąć nasycenie w devtools.

Wszystkie ciemne kolory

* {
  --brand-dark: hsl(var(--brand-hue) calc(var(--brand-saturation) / 2) calc(var(--brand-lightness) / 1.5));
  --text1-dark: hsl(var(--brand-hue) 15% 85%);
  --text2-dark: hsl(var(--brand-hue) 5% 65%);
  --surface1-dark: hsl(var(--brand-hue) 10% 10%);
  --surface2-dark: hsl(var(--brand-hue) 10% 15%);
  --surface3-dark: hsl(var(--brand-hue) 5%  20%);
  --surface4-dark: hsl(var(--brand-hue) 5% 25%);
  --surface-shadow-dark: var(--brand-hue) 50% 3%;
  --shadow-strength-dark: .8;
}
Zrzut ekranu pokazujący wszystkie ciemne kolory
Sandbox na CodePen

Motyw przyciemniony

Ten schemat kolorów opiera się na jasności i nasycenie. Należy zastosować wystarczającą nasycenie, aby kolor był widoczny, ale jednocześnie nie przekraczać wartości kontrastu, ponieważ obraz ma być ciemny i mieć niski kontrast.

podgląd końcowych wyników motywu przyciemnionego;

Marka

* {
  --brand-dim: hsl(
    var(--brand-hue)
    calc(var(--brand-saturation) / 1.25)
    calc(var(--brand-lightness) / 1.25)
  );
}

Kolory tekstu

* {
  --text1-dim: hsl(var(--brand-hue) 15% 75%);
  --text2-dim: hsl(var(--brand-hue) 10% 61%);
}

Kolory powierzchni

* {
  --surface1-dim: hsl(var(--brand-hue) 10% 20%);
  --surface2-dim: hsl(var(--brand-hue) 10% 25%);
  --surface3-dim: hsl(var(--brand-hue) 5%  30%);
  --surface4-dim: hsl(var(--brand-hue) 5% 35%);
}

Cienie

* {
  --surface-shadow-dim: var(--brand-hue) 30% 13%;
  --shadow-strength-dim: .2;
}

przyciemniać wszystkie kolory,

* {
  --brand-dim: hsl(var(--brand-hue) calc(var(--brand-saturation) / 1.25) calc(var(--brand-lightness) / 1.25));
  --text1-dim: hsl(var(--brand-hue) 15% 75%);
  --text2-dim: hsl(var(--brand-hue) 10% 61%);
  --surface1-dim: hsl(var(--brand-hue) 10% 20%);
  --surface2-dim: hsl(var(--brand-hue) 10% 25%);
  --surface3-dim: hsl(var(--brand-hue) 5%  30%);
  --surface4-dim: hsl(var(--brand-hue) 5% 35%);
  --surface-shadow-dim: var(--brand-hue) 30% 13%;
  --shadow-strength-dim: .2;
}
Zrzut ekranu pokazujący przyciemnione kolory
Sandbox na CodePen

Dostępne kolory

Zwróć uwagę, że najciemniejszy kolor tekstu to 65%, a najjaśniejszy kolor ciemnych powierzchni to 25%. To 40% różnicy w jasności pomiędzy nimi. W jasnym motywie jest 55% wolnego miejsca. Utrzymywanie różnic jasności między tekstem a kolorami powierzchni na poziomie około 40–50% może pomóc w zachowaniu wysokiego współczynnika kontrastu kolorów, a także stanowić subtelny element do regulacji w przypadku niskich wyników.

Nazywam to „bump bump til ya pass”, co oznacza interakcję polegającą na zwiększaniu wartości jasności, aż narzędzie wskaże, że jestem na pasie.

Naciśnij Shift + strzałka w dół, aby zmniejszyć jasność i zwiększyć kontrast, aż do przejścia.

Wszystkie motywy utworzone w ramach tego wyzwania spełniają kryteria kontrastu. Schemat stonowanych kolorów ma najmniejszy kontrast, ale nadal spełnia minimalne wymagania. Aby ułatwić innym członkom zespołu korzystanie z dobrych kolorów o wysokim kontraście, warto utworzyć nazwę klasy, która łączy kolor powierzchni z dostępnym kolorem tekstu.

.surface1 {
  background-color: var(--surface1);
  color: var(--text2);
}

.surface2 {
  background-color: var(--surface2);
  color: var(--text2);
}

.surface3 {
  background-color: var(--surface3);
  color: var(--text1);
}

.surface4 {
  background-color: var(--surface4);
  color: var(--text1);
}
Zrzut ekranu pokazujący łączenie ciemnej powierzchni z tekstem
Zrzut ekranu z połączeniem obrazu z tekstem w ciemnym tle z VisBug

Rad Shadow

Motywy korzystają z klasy pomocniczej o nazwie .rad-shadow. Ten cień został wygenerowany za pomocą narzędzia Gładki cień, które bardzo sobie cenię. Użyłem wygenerowanego fragmentu kodu i dostosowałem go do własnych kolorów oraz obliczeń stopnia krycia. Celem było stworzenie cienia, który można dostosować w ramach każdego schematu kolorów.

każda z nich obok siebie

Aby to osiągnąć, dla każdego schematu kolorów utworzyłem 2 zmienne: kolor cienia i natężenie cienia. Kolor służy do regulacji nasycenia i ciemności, a siła do łatwego zwiększania intensywności cieni w przypadku ciemnego schematu kolorów. Otrzymany wynik wyglądał tak.

:root {
  --surface-shadow-light: var(--brand-hue) 10% 20%;
  --shadow-strength-light: .02;
}

.rad-shadow {
  box-shadow:
    0 2.8px 2.2px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
    0 6.7px 5.3px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .01)),
    0 12.5px 10px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
    0 22.3px 17.9px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
    0 41.8px 33.4px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
    0 100px 80px hsl(var(--surface-shadow) / var(--shadow-strength))
  ;
}

Jeśli chciałbym pójść dalej z cieniem w swojej palecie kolorów, uczynię kąty cienia stałym elementem projektu, ponieważ kierunek światła powinien być taki sam dla wszystkich cieni w projekcie.

Korzystanie ze schematów kolorów

Po zdefiniowaniu kolorów należy je przekształcić w właściwości niezależne od schematu. Chodzi o to, że jako autor projektu schematu kolorów w kodzie CSS rzadko trzeba mieć dostęp do wartości konkretnego schematu kolorów. Chcę ułatwić Ci pozostawanie w ramach tematu.

Aby to osiągnąć, schemat kolorów powinien być używany wyłącznie za pomocą ogólnych właściwości niestandardowych, które zdefiniujemy za chwilę. Dzięki temu osoby korzystające ze zmiennych projektu nie muszą się martwić o to, jaki schemat kolorów jest aktualnie ustawiony. Wystarczy, że użyją kolorów powierzchni i tekstu. Zamiast color: var(--text1-light) używaj color: var(--text1). Wszystkie dostosowania i obracanie kolorów są wykonywane na dużo wyższym poziomie w CSS.

W tym bloku kodu style łączące jasny motyw łączą ogólną właściwość niestandardową z kolorami określonymi w jasnym motywie. Teraz wszystkie zastosowania var(--brand) będą używać jasnego koloru marki.

Jasny motyw (automatyczny)

:root {
  color-scheme: light;
  --brand: var(--brand-light);
  --text1: var(--text1-light);
  --text2: var(--text2-light);
  --surface1: var(--surface1-light);
  --surface2: var(--surface2-light);
  --surface3: var(--surface3-light);
  --surface4: var(--surface4-light);
  --surface-shadow: var(--surface-shadow-light);
  --shadow-strength: var(--shadow-strength-light);
}

Witryna używa teraz jasnego motywu. To bardzo przyjemny moment. Zobaczmy jeszcze kilka przykładów użycia zdefiniowanych kolorów w innych kontekstach schematu kolorów.

Ciemny motyw (automatyczny)

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;

    --brand: var(--brand-dark);
    --text1: var(--text1-dark);
    --text2: var(--text2-dark);
    --surface1: var(--surface1-dark);
    --surface2: var(--surface2-dark);
    --surface3: var(--surface3-dark);
    --surface4: var(--surface4-dark);
    --surface-shadow: var(--surface-shadow-dark);
    --shadow-strength: var(--shadow-strength-dark);
  }
}

Jasny motyw

[color-scheme="light"] {
  color-scheme: light;

  --brand: var(--brand-light);
  --text1: var(--text1-light);
  --text2: var(--text2-light);
  --surface1: var(--surface1-light);
  --surface2: var(--surface2-light);
  --surface3: var(--surface3-light);
  --surface4: var(--surface4-light);
  --surface-shadow: var(--surface-shadow-light);
  --shadow-strength: var(--shadow-strength-light);
}

Ciemny motyw

[color-scheme="dark"] {
  color-scheme: dark;

  --brand: var(--brand-dark);
  --text1: var(--text1-dark);
  --text2: var(--text2-dark);
  --surface1: var(--surface1-dark);
  --surface2: var(--surface2-dark);
  --surface3: var(--surface3-dark);
  --surface4: var(--surface4-dark);
  --surface-shadow: var(--surface-shadow-dark);
  --shadow-strength: var(--shadow-strength-dark);
}

Motyw przyciemniony

[color-scheme="dim"] {
  color-scheme: dark;

  --brand: var(--brand-dim);
  --text1: var(--text1-dim);
  --text2: var(--text2-dim);
  --surface1: var(--surface1-dim);
  --surface2: var(--surface2-dim);
  --surface3: var(--surface3-dim);
  --surface4: var(--surface4-dim);
  --surface-shadow: var(--surface-shadow-dim);
  --shadow-strength: var(--shadow-strength-dim);
}

W tej chwili autorzy mogą dowolnie korzystać z dostępnych schematów kolorów ogólnych i nie muszą się już martwić o motywy.

Podsumowanie

Teraz, gdy już wiesz, jak to zrobić, jak Ty to zrobisz? 🙂

Zróżnicujemy nasze podejścia i poznamy wszystkie sposoby tworzenia stron internetowych. Utwórz Codepen lub prześlij własne demo, tweetuj je, a ja dodam je do sekcji Remixe społeczności poniżej.

Źródło

Remixy społeczności – @chris-kruining dodał suwak odcienia, kolory stanu i tryby kontrastu dla no-preference, moreless: demo.