67

Using just CSS3, is there a way to add a nice fade-in and slide-from-left transition effect on a DETAILS/SUMMARY reveal?

For a demo of this new tag, see this demo:

details {
  transition:height 3s ease-in;
}
<details>
  <summary>Copyright 1999-2014.</summary>
  <section>
    <p> - by Refsnes Data. All Rights Reserved.</p>
    <p>All content and graphics on this web site are the property of the company Refsnes Data.</p>
  </section>
</details>

In my case, after the summary tag, I put all other content in its own section tag so that I could style it because summary:after selector didn't seem to work. I tried using CSS3 transitions on height for the section and details tag, but it didn't help.

Nick
  • 5,108
  • 2
  • 25
  • 58
Volomike
  • 23,743
  • 21
  • 113
  • 209
  • 1
    Please include all of the HTML & CSS in the question itself, in a [mcve]. You may also want to consider using a different reference than w3schools, like [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary) or even [the standard itself](https://html.spec.whatwg.org/multipage/forms.html#the-summary-element). Also, HTML elements do not need to be in all uppercase, and referring to them in that manner makes the question hard to read. – Heretic Monkey Jul 05 '16 at 22:07
  • Note that Edge support is still lacking. I have proposed a solution [here](https://stackoverflow.com/a/52607333/2397550). – Mr. Hugo Oct 02 '18 at 11:40

7 Answers7

87

This should fix it.

details[open] summary ~ * {
  animation: sweep .5s ease-in-out;
}

@keyframes sweep {
  0%    {opacity: 0; margin-left: -10px}
  100%  {opacity: 1; margin-left: 0px}
}
<details>
  <summary>Copyright 1999-2014.</summary>
  <p> - by Refsnes Data. All Rights Reserved.</p>
  <p>All content and graphics on this web site are the property of the company Refsnes Data.</p>
</details>

Some credit goes to Andrew for pointing this out. I adapted his answer. Here's how this works. By adding the [open] attribute on the DETAILS tag, it only fires the animation keyframe when clicked. Then, by adding SUMMARY ~ * it means "all elements after the SUMMARY tag" so that the animation applies to those, and not the SUMMARY element as well.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Volomike
  • 23,743
  • 21
  • 113
  • 209
  • 2
    this works well only if you have nothing after the
    .
    – Fabrizio Calderan Mar 29 '19 at 12:51
  • 3
    @fcalderan not so -- I've implemented it on FAQs with multiples of these. – Volomike Mar 30 '19 at 19:02
  • @Felipe & Volomike, if you want to add a new method, that's one thing, but completely changing to a different method is more or less against Stack Overflow policy. – TylerH Jun 01 '21 at 20:24
  • 1
    Consider [Felipe's answer](https://stackoverflow.com/a/67814400/105539) due to performance reasons. He's made a small improvement. – Volomike Jun 03 '21 at 13:34
  • 9
    It's a good solution ! But the animation is only triggered the first time on Chrome (looks ok on Firefox) – KCarnaille May 13 '22 at 09:22
  • 1
    @KCarnaille did you figure out a solution for Chrome? I want to restart the animation on Chrome. – cringe Jun 26 '23 at 06:49
29

For those looking for an open/close transition, it's possible to fake it by margin-bottom property.

details {
  background: gainsboro;
  padding: 10px;
}

details summary {
  cursor: pointer;
  transition: margin 150ms ease-out;
}

details[open] summary {
  margin-bottom: 10px;
}
<details>
  <summary><code>&lt;details&gt;</code> pseudo content transition</summary>
  Lorem ipsum dolor sit amet consectetur adipisicing elit. Quia amet magnam fugit nihil delectus, id ratione deleniti minima, ipsum accusantium exercitationem est ipsa, possimus harum distinctio consequatur qui recusandae et. Alias quas temporibus aliquam modi nulla omnis unde atque magni tempora, corporis ducimus voluptas, recusandae, repellendus officiis molestias cumque quam.
</details>
Tárcio Zemel
  • 821
  • 10
  • 28
  • 5
    This is the only answer where animation works on opening & closing the Details tags again. All other answers works only on first open of details tag. – DavChana Jan 05 '23 at 05:50
  • For some reason I don't understand, when the contents of the `
    ` are wrapped in certain tags, like `

    ` or `

    `, then the animation only plays on closing and not opening.

    – Daniel Ting Jul 12 '23 at 03:41
22

In addition to Volomike's answer, it would be possible to change margin-left to transform: translateX() for performance reasons.

details[open] summary ~ * {
  animation: sweep .5s ease-in-out;
}

@keyframes sweep {
  0%    {opacity: 0; transform: translateX(-10px)}
  100%  {opacity: 1; transform: translateX(0)}
}
<details>
  <summary>Copyright 1999-2014.</summary>
  <p> - by Refsnes Data. All Rights Reserved.</p>
  <p>All content and graphics on this web site are the property of the company Refsnes Data.</p>
</details>
Felipe Saldanha
  • 1,087
  • 8
  • 17
  • How do I revert this animation upon closing? Simply adding a `details[close] summary ~ *` property with the same animation but with the property `animation-direction: reverse` did not work. – Rich_Rich Aug 16 '21 at 07:48
  • 2
    @Rich_Rich it's not possible. According to [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details): "Unfortunately, at this time there's no built-in way to animate the transition between open and closed." – Felipe Saldanha Aug 17 '21 at 11:46
  • 3
    there goes my CSS only dream. Also good to note: On Firefox iOS (and thus presumably on all iOS browsers), closing and re-opening does not replay the animation. – Rich_Rich Aug 17 '21 at 14:16
14

details
{
    transition: height 1s ease;
    overflow: hidden;
}

details:not([open])
{
    height: 1.25em;
}

details[open]
{
    height: 2.50em;
}
<details>
    <summary>Example</summary>
    Height needs to be set for this to work. Works on Chrome, haven't tested further.
</details>

I recommend you also check out Animate.css here: http://daneden.me/animate. If

Spencer O'Reilly
  • 515
  • 1
  • 7
  • 20
Daniel Sepp
  • 178
  • 8
6

I think a true CSS3 details summary reveal should be done like this (no fixed height and no javascript):

@keyframes animate {
  from {grid-template-rows: 0fr;}
  to {grid-template-rows: 1fr;}
}
details > div {
  display: grid;
  grid-template-rows: 0fr;
  transition: all ease-in-out 0.5s;
}
details > div > div {
  overflow: hidden;
}
details[open] > div {
  animation: animate 0.15s 0s 1 normal forwards;
}
<details>
  <summary>Lorem ipsum</summary>
  <div>
    <div>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus suscipit neque vestibulum elit vehicula luctus. Aenean eget rutrum felis. Ut blandit, massa vitae pulvinar suscipit, nunc lorem pulvinar metus, sed elementum lectus erat euismod eros. Aliquam ac metus id tortor maximus mollis. Sed semper pulvinar risus. Mauris orci mauris, blandit tempus dolor sed, tincidunt pharetra nisi. Cras pulvinar ligula eu sapien cursus, in malesuada diam volutpat. Ut eleifend risus vitae eros pretium rhoncus. Nunc diam nibh, pharetra et orci eu, rutrum congue augue. Etiam quis tempor tortor. Pellentesque nec faucibus mi. Curabitur vitae tempus lorem.
    </div>
  </div>
</details>
<details>
  <summary>Lorem ipsum</summary>
  <div>
    <div>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus suscipit neque vestibulum elit vehicula luctus. Aenean eget rutrum felis. Ut blandit, massa vitae pulvinar suscipit, nunc lorem pulvinar metus, sed elementum lectus erat euismod eros. Aliquam ac metus id tortor maximus mollis. Sed semper pulvinar risus. Mauris orci mauris, blandit tempus dolor sed, tincidunt pharetra nisi. Cras pulvinar ligula eu sapien cursus, in malesuada diam volutpat. Ut eleifend risus vitae eros pretium rhoncus. Nunc diam nibh, pharetra et orci eu, rutrum congue augue. Etiam quis tempor tortor. Pellentesque nec faucibus mi. Curabitur vitae tempus lorem.
    </div>
  </div>
</details>

<br>
<br>

Inspired by <a href="https://www.youtube.com/watch?v=B_n4YONte5A">Kevin Powell</a>
Mr. Hugo
  • 11,887
  • 3
  • 42
  • 60
  • This only works for the first couple of clicks. If I click over and over again the details eventually stop sliding and abruptly open – jfudman Jul 11 '23 at 20:24
  • 1
    fwiw... you can combine your solution with this [answer here](https://stackoverflow.com/questions/69958043/animate-a-details-tag-when-closing). It takes minimal javascript to listen to animation end and click events – jfudman Jul 12 '23 at 13:09
5

My styling…

Using max-height for transition instead of height you can have unknown height (smaller than 99rem) of content in opened details.

details {
  margin: 1.3rem 0;
  border-bottom: 1px solid #aaa;
  padding: 0.5rem;
  height: auto;
  max-height: 1.5rem; /* set to line height */
  transition: all 0.1s ease;
}

details[open] {
  max-height: 99rem;
  transition: all 1s ease;
  border: 1px solid #aaa;
}

details summary {
  font-weight: bold;
  cursor: pointer;
  margin-bottom: 0.5em;
  font-weight: bold;
  margin: -0.5em -0.5em 0;
  padding: 0.5em;
}

details[open] summary {
  border-bottom: 1px solid #aaa;
  margin-bottom: 0.8em;
}
<details>
  <summary>Something like… question?</summary>
  And some very, very long explanation of summarised text. And some very, very long explanation of summarised text. And some very, very long explanation of summarised text
</details>
developer033
  • 24,267
  • 8
  • 82
  • 108
iiic
  • 1,366
  • 2
  • 15
  • 23
  • 1
    The text just appears, it doesn't have a transition or animation at all. You can see this by increasing the transition duration. – khaki Jun 21 '22 at 15:55
0

You probably would want to use a CSS animation using the keyframes if you don't plan on having it appear when you hover over it. If you only want the animation to appear, say, when you see details/summary description on the page, you could use some jQuery so that the browser adds the class of the animation when scrolling.

https://jsfiddle.net/22e95bxt/

Is this what you're looking for?

Edit: Whoops. This is NOT what you're asking for. My bad!

Andrew
  • 50
  • 2
  • It's close. Looks like you need to use the [open] and :not([open]) selectors to improve it, which is what I'm working on. – Volomike Jul 05 '16 at 21:59
  • Your answer looks to be the best if you could remove the bold edit and then switch your selector to like `DETAILS[open] SECTION` that fires the animation. That way, it only happens on the click. – Volomike Jul 05 '16 at 22:07