{"id":90,"date":"2008-04-09T07:00:43","date_gmt":"2008-04-09T12:00:43","guid":{"rendered":"http:\/\/cssnewbie.com\/css-only-accordion\/"},"modified":"2008-04-09T07:00:43","modified_gmt":"2008-04-09T12:00:43","slug":"css-only-accordion","status":"publish","type":"post","link":"https:\/\/cssdeck.com\/blog\/css-only-accordion\/","title":{"rendered":"The CSS-Only Accordion Effect"},"content":{"rendered":"<p><a href=\"\/example\/css-only-accordion\/horizontal.html\"><img decoding=\"async\" src=\"http:\/\/cssnewbie.com\/wp-content\/uploads\/2008\/04\/accordion-400.gif\" alt=\"\" \/><\/a><\/p>\n<p class=\"note\"><strong>Update: <\/strong><a href=\"\/advanced-css-accordion-effect\/\">I&#8217;ve created an advanced version of this technique that works in IE6! Read more here.<\/a><\/p>\n<p>The Accordion Effect is fast becoming one of the most commonly used (and perhaps abused?) effects of the Web 2.0 world. Most JavaScript frameworks make such an effect fairly easy to pull off \u2013 heck, <a href=\"http:\/\/mootools.net\/\">MooTools<\/a> even built their reputation on it in the early days. So what makes <em>this <\/em>accordion effect special? <strong>It doesn\u2019t require a single line of JavaScript.<\/strong><\/p>\n<p>First off, what is an \u201caccordion\u201d effect? Generally speaking, the accordion effect takes several larger elements and then compresses them into a small space so that only a small portion (like a heading) of most or all of the elements is visible. Then, when the user interacts with that element &#8212; either by clicking on it or maybe only mousing over &#8212; the accordion expands so that the element of interest is visible, and the other elements shrink down automatically. When it\u2019s in use, it looks a bit like an accordion expanding and contracting: hence the name.<\/p>\n<p>Our accordion will work exactly the same way: all of the elements will be partially visible when the user loads the page. And then when they mouse over a particular section, it will instantly expand \u2013 and the other elements will contract \u2013 to make reading more easy.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/cssnewbie.com\/wp-content\/uploads\/2008\/04\/accordion-example1-400.gif\" alt=\"example of accordion effect before and after the user mouses over it\" \/><\/p>\n<p>So how do we accomplish this trick? First, we start with our XHTML, which just consists of a couple of divs with some IDs applied:<\/p>\n<pre lang=\"html4strict\" escaped=\"true\" line=\"1\">&lt;div id=&quot;accordion&quot;&gt;\n\t&lt;div id=&quot;part1&quot;&gt;\n\t\t&lt;p&gt;This text is in part 1.&lt;\/p&gt;\n\t&lt;\/div&gt;\n\t&lt;div id=&quot;part2&quot;&gt;\n\t\t&lt;p&gt;This text is in part 2.&lt;\/p&gt;\n\t&lt;\/div&gt;\n\t&lt;div id=&quot;part3&quot;&gt;\n\t\t&lt;p&gt;This text is in part 3.&lt;\/p&gt;\n\t&lt;\/div&gt;\n\t&lt;div id=&quot;part4&quot;&gt;\n\t\t&lt;p&gt;This text is in part 4.&lt;\/p&gt;\n\t&lt;\/div&gt;\n&lt;\/div&gt;<\/pre>\n<p>My first div defines where my accordion starts and ends. The divs nested inside are just parts of my accordion \u2013 they don\u2019t even technically need IDs unless I want to style them differently. That\u2019s all the XHTML it takes!<\/p>\n<p>So now, let\u2019s start building our accordion. We start by defining the physical limitations of our space:<\/p>\n<pre lang=\"css\" escaped=\"true\" line=\"1\">#accordion { \n\twidth: 500px; \n\tmargin: 100px auto; }<\/pre>\n<p>All I\u2019ve done is give my accordion a specific width and centered it in the page for a nice visual effect. Now, I have to create the default state for the divs inside of my accordion:<\/p>\n<pre lang=\"css\" escaped=\"true\" line=\"1\">#accordion div {\n\tfloat: left;\n\twidth:25%;\n\theight: 300px;\n\toverflow: hidden;}<\/pre>\n<p>This snippet floats all of my divs to the left and gives them a specific width and height. I\u2019ve chosen a width of 25% because I have four elements in my accordion, so they all split that width up evenly by default. If I\u2019d had five elements, I would have used 20%, and so on. My height of 300 pixels also becomes the height of my accordion div.<\/p>\n<p>The overflow: hidden part here is also crucially important. This is what prevents my divs from either resizing to fit their content or spilling their content out of the containing div and onto our page. It also creates a nice visual effect&#8230; people will wonder what content they\u2019re missing, and will mouse over the area to investigate.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/cssnewbie.com\/wp-content\/uploads\/2008\/04\/accordion-example2-400.gif\" alt=\"extra text is hidden from the user, inspiring curiosity.\" \/><\/p>\n<p>So now that we\u2019ve created our default state, we need to create our hover or \u201cactive\u201d state. This requires two CSS rules. The first looks like this:<\/p>\n<pre lang=\"css\" escaped=\"true\" line=\"1\">#accordion:hover div { width: 20px; }<\/pre>\n<p>We\u2019re using the :hover pseudo-class here in a pretty creative way \u2013 we\u2019re telling all of the divs <em>inside<\/em> of the div we\u2019re hovering over to change. Specifically, we\u2019re shrinking them all down to 20 pixels to make room for our expanded accordion section. So now we just need to make sure it expands:<\/p>\n<pre lang=\"css\" escaped=\"true\" line=\"1\">#accordion:hover div:hover {\n\twidth: 440px;\n\toverflow: auto; }<\/pre>\n<p>The :hover pseudo-class comes into play here again. Now, we\u2019re applying styles to an element we\u2019re hovering over, inside of an element we\u2019re hovering over. We\u2019re styling this element differently than our others by giving it a specific width \u2013 440 pixels, i.e. 500 pixels minus the 20 pixels taken up by our other three divs \u2013 and setting its overflow to \u201cauto.\u201d These two classes cause our active div to expand, and then give it a scroll bar if the content is too long.<\/p>\n<p>And that\u2019s all there is to creating a CSS-only accordion box! <a href=\"\/example\/css-only-accordion\/horizontal.html\">If you\u2019d like to see it in action, click here.<\/a> The only change I\u2019ve made to the full version is I\u2019ve added a few background styles and some interior padding to each of the accordion sections to make them stand out and look a little more attractive.<\/p>\n<p>This example creates a horizontal accordion box. But it\u2019s just as easy to create a vertically oriented accordion. All we really need to do is eliminate the floats on our nested divs and turn most of our width tags into height tags. Here is the markup:<\/p>\n<pre lang=\"css\" escaped=\"true\" line=\"1\">#accordion {\n\twidth: 500px;\n\theight: 400px;\n\tmargin: 20% auto; }\n#accordion div {\n\theight:25%;\n\toverflow: hidden;}\n#accordion:hover div {\n\theight: 20px; }\n#accordion:hover div:hover {\n\theight: 340px;\n\toverflow: auto; }<\/pre>\n<p><a href=\"\/example\/css-only-accordion\/vertical.html\">And you can see it in action here.<\/a><\/p>\n<p>As with any trick this cool, there are some caveats. Most significantly: <strong>this technique does not work in IE6,<\/strong> (<a href=\"\/advanced-css-accordion-effect\/\"><strong>update:<\/strong> now works in IE6! Read more here<\/a>) because IE6 doesn\u2019t support hover states on anything other than anchors. Therefore, you <em>can<\/em> make it work if you\u2019re willing to make a sacrifice: if you wrap all of your divs in anchor tags, and then apply the hover state to those anchors instead of your divs, the technique should work the same (I haven\u2019t tried it, though). However, that wouldn\u2019t be particularly semantic or valid, so I\u2019m not showing it here.<\/p>\n<p>Also, if you apply any padding or borders to your #accordion div, that can cause some problems. The border and padding are part of your div, and therefore part of your :hover class. However, if you\u2019re hovering over the containing div\u2019s padding, you <em>aren\u2019t<\/em> hovering over one of the sections of your accordion \u2013 meaning all of your interior divs will shrink down to their smallest size, and none will grow to fill the space. It took me half an hour of debugging to figure this one out. :)<\/p>\n<p>So there you have it. Use it, share it, love it. And let me know in the comments if you come up with a particularly interesting or attractive implementation \u2013 mine is obviously pretty simple!<\/p>\n<div class=\"wp-socializer wpsr-share-icons \" data-lg-action=\"show\" data-sm-action=\"show\" data-sm-width=\"768\" ><h3>Share and Enjoy !<\/h3><div class=\"wpsr-si-inner\"><div class=\"wpsr-counter wpsrc-sz-32px\" style=\"color:#000\"><span class=\"scount\"><span data-wpsrs=\"\" data-wpsrs-svcs=\"facebook,twitter,linkedin,pinterest,print,pdf\">0<\/span><\/span><small class=\"stext\">Shares<\/small><\/div><div class=\"socializer sr-popup sr-32px sr-circle sr-opacity sr-pad sr-count-1 sr-count-1\"><span class=\"sr-facebook\"><a rel=\"nofollow\" href=\"https:\/\/www.facebook.com\/share.php?u=\" target=\"_blank\"  title=\"Share this on Facebook\"  style=\"color: #ffffff\" ><i class=\"fab fa-facebook-f\"><\/i><span class=\"ctext\"><span data-wpsrs=\"\" data-wpsrs-svcs=\"facebook\">0<\/span><\/span><\/a><\/span>\n<span class=\"sr-twitter\"><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/intent\/tweet?text=%20-%20%20\" target=\"_blank\"  title=\"Tweet this !\"  style=\"color: #ffffff\" ><i class=\"fab fa-twitter\"><\/i><\/a><\/span>\n<span class=\"sr-linkedin\"><a rel=\"nofollow\" href=\"https:\/\/www.linkedin.com\/sharing\/share-offsite\/?url=\" target=\"_blank\"  title=\"Add this to LinkedIn\"  style=\"color: #ffffff\" ><i class=\"fab fa-linkedin-in\"><\/i><\/a><\/span>\n<span class=\"sr-pinterest\"><a rel=\"nofollow\" href=\"https:\/\/www.pinterest.com\/pin\/create\/button\/?url=&amp;media=&amp;description=\" target=\"_blank\"  title=\"Submit this to Pinterest\"  style=\"color: #ffffff\" data-pin-custom=\"true\"><i class=\"fab fa-pinterest\"><\/i><span class=\"ctext\"><span data-wpsrs=\"\" data-wpsrs-svcs=\"pinterest\">0<\/span><\/span><\/a><\/span>\n<span class=\"sr-print\"><a rel=\"nofollow\" href=\"https:\/\/www.printfriendly.com\/print?url=\" target=\"_blank\"  title=\"Print this article \"  style=\"color: #ffffff\" ><i class=\"fa fa-print\"><\/i><\/a><\/span>\n<span class=\"sr-pdf\"><a rel=\"nofollow\" href=\"https:\/\/www.printfriendly.com\/print?url=\" target=\"_blank\"  title=\"Convert to PDF\"  style=\"color: #ffffff\" ><i class=\"fa fa-file-pdf\"><\/i><\/a><\/span><\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"<\/p>\n<p class=\"note\">Update: I&#8217;ve created an advanced version of this technique that works in IE6! Read more here.<\/p>\n<p>The Accordion Effect is fast becoming one of the most commonly used (and perhaps abused?) effects of the Web 2.0 world. Most JavaScript frameworks [&#8230;]<\/p>\n<p><a class=\"more-link article\" href=\"https:\/\/cssdeck.com\/blog\/css-only-accordion\/\" title=\"Click to read 'The CSS-Only Accordion Effect'\">Read Article<\/a><\/p>\n","protected":false},"author":18,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[165,178],"tags":[67,200,62,136,124],"_links":{"self":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts\/90"}],"collection":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/users\/18"}],"replies":[{"embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/comments?post=90"}],"version-history":[{"count":0,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts\/90\/revisions"}],"wp:attachment":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/media?parent=90"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/categories?post=90"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/tags?post=90"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}