This week we’ve found a new technique for creating semi-transparent css only buttons from list items, which become opaque when hovered over. This is easy enough to do when writing custom markup as you can put anything you like inside an anchor tag, but using some of Drupal’s theme output it isn’t always so simple.

In our case, we were finding that the list item area was turning opaque without the anchor being hovered over, giving the impression that it was clickable even though it wasn’t (bad UX alert!). The code below is a neat workaround for this problem and uses background opacity and the rarely used CSS3 attribute pointer-events.

Here’s the HTML code:

<ul>
    <li class="button">
        <a href="#"><h3>Click here</h3></a>
    </li>
    <li class="button">
        <a href="#"><h3>Click there</h3></a>
    </li>
    <li class="button">
        <a href="#"><h3>Don't click anywhere</h3></a>
    </li>
</ul>

And this is the CSS:

.button{
    width: 100%;
    pointer-events: none;
    background-color: rgb(0,0,0);
    background-color: rgba(0,0,0,0.5);
    text-align: center;
    padding: 30px;
    list-style: none;
}
.button:hover{
    background-color: rgb(0,0,0);
}
a{
    pointer-events: auto;
}

The key aspects are the use of rgba values to describe an opacity value for the list item backgrounds and the pointer-events attribute. Pointer-events can be used to switch off action events based on hover or touch and turn them back on for underlying elements, in this case our anchor tag. So the :hover css is only applied to the list item when the anchor underneath is hovered over.

Bear in mind that not all browsers (Internet Explorer 10, I’m looking at you) support pointer-events or, in some cases, background opacity, so make sure that you have a gracefully degrading fallback in place. In this case I’ve just settled for having fully opaque buttons where support isn’t available.