Pure CSS Clickable Events Without :target

The other day I received a tweet from Marcos Navarro about CSS-only click events without using JavaScript. I told him about the :target method, but he could not use that for what he was trying to accomplish. Unfortunately, this CSS-only approach didn’t really work for his needs. However, there is a lot of cool stuff you can do with this method.

@Ryan_Collins Is there possible to make an on click event without jquery? I mean pure CSS?

— Marcos Navarro (@datfruit) March 12, 2012

Click on the drop downs above. That’s done all in CSS; no kind of javascript whatsoever. Pretty cool, eh? It’s a fun use of the :active and :hover selectors. You can browse the source code for the demo above here. If you’d like a more in-depth tutorial of how to accomplish this, continue reading.

Tutorial

First we’ll need to make a wrapper that will hold both the button and the content it toggles when clicked. It should look something like this:


<div class="wrapper">
	<div class="content">
		<li>Lorem ipsum dolor sit amet.</li>
		<li>Consectetur adipiscing elit.</li>
	</div>
	<div class="button">Toggle Button</div>
</div>

We want .content to be invisible unless .wrapper is clicked on. To do this we’ll set .content to display: none. Next we’ll make it so that when .wrapper is clicked, it changes .content to display: block. To do this, we’ll set .wrapper:active .content to display: block. At its current state, .content will only be visible while the mouse is clicked down. Once you lift from your click, .content will disappear again. To fix this, we’ll make it so that whenever you are hovered over .content it is set to display: block. So, just set .content:hover to display: block. So far our CSS should be this:

.content {
	display: none;
}

.wrapper:active .content {
	display: block;
}

.content:hover {
	display: block;
}

It should output as:

  • Lorem ipsum dolor sit amet.
  • Consectetur adipiscing elit.
  • Toggle Button

    Now we’re just going to add a bit more styling to make it function slightly better and make more sense visually.

    .wrapper {
    	position: relative;
    }
    
    .button {
    	background: yellow;
    	height: 20px;
    	width: 150px;
    }
    
    .content {
    	position: absolute;
    	padding-top: 20px;
    }
    
    .content li {
    	background: red;
    }
    

    It should output as:

  • Lorem ipsum dolor sit amet.
  • Consectetur adipiscing elit.
  • Toggle Button

    And that’s pretty much it. You can play around and expand on the code — I’m sure you can come up with much cooler things than I can. If you have any feedback or questions, feel free to email me or mention me on twitter.

    Want to be awesome? Check out my ongoing project, Theatme. Thanks!