Quick Tip: Mimic a Click Event with CSS
videos

Quick Tip: Mimic a Click Event with CSS

Tutorial Details

In today’s video quick tip, I’ll show you a nifty technique: we’ll use plain and simple CSS to mimic click events. The key is to use the helpful :target pseudo class.


Final Source

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title></title>
    <style>
       figure { background: #e3e3e3; display: block; float: left;}
       #zoom {
          width: 200px; 
          -webkit-transition: width 1s;
          -moz-transition: width 1s;
          -o-transition: width 1s;
          transition: width 1s;
      }

     /* Compliance = IE8+, Firefox 2+, Safari, Chrome, Opera 10+ */
      #zoom:target {
         width: 400px;
      }
    </style>
</head>
<body>
   <h1> "Click" Effect with CSS </h1>
   <figure>
      <img id="zoom" src="http://d2o0t5hpnwv4c1.cloudfront.net/871_dryEE/dry-ee.png" alt="EE" />
      <figcaption>
         <ul>
            <li>
               <a href="#zoom">Zoom In</a>
            </li>
            <li>
               <a href="#">Zoom Out</a>
            </li>
         </ul>
      </figcaption>
   </figure>
</body>
</html>

Conclusion

So what do you think? Pretty neat, huh? On a side note, within the comments, I’d like to know what your thoughts are on my usage of the figcaption element to house those “Zoom” links that are associated with the image. Do you think that’s a fair usage of the element? Thanks for watching!

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://laroouse.com piyansitll

    css ne güzel bir şey değil mi ben çok seviyorum bu css i

  • Max

    So that’s why you needed 2 links in figcaption! Never heard of :target. Thanks!

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Yep!

  • nykeri

    i must say that is brilliant, simply brilliant

  • http://www.alexanderwassberg.com Alexander

    Amazing. CSS3 is the way to go, I just wish all versions of web browsers supported it.

  • http://zecel.com Shishant Todi

    Really cool…. Please keep on with more CSS3 tricks like this… short and sweet, a good way to learn daily something new.

  • JF

    Nice one, as usual ! That’s pretty neet.

    How do you complete your code using the “>” caracter. (kind of chaining) ?

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      ZenCoding plugin.

      • JF

        Thank you ! And I just discovered it’s also available for Textmate. So no need to back to my old “Vi” time.

  • http://khrrsn.com Keith

    why not use -moz-transition: width 1s; aswell?

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      I did. It’s in the source code above.

      • http://khrrsn.com Keith

        you didn’t do that in the video/demo though, was just curious as to why not, did you forget?

      • http://www.jeffrey-way.com Jeffrey Way
        Author

        No – I mentioned in the video that we’d just do webkit to save time. I only had a few minutes to record. :)

      • http://www.stav.co Mathias M. Stav

        I know it’s a biy off track, but I just had to comment on this.

        When I do css in coda I allways do -webkit- then when I’m done I can use the find tool and put in wildcards. Like:

        find: -webkit-box-shadow: (1) (2) (3) (4);
        replace with: box-shadow: (1) (2) (3) (4); -webkit-box-shadow: (1) (2) (3) (4); -moz-box-shadow: (1) (2) (3) (4);

        The transition does not work with ff 3.6 btw :(

  • http://www.ShaneHudson.net Shane Hudson

    This is a very good technique! Was it a typo or did I read somewhere that in Chrome 8 they will be removing the :target pseudo-element?

    Perhaps using things such as webkit animation you could make click like effects by using :active (bet you don’t often use that!) paired with “>”.

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Not sure — if you find that article about Chrome 8, please link to it for me. Thx!

  • http://andrewdotson.com Andrew

    This doesn’t work in any verison of IE correct? Rendering it nearly useless :D Still something new I learned though! Thanks

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Works in IE8+.

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      And it’s not useless at all. You can provide additional features for modern browsers. How is that useless?

    • Mark Sinkinson

      I think someone needs to buy Andy Clarke’s Hardboiled Web Design….

    • http://www.amsheehan.com Alex

      Also, IE has less than 50% market share now. Fingers crossed that it dips below 10 by 2013!

  • Darren L.

    This is awesome! Thank you so much!!!

  • Matt

    Web development has layers.

    HTML is for content.
    CSS is for style.
    JavaScript is for behavior.

    Clicking is a _behavior_. Therefore it belongs in the behavior layer, which isn’t CSS.

    Why would you mix layers? It makes code maintenance difficult and confusing.

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Matt, would you consider the :hover pseudo class to be behavior? If so, shouldn’t that be JavaScript-controlled as well?

      Secondly – if something can be accomplished purely in CSS, why use JavaScript, when roughly 5% of all users have it disabled? (Of course, in this case, :target isn’t supported in IE7 and below).

      • Matt

        Yes, I would say :hover also breaks this rule, technically. I’m not saying you should never do things like this. I’m just talking about following best practices and keeping your code more organized and maintainable.

        This is the equivalent to setting element’s style properties using JavaScript. While it’s OK to do it sometimes (with care), it’s not the best practice. It’s a much better idea to assign elements CSS classes than directly accessing their style properties with JavaScript.

        Furthermore, the users with JS disabled argument doesn’t hold much ground these days. Doing almost anything online without JS is a horrible experience. And like you said, I’m guessing anyone browsing without it is using a browser that won’t support advanced CSS3 properties.

    • http://www.material-designer.com Chris

      I would tend to agree with this. I of course know it’s purely an experiment.

      However, the added benefit of doing something like this in CSS as opposed to JS is you still retain the functionality when JS is disabled.

      It can also be argued that the width of an element is a “design/style” property, and therefore using only CSS for it is still well within the design realm.

      • Matt

        The title calls it a “quick tip” – not an experiment. As an experiment, I think it’s cool, but I don’t think it’s a good “tip”, especially not for beginners trying to learn web development.

    • Mike Hopley

      Yes, it’s good to separate web development into content, style, and behaviour. But you will never get this separation 100% pure, because the divisions between them are not as neat as is commonly assumed.

      What constitutes behaviour? Is it an event, such as a click or key-press? Is it the appearance of movement, of dynamism, such as an animation? Where do you draw the line?

      Similarly, what constitutes style? Must style be purely static?

      What makes one set of code easier to maintain than other? There are many factors, but here’s one: maintenance is easier if you keep related code together. In this example, we have a simple presentational effect: an image that can be zoomed. You argue that this is more maintainable if we split it across HTML (for the markup), CSS (for the initial, static styles), and JS (for the dynamic effect).

      I argue that it’s more maintainable if we split it across fewer layers, not more: HTML (for the markup), and CSS (for the presentation). That way, most modifications can be carried out in one place (the CSS). Why add another layer if you don’t need it?

      Of course, it’s not just about counting the layers. It also depends on how complicated the code is. You wouldn’t write 1000 lines of CSS to replace a 3-line javascript effect. ;)

      Separation of layers is a good basic idea. It helps us avoid writing spaghetti code (font tags in the HTML, HTML fragments in the javascript, inline event handlers everywhere…). But separation of layers is not the goal: it’s merely a method that contributes towards the goal, which is high-quality code.

      Rather than worrying about 100% pure separation of layers (which is impossible), try to choose the best tool for the job. If a presentational effect can be achieved elegantly in CSS, why would you add javascript?

      You know, if you really believed in this 100% pure separation, you would refuse to use a:hover and add the styles via javascript instead. Do you actually do that? No, of course you don’t. Why? Because a:hover is familiar; you accept it because it’s been around for a long time, and nobody moans about it being “bad coding practice”.

      “Following best practices” is often a euphemism for “I don’t understand why I’m supposed to do this, but someone important told me once”. ;)

  • http://randsco.com randsco

    Neat “trick”, but won’t use, as it’s not cross-browser compatible.

    In the future, I’d recommend full disclosure. Which browsers work and/or not work. Devs may not like and ignore Internet Explorer, but the real world and goal should be for the technique to work for *everyone*.

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      @randsco – I mention compatibility in both the video and the source code.

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      If you won’t take advantage of the latest techniques in modern browsers, then you’re going to quickly fall behind the rest of the pack.

    • Ethan

      Let’s not beat around the bush. The mantra used to be perfect experience parity across browsers, but that’s out the window now. We’re done waiting for users to catch up on their browser updates. The lowest common denominator can no longer define the experience for everyone. Provide enhanced functionality for those who happen to be capable of using/viewing it.

      The attitude that we can’t implement something if it doesn’t work for everyone is harmful to our industry and is holding back web innovation more than browser standards compliance is.

  • http://www.willenewmedia.de/ WilleNewMedia

    @Andrew: The final source says the following
    /* Compliance = IE8+, Firefox 2+, Safari, Chrome, Opera 10+ */

    so any IE below 8 does not work, see?

    @Jeff: Pretty nice work, :target is one more on my list of CSS3-stuff i have to keep thinking of. Thanks for the nice, short and clear tut on the usage of :target.

  • WM

    I was more interested in that plugin you used for HTML creation then in the tutorial… could you please name it?

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      ZenCoding or Sparkup for Vim.

  • http://www.macaronibros.com Fabio Fidanza

    Thanks for pointing out this technique, it opens a lot of possibilities for navigational interfaces, especially when you can’t or doesn’t want to use JS.

    One side question: I felt amazed by your VIM configuration that seems to work like a charm. Can we have some suggestion on how to get a similar environment?

    Thanks again!

  • http://www.material-designer.com Chris

    @Jeffrey,

    I’m a little weary about using the figcaption for housing these types of links.

    While the spec for figcaption is sparse (it’s more than sparse, it’s spartan), I wonder if something that is used solely for display/style/behavior really belongs there.

    Traditionally, things like figure captions are used for explanatory content. For the blind, it provides a logical relationship between extra text and the figure image which it corresponds to.

    A more semantic HTML5 tag (which I’m unsure if it has been implemented in any browsers) would be a menu tag http://dev.w3.org/html5/spec/Overview.html#menus, with the Zoom In and Zoom Outs being command tag, http://dev.w3.org/html5/spec/Overview.html#the-command

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Hey Chris – I agree that menu would be a better fit, but I wasn’t sure if the figure element limited which elements can be nested as children — in the same way that a ul can only house lis. I need to research that a bit more.

      Anyhow, figcaption is used to associate some value/information with the image — which I felt was appropriate.

      But yeah — it’s totally up for discussion. The spec is pretty vague, as you said; so it’s difficult to know for sure. :)

  • Callum

    Thanks for the tip Jeff. I can see this having potential. I don’t see myself using this though as i agree with matt that any click event should be handled by jquery/javascript.

  • http://twitter.com/DanielMorosan Danie

    This is a great one. I would try to use it with XHTML tags, will it work? Or is it necessary to have <figcaption> as you did?

  • http://www.linknomer.com andrei

    wow really nice effect, great to impress your friends with, and its compatible enough for me.

  • http://zaktus.net Zaktus

    This is a great technique!

  • Ricardo Nunes

    As always, when I need something, nettuts always read my mind :)

    I’ve used this for a side menu, and it works great! my code:

    /* ARTICLES EMPRESA */

    #quemsomos, #equipa {
    opacity:0;
    -webkit-transition: opacity 1s;
    -moz-transition: opacity 1s;
    -o-transition: opacity 1s;
    transition: opacity 1s;
    overflow:hidden;
    width:0px;
    position:absolute;
    max-height:200px;
    }

    #quemsomos:target {
    opacity:1;
    width:620px;
    position:inherit;
    }

    #equipa:target {
    opacity:1;
    width:620px;
    position:inherit;
    }

    It’s a bit clumbsy because I’m still trying different effects.

    BTW, I know I’ll find it if I search and I’m being a bit lame, but how do I change a .act class by CSS?

    • http://www.material-designer.com Chris

      Do you mean how do you style an element with a class of act?

      .act { }

      Or how do you change the class name of an html element with a current class of “act” to something different?

      You can’t do it with CSS, but you can do it with javascript. In jQuery it’d be as simple as adding

      $(“.act”).toggleClass(“act secondClassName”);

      • Ricardo Nunes

        I thought I would be able to change it trough CSS also with “>” selector…

        Thanks for the info :)

  • Joe

    Cool. You can also use the :target sudo-class for fixing the weird dotter outline in firefox.

    a:target { -moz-outline-style: none; }

  • http://willboling.com Will

    Well done! That is pretty slick if I do say so myself.

  • http://adrusi.com/ Adrian

    problem with :target is that is causes the window to scroll to the location of the target element. I co-wrote an article with Chris Coyier a few months ago, about using :focus to zoom images. if you add the tabindex attribute to any element it allows it to be focusable like a text box, so it has the :focus pseudo-class until something else is clicked. so you could use:

    <figure tabindex=”-1″>
    <img src=”path/to/img.png” alt=”" />
    <figcaption>Caption</figcaption>
    </figure>

    and then do something like this in your css:

    figure img { width: 100px; }
    figure:focus img { width: 200px; }

    to see a result with some added styling: http://jsfiddle.net/9b8pj/embedded/result/
    OR
    see the original tutorial http://css-tricks.com/expanding-images-html5/

  • http://adventistsinglesdating.com chriss

    Sweet! I’ll try this on one my sites soon. I’m not a CSS guru yet, so I’ll have to do a little research on figcaption

  • http://www.a.com Drake

    You’re a genius Jeff, you amaze me with every tut!
    I got lost with the HTML 5 part; I really have to get updated with that thing. Thanks a lot for this tip! :D

  • http://jeffri.net Jeffri Hong

    This is a great technique… Never know the :target pseudo…

    Thanks!

  • Abhijit

    Good technique. I remember this technique was used in the book “CSS instant results” quite some time back.

  • Julien

    Very interesting but I don’t think transitions work on Firefox 3.
    https://developer.mozilla.org/en/CSS/-moz-transition-duration

  • http://thimk.22web.net Thim

    Awesome tutorial Jeffrey! Will use this in the future :)

  • http://www.cpusers.gr Texnologia

    Thats exactly what I was searching for! many thanks for the tut

  • http://www.stav.com Mathias M. Stav

    I’ve made a Crazy Cool Pure CSS Horizontal Accordion Slider :D
    Using :target to get it to work. Probably gonna release it tonight, just gotta make a pretty site for it.
    It doesn’t have any fallback for now, but its more about showing that its possible. With basic styling it weights about 800b Check it out soon @ http://www.csslider.com

  • http://www.devseo.co.uk/ Alex Hall

    I tweeted this a while ago. I tried to recreate the Twitter login form show/hide method using just CSS3. The target attribute shows the form and a ‘modal’ background, so if you click anywhere outside the form it will hide it.

    http://www.devseo.co.uk/examples/css-only-twitter-login-form/

  • http://www.abijith.com Abijith

    Coding looks simple as well..

  • http://idealthought.in Basanta

    Simple code But not working in IE7.

  • http://codecanyon.net/user/Keliah Keliah

    Great tip !

    I’m doing some experimentation now and I found out that a click on any link without href within the page switches the element back to it’s original state, right ? Hope that makes sense !

    Thank you Jeffrey :)

  • http://www.jarodbillingslea.com/ Jarod Billingslea

    My jaw is seriously hanging right now… This is AMAZING…. omg… dude! This is COOL man, I’m glad you shared this dude!

  • http://visualmushroom.daportfolio.com Hector abreu

    NICE TUT!

    if you put the css like this (you can create a really nice accordion effect):

    figure { background: #e3e3e3; display: block; float: left;}
    #zoom {
    width: 400px;
    height:0;
    -webkit-transition: height 1s;
    -moz-transition: height 1s;
    -o-transition: height 1s;
    transition: height 1s;
    }

    /* Compliance = IE8+, Firefox 2+, Safari, Chrome, Opera 10+ */
    #zoom:target {

    height:450px;
    }

  • http://capitalh.ir/ CapitalH

    Nice article,
    One question though, is the only restriction in using this technique, browser support esp IE? other than that could it be used instead of JQuery Click events in most cases?

  • Sara

    I love ur tuts and tips Jeffrey, always so helpful. I’ve seen a CSS3 Lightbox effect being created using :target , but I never really understood the logic behind it completely, u just cleared up that little vague part on my head :) thank u so much this is so awesome! :)

    P.S You’re a great teacher!!

  • Red_hawk

    Damn Good…..:)