Create the accordion effect using CSS3
Recently I have been playing around with CSS transitions and animations as implemented in webkit based browsers such as Safari and Chrome. They have been submitted to the W3C for consideration in the CSS3 spec so hopefully we should see more browsers support this soon, Firefox 3.5 supports CSS transforms which was developed by the webkit people to work alongside CSS animations & transitions.
To continue my effort to accomplish tasks in CSS that are usually reserved for JavaScript, such as my Futurebox and CSS based iPhone orientation detection. I have developed a CSS based version of the popular “accordion effect” that utilises the webkit CSS transitions. Like the Futurebox demo I’m utilising the CSS3 :target pseudo class to know which item to show based the URI fragment identifier (the # in the url).
It should be noted that this works best in a webkit based browser such as Safari 3+, Chrome or iPhone. Other browsers that support the :target pseudo class will still function on the core level but won’t animate the showing and hiding. The following browsers have been tested and work with this demo.
- Firefox 1.5+
- Opera 9.6+
- Safari 3+
- Chrome 1+
- IE6+ – IE solution
The xhtml
<dl> <dt><a href="#Section1">Section 1</a></dt> <dd id="Section1"> <p> Lorem ipsum dolor sit amet... </p> </dd> <dt><a href="#Section2">Section 2</a></dt> <dd id="Section2"> <p> Lorem ipsum dolor sit amet... </dd> ... </dl>
We setup the accordion using a definition list to create the foundation so we can show and hide the definition data (dd) tag when the user clicks the anchor link inside the definition title (dt) tag.
The CSS
dl { padding: 10px; min-width: 960px; } dl dt { -webkit-border-radius: 5px; -moz-border-radius: 5px; border: 1px solid #cccccc; margin: 0; } dl dt a { color: #ffffff; font-weight: bold; text-decoration: none; padding: 10px; display: block; } dl dd { margin: 0; height: 0; overflow: hidden; -webkit-transition: height 1s ease; } dl dd p { padding: 10px; margin: 0; } dl dd:target { height: auto; } @media (-webkit-transition) { dl dd:target { height: 6.667em; } }
Pretty simple CSS involved, the dd tag is hidden by setting the height to 0 and the overflow to hidden.
-webkit-transition: height 1s ease;
This property on the dd tag lets webkit browsers know we wish to transition the height value over 1 second period using the ease timing function this transition will only happen when the height of the dd tag is changed. We can also express this in a long hand version.
-webkit-transition-property: height; -webkit-transition-duration: 1s; -webkit-transition-timing-function: ease;
To change the height we use the :target pseudo class to set the height of the dd tag to auto so the right content will show based the URI fragment identifier. For webkit browsers it’s a little different.
Webkit media queries
In webkit browsers there are additional media queries available so we can target browsers that support the extended features such as transitions and not affect other browsers. In this demo I use the @media (transition) media query.
Webkit implements this feature by using their -webkit vendor extension so the media query looks like the following
@media (-webkit-transition) { dl dd:target { height: 6.667em; } }
Unfortunately setting the height of the dd tag to auto will not make it animate although this would be ideal and much more capable of catering for different sized content it’s not possible at the moment. For now we have to set the height to an actual value, to keep the height in line with any text resizing I set the height using em based value so if the user has larger text the height will adjust and won’t cut of any content. The height is 80px we divide by the base font size, which is 12, and we get 6.667em.
What about IE
Unfortunately IE doesn’t support the :target pseudo class and won’t work as describe above, but that didn’t stop me! Take a look at working example that functions in IE6 and up.
This is quite hacky and involves a bit of IE conditional comments.
IE xhtml
<dl> <!--[if IE]> <a href="#Section1" class="ie"><div> <![endif]--> <dt> <!--[if !IE]>--> <a href="#Section1"> <!--<![endif]-->Section 1<!--[if !IE]>--> </a> <!--<![endif]--> </dt> <dd id="Section1"> <p> Lorem ipsum dolor sit amet... </p> </dd> <!--[if IE]> </div></a> <![endif]--> ... </dl>
As you can see there is conditional comments so I can wrap the dt and dd tag in an anchor so we can get it functioning in IE using the following CSS. I also use the conditional comments to hide the anchor that appears in the dt tag only for IE browsers. IE6 was not functioning with just the anchor around the dd & dt so I added a div inside the anchor. In IE6 the first anchor would surround all the items, the div fixes that. Demo, demo files and example code has been updated to reflect that.
IE CSS
dl a.ie { text-decoration: none; } dl a.ie dd { display: none; } /* Fix IE6 hover bug */ dl a.ie:hover { background-color: #606061 !important; } dl a.ie dt { color: #ffffff; font-weight: bold; text-decoration: none; padding: 10px; display: block; } dl a.ie:hover dd, dl a.ie:active dd, dl a.ie:focus dd { height: auto; color: #cccccc !important; display: block; }
Pretty simple stuff, set the text-decoration so the content isn’t underlined. We need to hide the dd tag as it causes issues in IE7 and below when trying to hover over any items below the first section. Next a background-color is applied to the :hover pseudo class of the surrounding anchor to fix an issue in IE6 that won’t trigger a hover unless something like a background-color is applied it. To make it work in IE we utilise the :hover, :focus and :active pseudo classes. That way when the user hovers in IE the content gets revealed, we also simulate a “click” by using the :active pseudo class. The :focus pseudo class allows us to make it work by using keyboard navigation, tabbing to the anchor will reveal the content. All the mark-up is XHTML 1.0 Strict complaint.
I think this is a pretty good attempt and best of all it works in all major browser so it can be potentially be used in a production environment.
Post filed under: css.
Comments
Trackbacks
-
[...] Visit Source. [...]
-
Create the accordion effect using CSS3…
Using the :target CSS3 pseudo selector along with webkit CSS transitions to re-create the “accordion” effect without the need for JavaScript. Works in all major browsers including IE (with some work arounds).
… -
[...] pseudo class will still function on the core level but won’t animate the showing and hiding. Demo | Tutorial and Download Source [...]
-
[...] [...]
-
[...] 13. Create the accordion effect using CSS3 [...]
-
[...] Create the accordion effect using CSS3 | The CSS Ninja – All things CSS, Javascript & xhtm… Recently I have been playing around with CSS transitions and animations as implemented in webkit based browsers such as Safari and Chrome. They have been submitted to the W3C for consideration in the CSS3 spec so hopefully we should see more browsers support this soon, Firefox 3.5 supports CSS transforms which was developed by the webkit people to work alongside CSS animations & transitions. Tags: css akkordion effect menu Beschreibung Produktbeschreibung [...]
-
[...] Create the accordion effect using CSS3 | The CSS Ninja – 05.08.2009 "I have developed a CSS based version of the popular “accordion effect” that utilises the webkit CSS transitions. Like the Futurebox demo I’m utilising the CSS3 :target pseudo class to know which item to show based the URI fragment identifier (the # in the url)." [...]
-
[...] Shared Create the accordion effect using CSS3 | The CSS Ninja – All things CSS, Javascript & xhtml. [...]
-
[...] 5. Create the accordion effect using CSS3 [...]
-
[...] Create the Accordion Effect Using CSS3 [...]
-
[...] Create the Accordion Effect Using CSS3 [...]
-
[...] So funktioniert es auch in IE 6+ : Create the accordion effect using CSS3 [...]
-
[...] View Tutorial [...]
-
[...] Create the Accordion Effect Using CSS3 [...]
-
Social comments and analytics for this post…
This post was mentioned on Twitter by umutm: Create the accordion effect using #CSS3: http://tinyurl.com/np7utr...
-
[...] Accordion Effect Using CSS3 [...]
-
[...] Accordion Effect Using CSS3 [...]
-
[...] Create the Accordion Effect Using CSS3 [...]
-
[...] CSS3 Accordion: http://www.thecssninja.com/css/accordian-effect-using-css [...]
-
[...] 13. Create the accordion effect using CSS3 [...]
-
[...] Create the Accordion Effect Using CSS3 In yet another variation of the popular “accordion effect”, in this tutorial you will learn how to recreate an accordion effect that makes use of webkits CSS transitions. It uses the CSS3 :target pseudo class to know which item to show based on the URI fragment identifier (the # in the url). [...]
-
[...] 7.Create the Accordion Effect Using CSS3 A stylish accordion effect only with CSS3. DEMO [...]
-
[...] 7.Create the Accordion Effect Using CSS3 A stylish accordion effect only with CSS3. DEMO [...]
-
[...] Accordion Effect Using CSS3 [...]
-
[...] css? Das geht schon. Andir hat schon auf das CSS-Akkordeon hingewiesen. Hier der Artikel dazu: Create the accordion effect using CSS3 | The CSS Ninja , der die Methode beschreibt und hier die Live-Demo, die auch in IE 6 funktioniert. Auf kleinere [...]
-
[...] | تحميل | الشرح مثال | الشرح مثال | تحميل | الشرح مثال + الشرح [...]
-
[...] 51. Create The Accordion Effect With CSS3 [...]
-
[...] 51. Create The Accordion Effect With CSS3 [...]
-
[...] Create the Accordion Effect Using CSS3 [...]
-
[...] 6. Create the Accordion Effect Using CSS3 [...]
-
[...] [...]
Nicely done – especially the keyboard support and IE compatibility.
I think it could be a good idea to note that using :target anywhere except for on the top of a page can make the page jump (since it’s scrolls to the element you’re targeting), and you might not want that behavior.
Teddy Zetterlund, August 6th, 2009Another great CSS3 tutorial, i like it!
mupet, August 6th, 2009Cool tutorial, but I still think that animation and transition should be a javascript thing, CSS should only be use as display
Cedric Dugas, August 6th, 2009@Cedric – I think there is certainly a place for CSS animations and they offer advantages over using javascript. e.g. animating a background-image on a navigation item, UI notifications etc. CSS animations a more reserved for adding visual “niceness” to an element.
The Css Ninja, August 6th, 2009You can have browsers without :target support fall back to height: auto; by using dd:not(:target) instead of just dd.
fantasai, August 6th, 2009Great idea, although it would be useless as all browsers who support :target also support :not and of course IE supports neither. Support for both these properties has been in Firefox since 1.0 and Safari since 1.3, Opera added support in 9.5 so it’s a pretty safe pseudo selector.
The Css Ninja, August 6th, 2009awesome tutorial. Is there a way to nest these controls? I gave it a quick whirl but could not get the interior set to expand properly.
Steve, September 23rd, 2009@Steve – Cheers.
Not really possible to nest these accordion menu’s because of the way the target pseudo class works. As soon as you click a nested item the parent item will lose it’s active styling because the fragment identifier has changed. Unfortunately there is no way to select a parent item using CSS so JavaScript would need to be used to have nested lists work.
The Css Ninja, September 23rd, 2009great tutorial, but I was just wondering if this could be done by using the and
Ramon G, October 7th, 2009Did you mean to post a link or extended on that comment?
The Css Ninja, October 7th, 2009I don’t know why it got cut off.
Ramon, October 14th, 2009You are using dl and dt tags. I was wondering if you could replace it with ol tags and li tags?
Would it still work.
@Ramon – Yeah you’re not restricted to defintion lists you just need an anchor tag that points to the id of the item you wish to show, in your case you could do something like this:
That way your hiding the paragraph and clicking the h3 will append the anchor to the url and trigger the styles for that :target id.
The Css Ninja, October 14th, 2009Note it works also in recent firefox nightlies : just add a -moz-transition, and put “height: 6.667em” for everyone, and that’s it ! :)
JulienW, October 30th, 2009@JulienW thanks for that, I did see that Firefox nightly added support for transitions which is great. We now have 3 major browsers that support it and a plethora of other webkit based browsers.
The Css Ninja, October 30th, 2009Hello,
Thank you, it’s working fine.
Bhossain, January 11th, 2010Love these transitions, but not convinced that the user will be expecting to see previous accordian states when they hit the browsers back button. This could be a usability issue…
Meander365, February 3rd, 2010@Meander365 – That’s one of the drawbacks/features of the :target pseudo-class. But it’s how anchor tags have worked since their inception it’s just that we can now style those interactions and create visual feedback which is new to most users.
The Css Ninja, February 3rd, 2010Thanks for this. It will come in handy in my future web designs.
Is there a way of having a different amount of text in each section and maintaining the ‘ease’ transition?
I have changed the “dl dd:target” to have “height: auto”, so that way, it shows all the text, no matter how long. However, this seems to get rid of the ease effect.
David, February 12th, 2010Is there a way of returning all sections to closed? or when you click on the section header again, that it closes? Thanks.
David, February 13th, 2010@David – You could have another container inside the dl that has the same height and just give it
overflow: autoso if there is more content it will just show a scroll bar.As for closing all of them you’ll need to change the fragment indentifier to something that doesn’t match one on the demo page. Like I do on my futurebox article.
The Css Ninja, February 13th, 2010onClick=”document.getElementById(‘text-01′).style.height=’auto’, document.getElementById(‘text-01′).style.height=document.getElementById(‘text-01′).offsetHeight + ‘px’”
try using that for adjustable height – it worked for me!
Sean, March 23rd, 2010for me… it’s now practical. To many conditions for IE
shpyo, April 15th, 2010you IE 6 demo does not work consistently for me in IE 8. Should it? Sometimes sections get stuck open when mouse is not near them.
also, FF requires clicking, is that correct behavior?
johny why, April 28th, 2010Johny, that is the intended behaviour for IE. If you click an accordion title it will stay open as I am using the :active pseudo-class, that way you can click to keep it open and you can move the mouse away from the anchor but still read the accordion contents.
All other browsers, the ones that support the target pseudo-class, require you to click the title in order to open it as target relies on fragment identifiers in the address bar to take effect.
The Css Ninja, April 28th, 2010I am trying to use this method for a collapsible monthly calendar with the months as my headings. When the page loads, it automatically scrolls down to the first anchor putting the target at the very top of the browser window, effectively hiding my page header and the month title.
Is there a way to make the page only scroll when the expanded content extends beyond the open window? The months of January ~ May would be able to expand without the page scrolling, but as one clicks the later months, I would want the page to scroll down to the bottom of the expanded content. Make sense?
Anyone got an answer? I have to avoid using JavaScript entirely with this.
Terrence DiMarco, May 5th, 2010Comment above refers to page:
http://campusmarketing.dev.mavidea.com/t-resources.aspx#Section1
Terrence DiMarco, May 5th, 2010Great tutorial, thanks! I’m using it to create a navigation menu but in IE7, as soon as I mouse over an href tag, the accordion closes. Is there a fix I can apply? Thanks again.
Iain, May 20th, 2010Another great CSS3 tutorial, i like it!
Deepak Kaletha, June 17th, 2010I cant get this working in IE. Please email me and help!
Jarrid, July 1st, 2010@Terrence D – Unfortunately that is the intended behaviour of an in page anchor link. Without using javascript there is no real way around it.
The Css Ninja, July 5th, 2010maybe i have a good one buddy,,come to my blog
hendro-prayitno, July 15th, 2010Is there a way to default so the first item is open?
Matt, July 29th, 2010@Matt – Yes you can make any of them open by default by using the fragment identifier in the url. e.g In my demo adding #Section1 to the url will open the first one. The down side of that is if it appears below the fold or down further then the page will jump to that point.
The Css Ninja, July 29th, 2010Thanks – but is there another way such as changing a CSS property using Javascript? I can’t rely on the hash value as people may have already bookmarked the site without it.
Matt, July 30th, 2010I add this bit of jQuery, but the section remains open even when other sections are opened.
Matt, July 30th, 2010$(‘#Section1′).css({‘height’:’9em’});
@Matt – The reason it’s always staying open is due to the fact you’ve added an inline style to the first dd tag which has the greatest specificity and overrides the target pseudo-class trying to set it back to zero when it’s not active. You’ll have to reset or remove the inline style when any of the other items are clicked.
The Css Ninja, July 30th, 2010am i right in thinking it is impossible to add hyperlinks within the accordian sections when using IE,
since that would be a hyperlink within what is fundamentally a hyperlink?
Fibrewire, August 31st, 2010Links wouldn’t be able to be used inside the accordion for IE. I wouldn’t recommend using the IE solution as it has pretty poor UX. I would recommend to emulate target pseudo-class style functionality in IE with javascript.
The Css Ninja, September 1st, 2010It works great in safari but in IE it only shows what’s in the tags and everything else is lost. Is there a way to write a conditional comment without adding anymore html that would allow everything to stay expanded in IE without effecting the webkit transitions for other browsers?
Kelsy, September 27th, 2010@Kelsy – That is a good point and there is a easy solution that doesn’t require conditional comments or any extra markup and only requires one extra line of CSS.
All you have to do is remove the height: 0 from the dl dd style block and add a new one using the not. IE doesn’t understand the :not pseudo-class and since the height is no longer set to 0 on dl dd block all accordions in IE8 and down will be expanded.
I’ve updated the demo and source files to have this change.
The Css Ninja, September 27th, 2010Interesting effect, but not sure if i would use it over jQuery for the fact it will not animate in firefox. But very good tut thank you
Gerlach Firm, November 20th, 2010Very nice, maye i will try this instead of jQuery on my next project. Thank you
Gerlach Firm, November 20th, 2010Great tutorial! What browsers supported CSS3?
strony www, November 21st, 2010For a crossbrowser CSS only horizontal accordion menu (optional slide behavior with CSS3 or SMIL for IE) check http://alejandroaraneda.blogspot.com/
Alejandro, November 30th, 2010Thanks for this! Is it possible to have the selection minimize once you select the bar after it’s expanded?
Andrew V, January 21st, 2011@Andrew V
The Css Ninja, January 27th, 2011No due to the fact that
:targetpseudo-class relies on an in-page anchor, clicking the link again wouldn’t hide it. You would need to change or remove the fragment identifier in the URL.it works on Safari, but when i test it on Opera 11, the transition duration doesn’t work. so the dd content will opened directly with no transition duration. can you help me with this?
petra, February 21st, 2011@petra -
The Css Ninja, February 21st, 2011I’ve just tested it in Opera 11.01 on Win7 and the transition works fine. Has your version got
-o-transitionproperty?simple and wonderful accordion effect.
web design, March 29th, 2011great im really impress
sawebdesigns, April 18th, 2011Thank you very much this will help moving forward.
Noclegi, April 29th, 2011It’s great effect. I love it:)
Sweet, April 29th, 2011Is there a way to use this modify this code to make it work horizontally?
take flight, August 12th, 2011@take flight –
Of course! If you adjust the CSS you can make it show horizontally and the rather than do
Ryan Seddon, August 22nd, 2011height: auto;you use width and floats.Beside the point of this great tutorial, but anyway one could include a pure CSS dropdown-icon:
/* Dropdown-icon */ .dropdown-icon { border-color: #EEE transparent transparent; border-right: 5px dashed transparent; border-style: solid dashed dashed; border-width: 5px 5px 0; display: inline-block; font-size: 0; height: 0; left: 6px; line-height: 0; position: relative; top: 0; width: 0; }Bram de Haan, August 28th, 2011I was curious if besides reloading the page, there is a way to load all pleats of the accordion closed. My thing is that I need to have the accordion start off closed and then I need the pleats to close when folks click other pleats, but also, I was hoping to have this set up so that it can close if someone clicks the pleat again. I think that someone else asked a similar question, but I didn’t fully follow the response.
Thanks!
Shawn, September 17th, 2011Shawn
Hi Ryan,
sorry for my English I’m from Germany1
very Nice Tutorial but i have a little problem. I created a list which is larger than my display. If i click on one of the sections my page skips down to the section and this is not very nice.
I hope you can help me! THANKS A LOT
Micha, September 18th, 2011@Shawn –
Unfortunately due to the nature of anchor links clicking it again won’t remove the anchor from the address bar which the
Ryan Seddon, October 3rd, 2011:targetpseudo-class relies upon. That sort of functionality would require javascript.hello, I implement your accordion in my page, looks good but i have one concern, for some reason the firsts links is hidden, if you try to click on the 2nd o 3rd section i have to move the mouse and scrool up to find the text.
https://globalcallforwarding.com/GlobalCallForwarding-web/FAQS.htm
Thanks for your help.
Fabiola Singh, October 19th, 2011I’m having a crack at html5/css3. every example for an accordian results is the page jumping around each time the transition is started,doesn’t work with height:auto; and the extras required for ie are a joke.
has anyone found a solution for this?
this is a good tutorial thanks for the efforts, but a terrible solution. html5 is definitely not the flash killer it claims to be.
daniel, November 7th, 2011