See kevin powell video for complete details on this: https://www.youtube.com/watch?v=Vzj3jSUbMtI. NOTE THAT ALL OF THIS IS ALREADY IN OUR THEME FOR SITES BUILT AFTER SEPT. 2025. NOTE THAT SAFARI DOES NOT SUPPORT "::details-content" so animation only does not work. Also Firefox only very latest version supports ::details-content.
The details/summary elements are a bit odd. First, the browser automatically inserts an arrow/triangle before the summary element. You cannot see this on inspect, but the ::marker pseudo class is inserted by the browser and this creates the triangle somehow, which changes rotation (without transtions) based on whether the user has clicked on the summary to view the other non-summary elements in the detaisl element (i.e. the content to show).
The default position on the marker is "list-style-position: inside", which means that when the text in summary wraps, it wraps all the way over to the left and under the "arrow", which is not desirable. To change this, we add "list-style-position: outside" to our style sheet, which lines up the text properly when summary content wraps. But now, the ::marker is OUTSIDE the summary element AND outside the details element. This means it is inside any other parent element which wraps it, which may have padding on it. If the padding left on that element is expressed as a percentage, the ::marker might squeeze off the left hand side of the page when the scren gets small. MAKING SURE THE PADDING LEFT ON THE IMMEDIATE PARENT IS EXPRESSED IN PIXELS, SOLVES THIS PROBLEM.
Note that transitoning the rotation of the arrow does not seem to be possible as, with for example: summary::marker{ transition: all .6s; display: block; } The only known way at this point to have a transition on the rotationof the marker is to set ::marker content: ''; and then use ::before to build your own marker and code the javascript for its rotation, which is often impractical especially in WordPress. See last point on this page to see how this is done.
This is the answer
Add this to your stylesheet and make sure padding on parent div or group is set to a PIXEL value for left.
summary{ list-style-position: outside; }
Makes animating to height auto possible in detail blocks and other animations or transitions. This is a "progressive enhancement" meaning that not all browsers currently support it, but for those who don't its users just won't see the transitions on detial block or any other animation involving height auto or other "discrete" html elements. This is an inherited property, so could be put on html or body as well
Without having this setting set in dev tools you won't find anything on the content that is shown/hidden to indicate that is is in fact hidden or shown. To set this, open dev tools and go to settings (gear icon) and in the Preferences -- "Elements" block, ensure "Show user agent shadow DOM" setting is checked on. Now when you inspect the details block you will see a new element called "shadow root". Open the shadow root and you will see the web component "slots" where you can see display:block and display: none being toggled. You now also see "slot id="details-content" pseudo="details-content". We will be targeting that ::details-content speudo selector in the Fourth Issue
details[open]::details-content{
/* don't add margin/padding to this, add it to the actual stuff inside the details content. Also do not use prefix a class to selector (like .wp-block-details) as shadow root will prevent it from working*/
height: 0;
transition: height 1s, content-visibility 1s; /*browser toggles content visibility without transition automatically, we add transition here*/
transition-behavior: allow-discrete; /*allows transition of usually not transitionable things, in this case content-visibility (visible / hidden). This is an enchanced improvement--old browsers will ignore it and not do the transiton, but all will still work*/
overflow: hidden */hide any content from hide/show content that might interfere with trigger text*/
}
details[open]::details-content {
height: auto;
}
/*Explanation: We first force the height to be 0 for content to show
when the trigger is not set, then when browser automatically adds pseudo class "open" to details element, we
transition the height of the content to show to its natural height (height auto)*/
summary{
position: relative; /*so arrow positions absolute relative to this element*/
}
summary::marker{
content:none; /*remove auto browswer "arrow" content*/
}
summary::before{
content: "▸"; /*add whatever thing you want to use as arrow here*/
position: absolute;
transition: rotate .4s;
font-size: 40px;
left:0; /*adjust as required*/
top: -16px; /*adjust as required*/
left: -28px; /*adjust as required*/
}
details:open summary::before{
rotate: 90deg;
}