Merge pull request #1114 from ae-utbm/accordions

Improve accordion animation
This commit is contained in:
Bartuccio Antoine 2025-06-11 14:00:46 +02:00 committed by GitHub
commit 7b778d3e6b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 39 additions and 31 deletions

View File

@ -1,25 +0,0 @@
const setMaxHeight = (element: HTMLDetailsElement) => {
element.setAttribute("style", `max-height: ${element.scrollHeight}px`);
};
// Initialize max-height at load
window.addEventListener("DOMContentLoaded", () => {
for (const el of document.querySelectorAll("details.accordion")) {
setMaxHeight(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;
}
setMaxHeight(target);
}
}).observe(document.body, {
attributes: true,
attributeFilter: ["open"],
subtree: true,
});

View File

@ -38,18 +38,52 @@ 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;
padding: 1em 2.2em;
overflow: auto;
border: 1px solid #dddddd;
border-bottom-right-radius: 3px;
border-bottom-left-radius: 3px;
overflow: hidden;
}
details.accordion {
transition: max-height 300ms ease-in-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);
}
}
}
// ::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")
}
@supports #{'not selector(details::details-content)'} {
@include animation(">.accordion-content")
}

View File

@ -27,7 +27,6 @@
<script type="module" src="{{ static('bundled/htmx-index.js') }}"></script>
<script type="module" src="{{ static('bundled/country-flags-index.ts') }}"></script>
<script type="module" src="{{ static('bundled/core/tooltips-index.ts') }}"></script>
<script type="module" src="{{ static('bundled/core/accordion-index.ts') }}"></script>
<!-- Jquery declared here to be accessible in every django widgets -->
<script src="{{ static('bundled/vendored/jquery.min.js') }}"></script>