×

Простой php генератор цветов css на основе текста

Иногда нужно добавить на простенькую страницу немного цветов для лучшего восприятия информации. И сделать это не просто так, а опираясь на саму информацию.

Описание задачи

Например, вы выводите графики с заранее неизвестным количеством столбцов, линий или секторов диаграмы. Сохранять какие-то заранее определённые цвета в коде некрасиво, особенно при большом объёме данных. Нужно как-то генерировать эти цвета «на лету».

Нередко нужно еще не просто сгенерировать цвет, а сделать это предсказуемым образом. Так чтобы определённому объекту всегда соответствовал предсказуемый цвет. В случае с графиками, это полезно чтобы указать цвета в легенде рядом с основными данными. Но это может пригодиться и для подсвечивания ников в чате или еще чего-нибудь подобного.

Как можно задать цвет в css?

В css есть разные способы задать цвета. Можно использовать текстовые названия из английского языка. Например вот так:

.text{
   background-color: black;
   color: darkgrey;
   border-bottom: 3px solid aliceblue;
}

Получим вот такой текст.

Такой способ задания цвета сложно автоматизировать. Разве что перебором массива заранее заданных цветов и запоминанием индекса нужного цвета в этом массиве. Но это плохое решение.

Можно использовать цвета rgb или rgba. С ними предыдущий пример выглядел бы вот так (я добавил еще и альфа канал в color для наглядности):

.text{
   background-color: rgb(0,0,0);
   color: rgba(169, 169, 169, 1);
   border-bottom: 3px solid rgb(240, 248, 255);
}

Текст будет выглядеть также.

Это более удобный вариант. Я часто его использую, в сочетании с генератором случайных чисел. Но у этого решения есть минус – сложно сделать цвет предсказуемым. Только если сохранять его где-то, но это нарушает изначальную идею о том, чтобы цвет нигде не хранился, а подбирался по заранее известному правилу.

Есть еще аналогичный вариант с цветами в формате HSL и HSLA, но он ничем не отличается от rgb.

Самый простой способ задать предсказуемый цвет

Нам поможет шестнадцатеричное (HEX) представление цвета. Оно является самым популярным в сети. С ним предыдущий пример выглядел бы вот так (чёрный я намерено не сокращал, для наглядности.):

.text{
   background-color: #000000;
   color: #a9a9a9;
   border-bottom: 3px solid #f0f8ff;
}

Тот же текст.

Остаётся только получить шестнадцатеричное число. Если у ваших объектов на графике есть какое-то десятичное представление, то можно использовать php функцию dechex

$hex = dechex($integer);

Но гораздо более универсальным решением будет использовать md5 хэш от любой строки из объекта данных. Этой строкой может быть название линии, колонки, или сегмента, или её ID в базе данных и вообще что угодно (даже ник в чате). Вот как происходит генерация цвета:

$backgroundColor = '#' . substr(md5($string), 0, 6);
$color = '#' . substr(md5($string), 5, 6);
$borderBottomColor = '#' . substr(md5($string), 11, 6);

Md5 хэш представляет собой последовательность из 32 шестнадцатеричных цифр. Для генерации цвета фона мы берём первые 6 символов из хэша, для основного цвета текста следующие 6 символов, и аналогично для границы снизу. Это абсолютно предсказуемый результат, который можно повторить в любом месте программы не запоминая значения этих цветов. Главное знать правило, по которому генерируется цвет (нужно не забывать описывать это правило в документации)

Мало того, необязательно сдвигать строку на 6 символов, даже если сдвинуть позицию в строке для следующего цвета на один символ, то цвет уже будет другим. Ну и для более серьёзной разницы в цветах можно использовать сокращённую запись цвета из трёх символов.

Как добавить эти цвета на страницу?

Самым простым способом добавить эти цвета на страницу будет inline css в самих тегах.

<p style="background-color: <?=$backgroundColor?>; color: <?=$color?>; border-bottom: 3px solid <?=$borderBottomColor?>;">
   Текст
</p>

Но это некрасивый вариант, потому что такие цвета потом сложно переопределить (если вдруг это понадобится). Лучше генерировать в php тег style и добавить его на страницу.

<style>
   .text{
      background-color: <?=$backgroundColor?>; 
      color: <?=$color?>; 
      border-bottom: 3px solid <?=$borderBottomColor?>;">
   }
</style>

Можно реализовать тоже самое в javascript и оттуда менять стили нужных элементов. Но это уже тема для другой записи.

Задача решена.

logo