diff --git a/Build/Sources/TypeScript/backend/page-actions.ts b/Build/Sources/TypeScript/backend/page-actions.ts index d2556a7f6d3f98fa90eee1ad7aba7877b06a6508..552f1447e1ec47cb04c0097f0cfd9cf17946ff58 100644 --- a/Build/Sources/TypeScript/backend/page-actions.ts +++ b/Build/Sources/TypeScript/backend/page-actions.ts @@ -42,21 +42,27 @@ class PageActions { me.disabled = true; for (const hiddenElement of hiddenElements) { - hiddenElement.style.display = 'block'; + hiddenElement.style.display = 'flow-root'; const scrollHeight = hiddenElement.scrollHeight; - hiddenElement.style.display = ''; + + // Always set `overflow: clip` after storing scrollHeight + // * For hidden state `height: 0px` is already set. + // * For visible state setting `overflow: clip` is fine anyway. + hiddenElement.style.overflow = 'clip'; if (!me.checked) { - // Spacing between content elements is kept uniform by collapsed margins, - // hidden elements have a height of 0 and the margins of the surrounding elements - // cannot collapse, causing a visual gap. We therefore remove the element - // from the flow to prevent this. + // * Invisible elements must not be accessible/focusable by keyboard. + // * Spacing between content elements is kept uniform by collapsed margins, + // hidden elements have a height of 0 and the margins of the surrounding elements + // cannot collapse, causing a visual gap. + // Therefore do not display the element at all by setting `display: none`. hiddenElement.addEventListener('transitionend', (): void => { - hiddenElement.style.position = 'absolute'; + hiddenElement.style.display = 'none'; + hiddenElement.style.overflow = ''; }, { once: true }); - // We use requestAnimationFrame() as we have to set the container's height at first before resizing to 0px - // results in a smooth animation. + // We use requestAnimationFrame() as we have to set the container's height at first before resizing to + // collapsed-element-height. This results in a smooth animation. requestAnimationFrame(function() { hiddenElement.style.height = scrollHeight + 'px'; requestAnimationFrame(function() { @@ -64,7 +70,12 @@ class PageActions { }); }); } else { - hiddenElement.style.position = ''; + hiddenElement.addEventListener('transitionend', (): void => { + hiddenElement.style.display = ''; + hiddenElement.style.overflow = ''; + hiddenElement.style.height = ''; + }, { once: true }); + hiddenElement.style.height = scrollHeight + 'px'; } } diff --git a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html index 2d1304484f53326022c61e0279c69c1f9a1d87ee..ea41eabc1961abf75ec4e79d6f2fc616fce440f7 100644 --- a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html +++ b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html @@ -1,4 +1,4 @@ -{f:if(condition: '{item.disabled} && {item.context.drawingConfiguration.showHidden} == 0', then: 'height: 0; position: absolute;') -> f:variable(name: 'style')} +{f:if(condition: '{item.disabled} && {item.context.drawingConfiguration.showHidden} == 0', then: 'height: 0; display: none;') -> f:variable(name: 'style')} <div class="t3-page-ce {item.wrapperClassName} t3js-page-ce t3js-page-ce-sortable" id="element-tt_content-{item.record.uid}" data-table="tt_content" data-uid="{item.record.uid}" data-language-uid="{item.record.sys_language_uid}" style="{style}"> <div class="t3-page-ce-element t3-page-ce-dragitem"> <f:render partial="PageLayout/Record/{item.record.CType}/Header" arguments="{_all}" optional="1"> diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/page-actions.js b/typo3/sysext/backend/Resources/Public/JavaScript/page-actions.js index a16ba5b5c15c29467cc2f83d495f9391121ed299..bbc9b5358694499a18d11b97b6db74eefc2f3acc 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/page-actions.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/page-actions.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import DocumentService from"@typo3/core/document-service.js";import RegularEvent from"@typo3/core/event/regular-event.js";import PersistentStorage from"@typo3/backend/storage/persistent.js";var IdentifierEnum;!function(e){e.hiddenElements=".t3js-hidden-record"}(IdentifierEnum||(IdentifierEnum={}));class PageActions{constructor(){DocumentService.ready().then((()=>{const e=document.getElementById("checkShowHidden");null!==e&&new RegularEvent("change",this.toggleContentElementVisibility).bindTo(e)}))}toggleContentElementVisibility(e){const t=e.target,n=document.querySelectorAll(IdentifierEnum.hiddenElements);t.disabled=!0;for(const e of n){e.style.display="block";const n=e.scrollHeight;e.style.display="",t.checked?(e.style.position="",e.style.height=n+"px"):(e.addEventListener("transitionend",(()=>{e.style.position="absolute"}),{once:!0}),requestAnimationFrame((function(){e.style.height=n+"px",requestAnimationFrame((function(){e.style.height="0px"}))})))}PersistentStorage.set("moduleData.web_layout.showHidden",t.checked?"1":"0").then((()=>{t.disabled=!1}))}}export default new PageActions; \ No newline at end of file +import DocumentService from"@typo3/core/document-service.js";import RegularEvent from"@typo3/core/event/regular-event.js";import PersistentStorage from"@typo3/backend/storage/persistent.js";var IdentifierEnum;!function(e){e.hiddenElements=".t3js-hidden-record"}(IdentifierEnum||(IdentifierEnum={}));class PageActions{constructor(){DocumentService.ready().then((()=>{const e=document.getElementById("checkShowHidden");null!==e&&new RegularEvent("change",this.toggleContentElementVisibility).bindTo(e)}))}toggleContentElementVisibility(e){const t=e.target,n=document.querySelectorAll(IdentifierEnum.hiddenElements);t.disabled=!0;for(const e of n){e.style.display="flow-root";const n=e.scrollHeight;e.style.overflow="clip",t.checked?(e.addEventListener("transitionend",(()=>{e.style.display="",e.style.overflow="",e.style.height=""}),{once:!0}),e.style.height=n+"px"):(e.addEventListener("transitionend",(()=>{e.style.display="none",e.style.overflow=""}),{once:!0}),requestAnimationFrame((function(){e.style.height=n+"px",requestAnimationFrame((function(){e.style.height="0px"}))})))}PersistentStorage.set("moduleData.web_layout.showHidden",t.checked?"1":"0").then((()=>{t.disabled=!1}))}}export default new PageActions; \ No newline at end of file