【问题标题】:Transitioning between open close in details element在详细信息元素中打开关闭之间的转换
【发布时间】:2013-06-22 11:35:46
【问题描述】:

是否可以仅使用 CSS 为 <details> 元素的打开/关闭状态之间的过渡设置动画?

【问题讨论】:

标签: html css


【解决方案1】:

不,目前没有。是的,但前提是您知道height 或可以为font-size 设置动画。

最初情况并非如此。来自http://html5doctor.com/the-details-and-summary-elements/“...如果您可以使用 CSS 过渡来为打开和关闭设置动画,但我们现在还不能。”(HTML5 医生在结尾处有一条评论,但它似乎需要 JS 来强制 CSS 动画。)

可以根据它是打开还是关闭来使用不同的样式,但是过渡没有正常“采用”。然而,今天,如果您知道height 或可以为font-size 设置动画,则转换确实有效。有关示例和更多详细信息,请参阅 http://codepen.io/morewry/pen/gbJvy

这是 2013 年的解决方案,有点假:

CSS(可能需要加前缀)

/* http://daneden.me/animate/ */
@keyframes fadeInDown {
    0% {
        opacity: 0;
        transform: translateY(-1.25em);
    }
    100% {
        opacity: 1;
        transform: translateY(0);
    }
}
.details-animated[open] {
    animation-name: fadeInDown;
    animation-duration: 0.5s;
}

HTML

<details class="details-animated">
    <summary>CSS Animation - Summary</summary>
    Try using [Dan Eden's fadeInDown][1] to maybe fake it a little.  Yay, some animation.
</details>

今天有效:

CSS(可能需要加前缀)

.details-animated {
  transition: height 1s ease;
}
.details-animated:not([open]) { height: 1.25em; }
.details-animated[open] { height: 3.75em; }

PS:仅在 Chrome 中测试。听说 FF 一般还是不支持details IE 和 Edge 79 之前的版本还是不支持details

(您可以使用关键帧动画或转场来做各种其他动画打开。我选择fadeInDown 仅用于说明目的。这是一个合理的选择,如果您无法添加也会给出类似的感觉额外的标记或不知道内容的高度。但是,您的选择不仅限于此:请参阅此答案中的 cmets,其中包括两种选择,包括 font-size 方法。)

【讨论】:

  • 很遗憾它不起作用。顺便说一句,我在小提琴中复制了您的示例,但它没有用,我没有看到任何变化。
  • 它适用于我,但它只适用于-webkit-moz-o(这是一个精简代码示例)。直到现在我还在编辑它。 Codepen.io 有一个 CSS 的“无前缀”选项——我不记得 JSFiddle 有没有?验证最新代码并可能想尝试添加前缀。
  • 对不起,我没有检查前缀。
  • (可选)为font-size 设置动画效果,如stackoverflow.com/a/30531678/923745 以进行视觉扩展。
  • 这是一个很好的技术,但在这种情况下存在问题。首先,示例中使用的 CSS 过渡不起作用,不仅仅是因为 height 问题。在details 上使用opacity: 0 将隐藏summary 并且font-size: 0 将被summary 继承。这使得summary:not([open]) 时不可见,因此无法打开(或者单击后它会不和谐地消失)。这些问题必须通过关键帧动画、额外的包装元素和额外的样式来解决。在可能的情况下,它确实有助于提高身高;那谢谢啦!我把它加到笔里了。
【解决方案2】:

我的简短回答是:您不能在摘要和其他详细信息内容之间进行转换。

但是!

您可以在选择器 detailsdetails[open]

之间的摘要内进行一些不错的转换

details{
  position: relative;
  width: 100px;height: 100px;
  perspective: 1000px;
}
div{
  position: absolute;
  top: 20px;
  width: 100px;height: 100px;
  background: black;
}
details .transition{
  transition: 1s linear;
  transform-origin: right top;
  ;
}
details[open] .transition{
  transform: rotateY(180deg);
  background: orangered;
}
<details>
  <summary>
    <div></div>
    <div class="transition"></div>
  </summary>
</details>

注意:我回答这个问题是因为这是谷歌搜索的第一个结果!

【讨论】:

    【解决方案3】:

    鉴于高度必须在某个点捕捉,我更喜欢开始为高度设置动画然后捕捉。如果您有幸让所有元素的高度相似,则此解决方案可能非常有效。 (不过,您的详细信息元素中确实需要一个 div)

    @keyframes slideDown {
        0% {
            opacity: 0;
            height: 0;
        }
        100% {
            opacity: 1;
            height: 20px; /* height of your smallest content, e.g. one line */
        }
    }
    details {
        max-width:400px;
    }
    details[open]>div {
        animation-name: slideDown;
        animation-duration: 200ms;
        animation-timing-function:ease-in;
        overflow:hidden;
    }
    

    例如见http://dabblet.com/gist/5866920

    【讨论】:

    • 链接错误。请添加一个sn-p来替换它
    【解决方案4】:

    当然可以:

    DETAILS[open] SUMMARY ~ * {
      animation: sweep 3s ease-in-out;
    }
    
    @keyframes sweep {
      0% {
        opacity: 0;
        margin-left: -10px
      }
      100% {
        opacity: 1;
        margin-left: 0px
      }
    }
    <details>
      <summary>Summary content</summary>
      Test test test test.
    </details>

    【讨论】:

    • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。请阅读此how-to-answer 以提供高质量的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-15
    • 1970-01-01
    • 2017-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多