CSS height属性从0px转换为auto

哈Ha!

我想分享另一种创建height属性从0pxauto的css过渡的方法。

开发Web组件TreeView和DataGrid时遇到此问题。 在TreeView中,我决定使节点平滑扩展/折叠,并在DataGrid中使行具有附加内容。 阅读互联网后,我发现了几种实现方法,主要是通过max-height和javascript实现的。 javascript的实现被排除在外-CSS支持过渡和动画。 保持max-height ,尤其是在带有下拉菜单的示例中,一切正常。

在TreeView中,每个节点都有无限的嵌套,因此您无法立即确定其内容的最大高度,即使将max-height设置为非常大,过渡动画也会出现问题。 另外,如果展开子节点,则父节点的高度会增加,并且可能与max-height重叠。 不管喜欢与否, max-height不适合。 DataGrid有相同的问题-一行中可以有任何其他内容。 需要height:auto

因此,让我们开始实现height属性从0pxauto的过渡。 考虑一个简单的例子。

让:

  • elBlock: HTMLDivElementelBlock: HTMLDivElement /折叠的块;
  • elToggle: HTMLButtonElement按钮切换状态。

为我们定义内容修剪和过渡本身的块定义一个css类:

 .block { overflow: hidden; transition: height 500ms ease; } 

我们描述elToggleonClick事件onClick

 elToggle.addEventListener("click", () => { if (elBlock.style.height === "0px") { elBlock.style.height = `${ elBlock.scrollHeight }px` } else { elBlock.style.height = `${ elBlock.scrollHeight }px`; window.getComputedStyle(elBlock, null).getPropertyValue("height"); elBlock.style.height = "0"; } }); 

过渡后仍需添加返回height:auto

 elBlock.addEventListener("transitionend", () => { if (elBlock.style.height !== "0px") { elBlock.style.height = "auto" } }); 

好了,仅此而已,现在,块的展开/折叠可以正常进行,而与内容的大小无关。


图1-在TreeView中展开/折叠节点的示例

值得注意的是这种方法的缺点:

  • 使用JavaScript,我只想要CSS;
  • 在过渡期间,内容(其高度, scrollHeight )可能会更改,并且在完成后(如果auto返回),块的高度将在一个方向或另一个方向上发生巨大变化。 为了避免这种影响,您需要跟踪scrollHeight的更改并更改height 。 如实践所示,通常,展开/折叠过渡每个花费0.5 s,在此期间,用户不太可能有时间更改内部的某些内容,例如,对于TreeView,展开子节点。

感谢您的关注!

Source: https://habr.com/ru/post/zh-CN475520/


All Articles