Да си направим красиви градиенти с помощта на CSS

Оригиналът е на Joshua Comeau

2
633

Да погледнем този линеен градиент, създаден с помощта на CSS, който се променя от чисто жълт до чисто син цвят:

Забелязахте ли, че в центъра той изглежда блед и някак мръсен?

Този ефект известният графичен дизайнер Ерик Кенеди нарече „Мъртвата зона на сивото„. Ако ни изберете по-внимателно цветовете за своите градиенти, то в градиентите, направени с помощта на CSS обикновено възниква именно такава безцветна част в средата.

Оказа се, че е възможно изцяло да избегнем и да се избавим от тази мъртва зона на сивото. В тази статия ще покажа защо възниква този ефект и как можем да използваме теорията на цветовете за създаването на наситени и ярки градиенти, които изглеждат много добре в цялата си дължина.

Пресмятането на градиентите

Задавали ли сте си въпроса, как конкретно работи алгоритъмът linear-gradient при CSS? Как се пресмята конкретното значение на цветовете за всеки пиксел от спектъра?

Ще обясня. Алгоритъмът го изчислява, като взема математически средното значение за всеки един от трите цветови канала: Red, Green и Blue.

 

В оригинала изображенията са интерактивни

В цветовото пространство RGB ние създаваме различни цветове чрез смесване на трите основни канала – червения, зеления и синия. Всеки един канал има диапазон от значения от 0 до 255.

Ако увеличим до максимум значението на всичките три канала – 255 / 255 / 255, ще получим чисто бял цвят. Ако зададем на всеки канал 0, ще получим черен – отсъствие на цвят.

От друга страна, ако и на трите канала дадем еднакво значение, то резултатът винаги ще бъде сив цвят с различни оттенъци.

В показания по-горе пример на градиент ние започваме с чисто жълт цвят (255/255/0). При преместването по градиента започваме да добавяме син цвят (0/0/255). И когато достигнем средата, ние махаме половината от жълтия и добавяме половината от синия.

С други думи и трите канала по средата имат еднакво значение от 127,5. Това е сив цвят.

На мен ми изглежда твърде странно, че средното между синьото и жълтото може да бъде сиво. Когато смесим два много наситени цвята, неочаквано получаваме нещо съвсем бледо. Тук липсва метод за смесването само на пигмента, като наситеността би трябвало да остане същата…

Алтернативните цветови модели

Има редица най-различни начини и методи за задаване на цветовете. Дотук използвахме само R/G/B и честно казано, този цветови модел не е много удачен.

Нека да се спрем върху HSL цветовия модел.

HSL означава Hue / Saturation / Lightness или Отенък / Наситеност /  Яркост. Ако сте използвали селектор на цветовете, то най-вероятно сте работили именно с това цветово пространство.

Ето какво означава всеки параметър:

  • Hue (Отенък, понякога Нюанс) – контролира къде в цветовата скала се намира пигментът
  • Saturation (Наситеност) – регулира интензивността на цвета
  • Lightness (Яркост) – управлява колко светъл или тъмен да бъде съответния цвят

Лично на мен този метод ми изглежда много по-интуитивен начин за възприемане на цветовете.

Но ето какво е наистина вълшебно: какво ще стане, ако вместо да използваме значенията в RGB цветовото пространство в нашите градиенти започнем да употребяваме параметрите на HSL?

Веднага се вижда, че мъртва зона повече няма, понеже този път не използваме R/G/B параметрите, а H/S/L значенията.

Цветовете в началото и края имат еднаква наситеност яркост, понеже единственото което се променя е отенъкът (Hue). Останалите два параметъра не се променят (100, 50). В крайна сметка се получава така, че ние просто се придвижваме по скалата на цветовете.

Ето още един пример, в който използваме смесване на цветове с различна наситеност и осветеност. За сравнение са показани и цветовете при използването на RGB пространството:

Разликата е очевидна, нали?

Но и HSL далеч не винаги е най-добрият цветови модел за всяка ситуация. При използването на това цветово пространство често пъти се получават твърде ярки и живи градиенти, понеже не са взети предвид особеностите на човешкото възприятие.

Според HSL цветовия модел, следните двата квадрата имат еднаква яркост:

Хората не винаги възприемат цветовете еднакво. Повечето хора биха казали че жълтият цвят по-горе изглежда много по-светъл в сравнение със синия, въпреки еднаквото значение на яркостта. Това е така, защото HSL моделът не включва информация за това как хората възприемат цветовете. Този модел се базира на чиста физика – енергия и дължини на вълните, което от друга страна си има своите положителни черти.

За щастие има редица други цветови модели, които вземат предвид човешкото възприемане на цветовете. Така например, HCL моделът много прилича на HSL, но е моделиран по такъв начин, че отчита особеностите на човешкото зрение:

Кой в такъв случай е най-добрият цветови модел? Това силно зависи от ефекта, който искате да постигнете. Аз обичам да експериментирам с най-различни цветови модели, за да намеря оптималното решение за конкретния градиент.

Да приложим наученото на практика

Имам както добри, така и лоши новини. Да започнем с лошите.

CSS не ни дава възможност за избор на цветови модел при изчисляването на градиентите. Това означава, че ние не можем да изберем HSL интерполацията за конкретен градиент, поне засега. Доколкото ми е известно CSS Images Level 4 дава възможност за оказване на начина за интерполиране на цветовете, само че не се поддържа от всички браузъри.

Има и добри новини: можем да постъпим хитро и да заобиколим тези ограничения.

Градиентите в CSS не са ограничени до използването само на два цвята. Могат да бъдат използвани 3, а защо не 10 или дори 100 цвята.

В началото ще трябва ръчно да изчислим набора междинни цветове. Можем да направим това с помощта на JavaScript, за да можем да използваме необходимия в конкретен случай цветови модел. Това най-лесно може да стане с помощта на полезната библиотека chroma.js или някоя друга.

След това взимаме този комплект от цветове и подаваме всяко от техните значения на функцията за градиент при CSS:

.box {
  background-image: linear-gradient(
    to right,
    #ffff00,
    #f8ea47,
    #f0d465,
    #f0d465,
    #e7bf7c,
    #ddaa8f,
    #d095a1,
    #c280b2,
    #b26cc2,
    #9d56d2,
    #8440e1,
    #6028f0,
    #0000ff
  )
}

Тук използваме линейни градиенти, но същият трик работи с радиални и конични градиенти.

Но чакайте малко, нима CSS енджина не използва RGB интерполация за изчисляване на цветовото пространство между всеки един между указаните цветове? Ако ние не подадем стотици цветове, необходими за всеки един отделен пиксел, то тогава енджинът очевидно интерполира тези междинни значения.

Това е истина, но няма особено значение.

Когато два цвята са много близки един до друг на практика не е важно какъв точно цветови модел се използва. В този случай градиентът се получава приблизително еднакъв. Дотолкова приблизително, че човешкото око не може да открие разликите.

Ето един градиент в който се използват два приблизително еднакви цвята:

Цветовете дотолкова си приличат и са близки, че RGB интерполацията не може да развали изображенията.

И така нашият хитър трик е в това, да се генерира комплект от междинни точки от избран цветови модел, които след това да се подадат като параметри във функцията за градиентна CSS. Самият CSS енджин използва RGB интерполация, но това не оказва влияние на крайния резултат. Всъщност оказва влияние, но това не може да бъде забелязан от хората.

Остана най-интересното. Нека да кажем няколко думи как става автоматичното генериране на подобни градиенти.

Генераторът на градиенти

Аз създадох софтуерен инструмент, който дава възможност за генериране на разкошни и красиви градиенти, които могат да се използват в CSS:

Аз съм във възторг от този инструмент. В него се използват всички елементи, за които стана дума в тази статия, както и някои допълнителни трикове по разпределението на цветовете.

Можете да настройвате всички цветове, докато не се получи необходимия резултат, а след това да копирате и вмъкнете в своя код фрагмента от CSS кода, който се показва в долния десен ъгъл. Засега инструментът генерира само линейни градиенти, но всеки може да копира и постави комплекта от цветове в CSS и без проблем да ги използва в радиалните и коничните градиенти!

 

Абонирай се
Извести ме за
guest
2 Коментара
стари
нови
Отзиви
Всички коментари