The idea

I saw the site What colour is it? and thought the concept was really cool. For whatever reason, visualization generators pique my interest. I wanted to alter the original to see a wider range of colors, and to play with the attr() function in CSS' ::after psuedo-element. I also wanted to add a slider just to allow the user to tweak the generated color.

See the Pen Time color by Aaron Holmes (@aholmes) on CodePen.

The HTML and CSS

First set the attribute on your element. I decided to call it data-text .

<h1 id="time" data-text="00 : 00 : 00"></h1>

We only need two lines of CSS to get the attribute function to display.

h1::after { display:block; content:attr(data-text); }

Normally the content attribute is set to a static string, but there's also the attr() function that let's you use an attribute value on your element instead.

You can find more information about attr() on MDN.

NOTE: Browser compatibility is sketchy at best. There are some gotchas to be careful of too.

Updating the content with JavaScript

There are no DOM API methods that let us access ::after or ::before psuedo-elements with JavaScript. We can at least use the attr() function in conjunction with the setAttribute() method or dataset property to change the content of the psuedo-elements.

With the HTML element above, here's how we can change the value of the data-text attribute. This change will then be rendered with our CSS rules to display new text in the psuedo-element.

var timeHeader = document.getElementById('time'); var time = "15:30:25"; if (timeHeader.dataset !== undefined) { timeHeader.dataset.text = time; } else { timeHeader.setAttribute('data-text', time); }

Theoretically that should be all we need! With a little more code to set the correct time value on a loop, the site will show a new time every second.

A repaint issue on Chrome version 39.0.2171.95

My experiment didn't go perfectly. I discovered that changing the attribute value does not always trigger a repaint, and thus the new time would not display. I have not figured out exactly what caused this; it was sporadic, and I wonder if it's partly related to how codepen works.

Thankfully there's an easy way to trigger a repaint. It's not exactly the prettiest solution, but it does ensure the new time is displayed each second.

timeHeader.style.display='none'; timeHeader.offsetHeight; timeHeader.style.display='';

A little extra

The original code uses the time values as the hexidecimal values for the background color. A time of 9 hours, 23 minutes, and 40 seconds give you the hex color #092340 .

Given that this will increment the 0th digit for each red, green, and blue hex value, we end up with a similar color for each second, minute, and hour.

If the time value is 09 23 40, then our RGB values are as follows.

Hex Dec Conversion Red 0x09 9 (0 * 16^1) + (9 * 16^0) Green 0x23 35 (2 * 16^1) + (3 * 16^0) Blue 0x40 64 (4 * 16^1) + (0 * 16^0)

After 1 second, blue becomes 65, then 66, 67, 68, and so on. This is a very slow increase!

Additionally, because there are only 24 hours in a day, 60 minutes to an hour, and 60 seconds to a minute, our scale of colors is limited. Red ranges from 0 - 23, green 0 - 59, and blue 0 - 59.

Here's a visualization of all possible red, green, and blue values individually.

Hex Dec Flipped String Red 0x09 9 90 Green 0x23 35 53 Blue 0x40 64 46

To get a wider range of colors, each hexidecimal string value can be flipped. For example, 9 is "09" as a string, and "90" flipped. Here's what our example above looks like with the values flipped.

And here's the range of colors and the pattern in which they occur.