From 4774a7b741d65dcf8292939bb16953898c74d718 Mon Sep 17 00:00:00 2001 From: Sli Date: Thu, 5 Jun 2025 20:37:58 +0200 Subject: [PATCH 1/4] Improve accordion animation --- core/static/bundled/core/accordion-index.ts | 16 ++++++++++++---- core/static/core/accordion.scss | 11 ++++++++--- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/core/static/bundled/core/accordion-index.ts b/core/static/bundled/core/accordion-index.ts index 39e37564..d2007767 100644 --- a/core/static/bundled/core/accordion-index.ts +++ b/core/static/bundled/core/accordion-index.ts @@ -1,11 +1,19 @@ -const setMaxHeight = (element: HTMLDetailsElement) => { - element.setAttribute("style", `max-height: ${element.scrollHeight}px`); +const updateMaxHeight = (element: HTMLDetailsElement) => { + const content = element.querySelector(".accordion-content") as HTMLElement | null; + if (!content) { + return; + } + if (element.hasAttribute("open")) { + content.style.maxHeight = `${content.scrollHeight}px`; + } else { + content.style.maxHeight = "0px"; + } }; // Initialize max-height at load window.addEventListener("DOMContentLoaded", () => { for (const el of document.querySelectorAll("details.accordion")) { - setMaxHeight(el as HTMLDetailsElement); + updateMaxHeight(el as HTMLDetailsElement); } }); @@ -16,7 +24,7 @@ new MutationObserver((mutations: MutationRecord[]) => { if (target.tagName !== "DETAILS" || !target.classList.contains("accordion")) { continue; } - setMaxHeight(target); + updateMaxHeight(target); } }).observe(document.body, { attributes: true, diff --git a/core/static/core/accordion.scss b/core/static/core/accordion.scss index abdbba02..17443e5e 100644 --- a/core/static/core/accordion.scss +++ b/core/static/core/accordion.scss @@ -44,12 +44,17 @@ details.accordion>.accordion-content { background: #ffffff; color: #333333; padding: 1em 2.2em; - overflow: auto; border: 1px solid #dddddd; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; + opacity: 0; + overflow: hidden; } -details.accordion { - transition: max-height 300ms ease-in-out; +details[open].accordion>.accordion-content { + opacity: 1; + // Setting a transition on all states of the content + // will create a strange behavior where the transition + // continues without being shown, creating inconsistenties + transition: all 300ms ease-out; } \ No newline at end of file From 36d4a02a459b4f91e7bd073866743fb96d046941 Mon Sep 17 00:00:00 2001 From: Sli Date: Tue, 10 Jun 2025 15:06:59 +0200 Subject: [PATCH 2/4] Remove js size animation and only use the opacity one --- core/static/bundled/core/accordion-index.ts | 33 --------------------- core/templates/core/base.jinja | 1 - 2 files changed, 34 deletions(-) delete mode 100644 core/static/bundled/core/accordion-index.ts diff --git a/core/static/bundled/core/accordion-index.ts b/core/static/bundled/core/accordion-index.ts deleted file mode 100644 index d2007767..00000000 --- a/core/static/bundled/core/accordion-index.ts +++ /dev/null @@ -1,33 +0,0 @@ -const updateMaxHeight = (element: HTMLDetailsElement) => { - const content = element.querySelector(".accordion-content") as HTMLElement | null; - if (!content) { - return; - } - if (element.hasAttribute("open")) { - content.style.maxHeight = `${content.scrollHeight}px`; - } else { - content.style.maxHeight = "0px"; - } -}; - -// Initialize max-height at load -window.addEventListener("DOMContentLoaded", () => { - for (const el of document.querySelectorAll("details.accordion")) { - updateMaxHeight(el as HTMLDetailsElement); - } -}); - -// Accordion opened -new MutationObserver((mutations: MutationRecord[]) => { - for (const mutation of mutations) { - const target = mutation.target as HTMLDetailsElement; - if (target.tagName !== "DETAILS" || !target.classList.contains("accordion")) { - continue; - } - updateMaxHeight(target); - } -}).observe(document.body, { - attributes: true, - attributeFilter: ["open"], - subtree: true, -}); diff --git a/core/templates/core/base.jinja b/core/templates/core/base.jinja index 0d476689..a3afb49f 100644 --- a/core/templates/core/base.jinja +++ b/core/templates/core/base.jinja @@ -27,7 +27,6 @@ - From 96f91138dd0ffe5320178fad7f51b9f5468df3de Mon Sep 17 00:00:00 2001 From: Sli Date: Wed, 11 Jun 2025 00:20:46 +0200 Subject: [PATCH 3/4] Fix accordion transition on chrome --- core/static/core/accordion.scss | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/core/static/core/accordion.scss b/core/static/core/accordion.scss index 17443e5e..c19e10ca 100644 --- a/core/static/core/accordion.scss +++ b/core/static/core/accordion.scss @@ -57,4 +57,17 @@ details[open].accordion>.accordion-content { // will create a strange behavior where the transition // continues without being shown, creating inconsistenties transition: all 300ms ease-out; +} + +// For some reason, it's still not enough for chrome +// We repeat duplicate the transition again but only for chrome +// And since everything with ::details-content crashes firefox +// we put this at the end so it doesn't break the previous code +details.accordion::details-content { + opacity: 0; +} + +details[open].accordion::details-content { + opacity: 1; + transition: all 300ms ease-out; } \ No newline at end of file From 4c67bb1e2a3502b328006303dea3589456d52f92 Mon Sep 17 00:00:00 2001 From: Sli Date: Wed, 11 Jun 2025 01:21:53 +0200 Subject: [PATCH 4/4] Support animation with calc-size and detect browser features --- core/static/core/accordion.scss | 52 +++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/core/static/core/accordion.scss b/core/static/core/accordion.scss index c19e10ca..4f40ba71 100644 --- a/core/static/core/accordion.scss +++ b/core/static/core/accordion.scss @@ -38,8 +38,6 @@ details[open].accordion>summary::before { content: '\f0d7'; } -// ::details-content isn't available on firefox yet -// we use .accordion-content as a workaround details.accordion>.accordion-content { background: #ffffff; color: #333333; @@ -47,27 +45,45 @@ details.accordion>.accordion-content { border: 1px solid #dddddd; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; - opacity: 0; overflow: hidden; } -details[open].accordion>.accordion-content { - opacity: 1; - // Setting a transition on all states of the content - // will create a strange behavior where the transition - // continues without being shown, creating inconsistenties - transition: all 300ms ease-out; +@mixin animation($selector) { + details.accordion#{$selector} { + opacity: 0; + + @supports (max-height: calc-size(max-content, size)) { + max-height: 0px; + } + } + + details[open].accordion#{$selector} { + opacity: 1; + + // Setting a transition on all states of the content + // will create a strange behavior where the transition + // continues without being shown, creating inconsistenties + transition: all 300ms ease-out; + + @supports (max-height: calc-size(max-content, size)) { + max-height: calc-size(max-content, size); + } + } } -// For some reason, it's still not enough for chrome -// We repeat duplicate the transition again but only for chrome -// And since everything with ::details-content crashes firefox -// we put this at the end so it doesn't break the previous code -details.accordion::details-content { - opacity: 0; +// ::details-content isn't available on firefox yet +// we use .accordion-content as a workaround +// But we need to use ::details-content for chrome because it's +// not working correctly otherwise +// it only happen in chrome, not safari or firefox +// Note: `selector` is not supported by scss so we comment it out to +// avoid compiling it and sending it straight to the css +// This is a trick that comes from here : +// https://stackoverflow.com/questions/62665318/using-supports-selector-despite-sass-not-supporting-it +@supports #{'selector(details::details-content)'} { + @include animation("::details-content") } -details[open].accordion::details-content { - opacity: 1; - transition: all 300ms ease-out; +@supports #{'not selector(details::details-content)'} { + @include animation(">.accordion-content") } \ No newline at end of file