Tinting or lightening with CSS

The problem

Consider the requirement that, on hover, an element’s background becomes lighter. The background could be an image or a colour. The ideal solution should allow a .tint-lighter (or .tint-darker, .tint-red, etc) class to be applied to any element.

Possible solutions

There are a number of use-cases for tinting with CSS and a number of ways to achieve the effect (Like this one). Most of the techniques I have seen before fall into three categories:

  • Using opacity
  • By layering background images
  • With an overlay

Each of those solutions has a drawback.

If you are using opacity then you cannot have anything behind the element (as we wanted a lighter colour not a see-through element). Also, if you have content in the element that will become translucent too.

The layered background images works well: you overlay the desired background with a translucent white background (say a uniform gradient). The main issue with this is that you need to know the properties of the original background in your declaration. That is, if an element has two classes, .red and .tint-lighten, there needs to be a specific selector for that combination, as it will override the background set by just .red. Say there are 50 classes with different colours (for example, to represent countries) and you have three tint types, plain, lighten on hover and darken to show some functionality is disabled. In that case you need to define 150 css selectors and backgrounds for each combination. Probably not too difficult with a pre-processor but pretty bloaty.

Using an overlay can work but again it will affect the content of the element and if the element is animated or an interesting shape there can be some complexity.

Throwing my hat into the ring

I had to tackle this issue the other day. I tried all of the above techniques but wasn’t happy. The best solution was the layered background images but we were using 10 different tints and 12 different colours (for a data visualization) and 120 perturbations for such a simple case was unsatisfying.

I tried to think about other ways to layer colours and came to box-shadows. The solution is based upon applying a very large inset box shadow with a translucent colour, then, the background is overlaid but not the content and the original background is still in place. Here’s an example:

See the Pen Esfch by chrismichaelscott (@chrismichaelscott) on CodePen.

An odd page layout (using CSS first-of-kind, last-of-kind, and nth-of-kind selectors)

Consider the following layout for a page with a collection of articles:

article layout idea idea

It’s a fairly common structure and really good for emphorsizing the lead story. I set about trying to create that layout as a theme for a FactMint infographic. As it was a theme, I couldn’t add any additional classes to the HTML (and would rather not anyway). I started from this criteria:

The first article must be full width and all others half width.

That can be accomplished using the CSS selector

section article:first-of-kind

or similarly using the :first-child pseudo class.

Although the criteria is fulfilled, there is problem. Take the case where there are two articles:

article layout problem 1

Looks a little unbalanced, at best. So, what’s the solution? Well, one could make the last article full width, too. That is accomplished using a selector like:

section article:list-of-kind.

The issue with that approach is fairly clear, it just moves the problem onto the cases where there are an odd number of articles; the penultimate article will, then, be solitary and half-width:

article layout problem 2

Logically, the general solution is easy to describe: make the last article full width only in the cases where there are an even number of blocks. The question is, how would one accompish that?

I’ve seen this problem resolved in the past by adding conditionally adding a class (say, .full-width) to the last article, subject to there being an even number of articles. That could be implemented using a templating engine or just code. The solution has its merits – it’s pretty easy to understand, for one thing, which is a big pro. It is, however, not a semantic class; even if you were to call the class last-component, while it would be semantic, the fact that it is conditional would nullify its sentiment.

Here’s the solution I came up with. It is dependent upon the precedence of four CSS rules, implemented by their order in the stylesheet. Namely:

  1. All articles are half width
  2. The last article is full width
  3. All odd articles are half width
  4. The first article is full width

So, the first article is always full width, as it’s the last (highest precedence) rule and the last article is full width unless it is odd (as the odd rule overrides the last rule).

Here’s a jsfiddle to illustrate. Play around with the number of articles in the section.

CSS for code tags

Recently I was looking at ways to improve the aesthetics of code I was putting up onto a site. I didn’t want to go down the route of a full on Javascript code highlighter but as I was looking at Syntax Highlighter I thought I must be able to replicate the look and feel (without the highlighting) just using CSS.

The basic premise is to repeat background stripes using em measures, to keep them inline with the text.

Here’s the result:

Favorite stars

Quick idea for CSS stars – useful for marking something as a favorite…


.star.starred:before {
content: "2605";
}

.star:before {
content: "2606";
}

.star {
font-size: 2em;
cursor: pointer;
}

.star:hover {
text-shadow: 0px 0px 3px yellow;
}

.star.starred:hover {
text-shadow: 0px 0px 3px red;
}

Add a little bit of Javascript to toggle the “starred” class:


$('.star').on('click', function() {
$(this).toggleClass('starred');
if ($(this).is('.starred')) {
// Do something to record that this is favourited
}
});

Here’s the results.

About me

Contrary to the massive "Chris Scott" at the top of the page, I'm not a (complete) ego-maniac. I just liked the font and couldn't think of anything more interesting to say.

I'm a passionate developer and entrepreneur. My company Factmint provides an elastic RDF triplestore and a suite of Data Visualization tools, so I largely talk about those things.

Fork me on GitHub

GitHub Octocat

chrismichaelscott @ GitHub

  • Status updating...