Using Time as a Color Generator

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.

HexDecConversion
Red0x099(0 * 16^1) + (9 * 16^0)
Green0x2335(2 * 16^1) + (3 * 16^0)
Blue0x4064(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.

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.
HexDecFlipped String
Red0x09990
Green0x233553
Blue0x406446

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