“高度:适合内容”没有 CSS 转换

问题描述 投票:0回答:5

我使用

transition: height 500ms
将动画添加到通过按钮从
height: 0
height: 100px
滑动打开的元素,反之亦然。

由于元素的内容是动态添加的,我不知道它的大小我想改用

height: fit-content
。这样元素将始终具有正确的大小来显示它的内容。

遗憾的是,这会禁用动画。

如何将动画与大小适合其内容的 div 元素结合在一起?

以下片段显示了行为:

document.querySelector('button')
  .addEventListener(
    'click',
    () => document.querySelectorAll('div')
      .forEach(div => div.classList.toggle('closed')));
div {
  background-color: lightblue;
  border: 1px solid black;
  overflow: hidden;
  transition: height 500ms;
}

div.closed {
  height: 0 !important;
}

div.div1 {
  height: 100px;
}

div.div2 {
  height: fit-content;
}
<button type="button">toggle</button>

<h1>'height: 100px' => 'height: 0'</h1>
<div class="div1">
some text<br />
even more text<br />
so much text
</div>

<br>

<h1>'height: fit-content' => 'height: 0'</h1>
<div class="div2">
some text<br />
even more text<br />
so much text
</div>

css animation css-transitions transition slide
5个回答
6
投票

正如 Mishel 所说,另一种解决方案是使用最大高度。这是该解决方案的一个工作示例。

关键是当它完全展开时接近你的最大高度,然后过渡会很平滑。

希望这有帮助。

https://www.w3schools.com/css/css3_transitions.asp

document.querySelector('button')
  .addEventListener(
    'click',
    () => document.querySelectorAll('div')
      .forEach(div => div.classList.toggle('closed')));
div {
  background-color: lightblue;
  border: 1px solid black;
  overflow-y: hidden;
	max-height: 75px; /* approximate max height */
	transition-property: all;
	transition-duration: .5s;
	transition-timing-function: cubic-bezier(1, 1, 1, 1);
}
div.closed {
   max-height: 0;
}
<button type="button">toggle</button>

<h1>'height: 100px' => 'height: 0'</h1>
<div class="div1">
some text<br />
even more text<br />
so much text
</div>

<br>

<h1>'height: fit-content' => 'height: 0'</h1>
<div class="div2">
some text<br />
even more text<br />
so much text
</div>


6
投票

一个可能的解决方案,虽然不是完美的,但动画

font-size
而不是
height
.

另一个解决方案可能是动画

max-height
而不是
height
。你可以使用
max-height
说300px或500px。但如果你需要的不止于此,它看起来就不好看了。

我在这里设置字体大小动画。

希望有帮助。谢谢。

document.querySelector('button')
  .addEventListener(
    'click',
    () => document.querySelectorAll('div')
      .forEach(div => div.classList.toggle('closed')));
div {
  background-color: lightblue;
  border: 1px solid black;
  overflow: hidden;
  transition: font-size 500ms;
}

div.closed {
  font-size: 0 !important;
}

div.div1 {
  font-size: 14px;
}

div.div2 {
  font-size: 14px;
}
<button type="button">toggle</button>

<h1>'height: 100px' => 'height: 0'</h1>
<div class="div1">
some text<br />
even more text<br />
so much text
</div>

<br>

<h1>'height: fit-content' => 'height: 0'</h1>
<div class="div2">
some text<br />
even more text<br />
so much text
</div>


0
投票

我解决问题的方法是计算孩子的身高

document.querySelector('.button1').addEventListener('click',
  () => document.querySelector('.div1').classList.toggle('closed'));

document.querySelector('.button2').addEventListener('click',
  () => document.querySelector('.div2').classList.toggle('closed'));

let extendedHeight = 0;
let div2 = document.querySelector('.div2')
for (let i = 0; i < div2.children.length; i++) {
  extendedHeight += div2.children[i].offsetHeight;
}

div2.style.setProperty('--extended-height', extendedHeight.toString() + "px")
div {
  background-color: lightblue;
  border: 1px solid black;
  overflow: hidden;
  transition: 500ms;
}

div.div1.closed {
  max-height: 0 !important;
}

div.div1 {
  max-height: 1000px;
}

div.div2.closed {
  height: 0 !important;
}

div.div2 {
  --extended-height: 0px;
  height: var(--extended-height);
}
<button type="button" class="button1">toggle</button>

<h1>'height: over predicted' => 'height: 0'</h1>
<div class="div1">
  <p>
  some text <br> even more text <br> so much text <br><br>
  </p>
</div>

<button type="button" class="button2">toggle</button>

<h1>'height: calculated' => 'height: 0'</h1>
<div class="div2">
  <p>some text <br> even more text <br> so much text <br><br>
  </p>
</div>

如果高度超过预期,那么动画看起来会很糟糕,但如果高度计算和设置完美,动画将正常工作并且看起来很完美。

为此,我使用

offsetHeight
计算了 div 的所有子项的高度,它返回元素的
height
然后我将我制作的自定义 CSS 变量 
+
 设置为所有孩子的身高
如果 div 具有彼此相邻的不同元素,您可能会遇到问题,而我解决该问题的方法只是获取彼此相邻的元素的最大元素的
padding-top
。就我而言,我只是使用了所有其他元素的
+

谢谢

你可以尝试使用变换:scaleY(0) -> scale(1)
它有点像高度一样。

我用这个:

border-top

0
投票
+

margin-top

0
投票

只要确保高度大于内容本身所占的高度,内容就会自动分布。 这也可以与 flex-direction:row 一起使用,操纵宽度而不是高度,只需对 justify-content 和 align-items 进行小的更改
我不喜欢将高度从 0 过渡到适合内容的最大高度解决方案,因为如果我低估了它会切断内容,如果我高估了过渡看起来很奇怪。
这是我组合的 CSS + JS 解决方案:
--extended-height

© www.soinside.com 2019 - 2024. All rights reserved.