Last updated at Wed, 25 Oct 2017 14:32:13 GMT

As a part of our work to make user-defined tags accessible, we have used a color picker to allow users to select appropriate colors for the different tags they create. After looking around at some existing color pickers, we could not find any suitable implementations. Our requirements were something which could be both usable and visually appealing. So we ended up with our own…

As a first step, we searched for a slick looking visual color picker which would allow for quick color selection. The simplest one we stumbled across was a table of hue and luminescence. We even considered some non-traditional looking as DMC color chart, but eventually got inspired by the hexagon layout from VisiBone (these guys are selling printed color charts).

We considered two approaches to implement the color picker. The first one is to create an image of the color space and allow the user to select a color by clicking on the image. To do this we took the cursor position against the image and retrieve the pixel color selected. This can be done in a number of ways. Either to save the image internally as a data structure, or upload the image in a canvas and retrieve canvas pixel color. An alternative approach is to define a set of colored CSS tiles and arrange them in using pure HTML. Using this approach, catching mouse clicks on the tiles is then piece a cake.

Which one is better? Hard to say. CSS/Javascript is more elegant, but for a complicated color space a picture-based is probably more feasible.

Hexagon layout in CSS is a challenging task (but we do like a challange 🙂 . Also CSS does allow you to stylize blocks in nontraditional shapes (referred to slants). And it is not overly complicated.

Firstly, we start with a simple hexagon layout. The hexagon is composed of two halves, hex0 and hex1. Both shares a common style plc. Even lines require alignment achieved by spc.

.plc { float: left; height: 0; line-height: 0;
  border-style: solid; width: 25px; margin-right: -5px;
  margin-left: -5px; }
.hex0 { border-width: 0 12px 21px; margin-top: 1px; }
.hex1 { border-width: 21px 12px 0; }
.spc { width: 10px; height: 12px; float: left; }
.clr { clear: both; }

A single hexagon therefore consists of two divs:

<div class="spc"></div>
<div class="plc hex0" style="border-color: #f00 transparent">
</div>
<div class="clr"></div>
<div class="spc"></div>
<div class="plc hex1" style="border-color: #f00 transparent">
</div>

As a next step we chain hexagons in lines:

<div class="spc"></div>
<div class="plc hex0" style="border-color: #f00 transparent"></div>
<div class="plc hex1" style="border-color: #f00 transparent"></div>
<div class="plc hex0" style="border-color: #f00 transparent"></div>
<div class="plc hex1" style="border-color: #f00 transparent"></div>
<div class="clr"></div>
<div class="spc"></div>
<div class="plc hex1" style="border-color: #f00 transparent"></div>
<div class="plc hex0" style="border-color: #f00 transparent"></div>
<div class="plc hex1" style="border-color: #f00 transparent"></div>
<div class="plc hex0" style="border-color: #f00 transparent"></div>
<div class="clr"></div>
<div class="spc"></div>
<div class="plc hex0" style="border-color: #f00 transparent"></div>
<div class="plc hex1" style="border-color: #f00 transparent"></div>
<div class="plc hex0" style="border-color: #f00 transparent"></div>
<div class="plc hex1" style="border-color: #f00 transparent"></div>
<div class="clr"></div>
<div class="spc"></div>
<div class="plc hex1" style="border-color: #f00 transparent"></div>
<div class="plc hex0" style="border-color: #f00 transparent"></div>
<div class="plc hex1" style="border-color: #f00 transparent"></div>
<div class="plc hex0" style="border-color: #f00 transparent"></div>

We are almost done! Let’s define smaller hexagons and all the colors:

.plc0 { float: left; height: 0; line-height: 0;
  border-style: solid; width: 6px; margin-right: -1px;
  margin-left: -1px; }
.hex20 { border-width: 0 3px 5px; margin-top: 1px; }
.hex10 { border-width: 5px 3px 0; }