Expert Ready, Set, Code!


The Backstory

My love for CSS all started with CSS Zen Garden. When I was new to writing CSS, I was blown away with how the same HTML could be styled so many distinctly different ways.

As I spent more time in the wonderful world of web development, I grew to be a fan of unconventional, experimental, and clever CSS. As expected, I ran across a handful of neat projects along the way. From creating impressive CSS digital paintings, art using A Single Div, to colorful patterns—my love for CSS continued to grow.

In addition to the more experimental use cases—I’ve also had the pleasure of discovering a TON of practical articles on CSS. One in particular that was incredibly helpful was an article titled “The 30 CSS Selectors You Must Memorize“. Not only did this open up a whole new world of CSS hooks to try—it also indicated browser compatibility (which was a bit chaotic at the time). This is also when I first discovered the unbelievable power of pseudo classes (::before/::after).

The Challenge

Fast forward to a few weeks ago when I was presented with an unconventional concept of creating a pricing widget that leveraged a range input. The basic idea would be to swap out content based on the input value. My only requirement was to make a proof of concept to get a feel for how it would work.

Without hesitation I did the first thing most developers do… fire off some obscure Google searches hoping to not have to reinvent the wheel. While the different libraries I found (noUiSlider, rangeslider.js) were neat—they were not quite what I was hoping for or were overkill.

Close but not quite right.

It became abundantly clear I needed to take a step back and distill the task at hand down to the basics: show/hide a set of divs based on an input value.

The initial idea that came to mind was to write a basic function that would set a data-attribute value that would fire with an onChange event on the input. As it turns out—this was incredibly easy and the CSS required was minimal. The gist of the CSS is defaulting the content to display: none and set the specific message to display: block based on the data-message value matched the correct message content.

.message-content {
  display: none;
#message[data-message="1"] .message-content--1 {
  display: block;
#message[data-message="2"] .message-content--2 {
  display: block;

Style The Input

The next step was to style out the input[type=”range”] itself. Up until this point I have rarely used this input type and was not familiar with what my options were for customizing this input type. Luckily for me I stumbled on another set of great articles and resources to help generate some styles!

Ultimately we decided this was a pretty terrible UX pattern. The overall feel was a gimmicky and more cumbersome variation of tabs or a carousel. Not only that—but accessibility had yet to be figured out and it was difficult to compare features side by side.

Moral of the story

Don’t be afraid to take a few moments to explore some ideas out of left field. They could be end up being terrible solutions—but I’m willing to bet that you’ll likely learn a thing or two and find a lot of great resources that can be leveraged in future projects.


About the author

Evan Dunham

Add comment

By Evan Dunham

Recent Posts

Recent Comments