【问题标题】:CSS Transition with truncated multiline text带有截断多行文本的 CSS 过渡
【发布时间】:2019-08-21 07:44:22
【问题描述】:

我有以下代码snippet:

如您所见,有一个截断的多行文本,如果单击它会展开。我还为 max-height 添加了一个过渡,以实现平滑切换。

input[type='checkbox'] {
  display: none;
}

.flexbox {
  display: flex;
  flex-flow: row wrap;
  background-color: green;
}

.lbl-toggle {
  max-height: 30px;
  transition: max-height 1s ease-in-out;
}

.truncate {
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}

.toggle:checked+.lbl-toggle {
  max-height: 350px;
}

.toggle:checked+.lbl-toggle>span {
  text-overflow: initial;
  overflow: initial;
  white-space: initial;
}
<div>
  <input id="collapsible" class="toggle" type="checkbox">
  <label for="collapsible" class="flexbox lbl-toggle">
    <span class="truncate">Text here is very very long that it might get truncate if this box get resized too small. Text here is very very long that it might get truncate if this box get resized too small</span>
  </label>
</div>

但是,whitespace-property 在与 max-height 和过渡的交互方面存在问题。只有最初的过渡有效,之后不再有效。我想如果我正在应用,那么截断并设置white-space: nowrap 我的 max-height 不再应用并且转换中断。

我唯一的想法是,当空白属性与 JS 一起应用时,我需要延迟。但是,我不想使用 JS。还有其他解决方案吗?

【问题讨论】:

  • 你不想使用 JS 有确切的理由吗?请注意,在这里它适用于第一次之后的扩展过渡,但只是您需要在最小化标签后等待整整一秒钟(max-height 1s ease-in-out;)。如果没有转换最小化是正常的,因为white-space: nowrap 可能会影响height 而不是max-height

标签: html css whitespace transition


【解决方案1】:

遗憾的是,max-height 输入/输出转换的不一致是 CSS 中的一个众所周知的问题 - this article 很好地解释了这个问题,并提供了一些可能有用的替代方案。

【讨论】:

  • 感谢这篇文章。它很好地指出了不同的用例。很遗憾,我无法使用没有 JS 的翻译。
  • 别担心@Theiaz,祝你好运!
【解决方案2】:

一种解决方案是去掉省略号并将折叠的最大高度设置为行高,省略号和行高迫使您使用white-space: nowrap;,这是过渡不起作用的罪魁祸首适当地。 注意如果你真的想用这个类控制这个属性,max-height 属性也应该应用于 span (.truncate)(在我的代码中,我应用于所有内部元素)

正如您正确猜到的那样,另一种解决方案是使用 JS,我真的不明白您为什么要避免。脚本并不复杂,你不需要一个假的复选框。

input[type='checkbox'] {
  display: none;
}

.flexbox {
  display: flex;
  flex-flow: row wrap;
  background-color: green;
}

.lbl-toggle/*, .lbl-toggle > **/ {
  max-height: 18px;
  transition: max-height 1s ease-in-out;
}

.truncate {
  overflow: hidden;
}

.toggle:checked+.lbl-toggle/*, .toggle:checked+.lbl-toggle > **/ {
  max-height: 350px;
}

.toggle:checked+.lbl-toggle > .truncate {
  overflow: initial;
}
<div>
  <input id="collapsible" class="toggle" type="checkbox">
  <label for="collapsible" class="flexbox lbl-toggle">
    <span class="truncate">Text here is very very long that it might get truncate if this box get resized too small. Text here is very very long that it might get truncate if this box get resized too small</span>
  </label>
</div>

JS 解决方案:

var collapsibles = document.getElementsByClassName('lbl-toggle'),
    i, l = collapsibles.length;

for(i = 0; i < l; i++){
  collapsibles[i].onclick = function(){
    var self = this;
    if(self.classList.contains('expanded')){
      self.classList.remove('expanded');
      setTimeout(function(){
        //the if is a safety in case of many rapid clicks
        if(!self.classList.contains('expanded')){
          self.classList.add('nowrap');
        }
      }, 1000);
    }else{
      self.classList.add('expanded');
      self.classList.remove('nowrap');
    }
  };
}
.flexbox {
  display: flex;
  flex-flow: row wrap;
  background-color: green;
}

.lbl-toggle {
  max-height: 30px;
  transition: max-height 1s ease-in-out;
}

.nowrap .truncate{
  white-space: nowrap;
}

.truncate {
  text-overflow: ellipsis;
  overflow: hidden;
}

.expanded {
  max-height: 350px;
}

.expanded > .truncate {
  text-overflow: initial;
  overflow: initial;
}
<div>
  <label class="flexbox lbl-toggle nowrap">
    <span class="truncate">Text here is very very long that it might get truncate if this box get resized too small. Text here is very very long that it might get truncate if this box get resized too small</span>
  </label>
</div>

【讨论】:

  • 我不想用JS来保持应用程序的过载尽可能小。此外,这种转变对我来说更是一个附加问题和个人问题。但是,感谢这个例子!
猜你喜欢
  • 1970-01-01
  • 2015-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
  • 2019-08-16
相关资源
最近更新 更多