寻求一种优雅的、纯 CSS 的方法来隐藏/显示自动高度内容(带过渡)

Posted

技术标签:

【中文标题】寻求一种优雅的、纯 CSS 的方法来隐藏/显示自动高度内容(带过渡)【英文标题】:Seeking an elegant, CSS-only method for hiding/showing auto-height content (with transitions) 【发布时间】:2011-11-26 05:50:01 【问题描述】:

我想要一种仅使用 CSS 过渡的方法,以便在悬停时有效(且有吸引力地)隐藏/显示内容。

需要注意的是我希望保持动态(自动)高度。

似乎最佳路线是在 fixed height:0height:auto 之间转换,但可惜浏览器中的转换尚不支持。

对 cme​​ts 的澄清 :: 这与其说是等到所有现存的浏览器都兼容 CSS3,不如说是解决 CSS3 本身的一个明显缺陷(例如,缺少height:0 > height:auto)

我已经探索了一些其他方法,可以在下面的小提琴中查看(并在下面详细说明),但它们都不能让我满意,我希望得到其他方法的反馈/提示。

http://jsfiddle.net/leifparker/PWbXp/1/

基础 CSS

.content
    -webkit-transition:all 0.5s ease-in-out;  
    -moz-transition:all 0.5s ease-in-out;
    transition:all 0.5s ease-in-out;
    overflow:hidden;


变体 #1 - 最大高度黑客
.content  max-height:0px; 
.activator:hover +.content max-height:2000px; 

缺点

a.您需要任意设置一个上限max-height,该上限包含大量动态内容,可能会截断信息。

b. 如果为了预防 (a),您需要设置 非常 较高的上限 max-height ,动画延迟变得尴尬,而且难以维持,因为浏览器会无形地转换整个距离。也会降低缓动的视觉效果。


变体 #2 - 填充和增长的错觉
.content  padding:0px; height:0px; opacity:0; 
.activator:hover +.content  padding:10px 0px; height:auto; opacity:1; 

缺点

a. 很刺耳。这绝对比直接弹出内容要好一些,并且通过过渡不透明度进一步销售效果,但总体上它在视觉上并没有那么流畅。


变体 #3 - 错误的仅宽度方法
.content  width:0%; 
.activator:hover +.content width:100%; 

缺点

a.随着宽度的缩小,换行会将任何额外的文本强制到后续行,我们最终会得到一个超高的不可见 div,它仍然需要空间。


变体 #4 - 有效但紧张的字体大小
.content   font-size:0em; opacity:0; 
.activator:hover +.content  font-size:1em; opacity:1; 

缺点

a.虽然这具有很好的全面效果,但随着字体的增长,换行的移动会导致不吸引人的抖动。

b. 这仅适用于由文本组成的内容。需要添加其他转换来管理输入和图像的缩放,虽然完全可行,但这会削弱简单性。


变体 #5 - 线高的黄油性
.content  line-height:0em; opacity:0; 
.activator:hover +.content line-height:1.2em; opacity:1; 

缺点

a.我最喜欢的美学,但与#4一样,这最简单地适用于纯文本内容。


变体 #6 - 反保证金(@graphicdivine 提供)
.wrapper_6  min-height: 20px 
.wrapper_6 .activator z-index:10; position: relative
.wrapper_6 .content  margin-top: -100%; 
.wrapper_6 .activator:hover +.content margin-top: 0 

缺点

a. 悬停时有延迟,这不是最佳的。这是.content 被隐藏在屏幕上很远的地方的结果,并且在出现之前需要时间向下动画。

b. margin-top: -100% 相对于包含元素的宽度。因此,对于流畅的设计,当窗口缩小得非常小时,margin-top 可能不足以将.content 隐藏起来。


正如我之前所说,如果我们能在height:0height:auto 之间转换,这一切都没有实际意义。

在那之前,有什么建议吗?

谢谢! 雷夫

【问题讨论】:

在这种情况下使用 JS 有什么好处? 哈!引用那个众所周知的登山者,“因为它就在那里”。 -- 我想,它只是觉得它应该优雅地可行,并且渴望简单。 使用 javascript 您可能会避免一些跨浏览器和向后兼容性问题。由于现在很多网页都使用 jQuery,我认为使用它不会有害。我想最好等到更多人使用支持 css3 的浏览器 :)。关于建议,我似乎对您的帖子没有任何补充。 你可以不代表你应该:) @DA。我认为我同意这种观点,除了 JS 应该处理高度计算的想法。浏览器已经原生地处理了这个(height : auto),看起来很尴尬的疏忽,为了这个目的使用 CSS 过渡意味着放弃原生的易用性。 【参考方案1】:

试试这个,反保证金

.wrapper_6  min-height: 20px 
.wrapper_6 .activator z-index:10; position: relative
.wrapper_6 .content  margin-top: -100%; 
.wrapper_6 .activator:hover +.content margin-top: 0 

http://jsfiddle.net/PWbXp/

【讨论】:

哦!我喜欢。我唯一的疑虑是,由于内容从“激活器”下方出现所需的时间,因此翻转会有轻微延迟;与ease-in 打得不好。否则,非常好。 经过一些测试,现在意识到延迟实际上是因为.content 隐藏在页面很远的地方。 margin:-100% 实际上太随意了,因为它与包含元素的宽度有关(而不是与它自己的高度有关)。这对于流体设计来说尤其成问题,因为容器的宽度可以缩小到足以将“反边距”.content 推入可见区域。此处说明:jsfiddle.net/leifparker/PWbXp/1(尝试缩小窗口宽度,您会看到“反边距”示例失败)。德拉特。不过谢谢! 我认为一些使用 box-sizing 规则的人应该可以解决其中的一些问题...?【参考方案2】:

嗯...我知道这已经有一段时间了,但我需要使用高度动画,并且相信很多其他程序员仍然需要或/并且将需要这样做。

所以,我来到这里是因为当用户悬停单元格时,我需要在单元格表中显示产品描述的模式详细信息。在没有用户悬停的情况下,最多只显示 2 行描述。一旦用户将鼠标悬停,所有行(文本可以是 1 到 8 行,动态且不可预测的长度)必须以某种高度动画显示。

我遇到了同样的困境,并选择使用最大高度转换(设置一个高最大高度,我确信这不会削减我的文本),因为这种方法在我看来是最干净的解决方案为高度设置动画。

但我对“上滑”动画的延迟不满意,就像你一样。 那时我在这里找到了关于过渡曲线的评论:http://css3.bradshawenterprises.com/animating_height/。

这家伙的idea很牛逼,但是单单这个方案就“截断”了“滑下”动画的效果。所以稍微思考了一下,我就得出了最终的解决方案。

这是我使用 Rhys 的想法的解决方案(上面链接的人):

向下滑动动画(悬停),带有“平滑增长”和向上滑动动画没有(实际上)“延迟”:

div 
  background-color: #ddd;
  width: 400px;
  overflow: hidden;
  -webkit-transition: max-height 1.5s cubic-bezier(0, 1.05, 0, 1);
  -moz-transition: max-height 1.5s cubic-bezier(0, 1.05, 0, 1);
  transition: max-height 1.5s cubic-bezier(0, 1.05, 0, 1);
  max-height: 38px;

div:hover 
  -webkit-transition: max-height 2s ease;
  -moz-transition: max-height 2s ease;
  transition: max-height 2s ease;
  max-height: 400px;
<div>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris ac lorem ante. Vestibulum quis magna pretium, lacinia arcu at, condimentum odio. Ut ultrices tempor metus, sit amet tristique nibh vestibulum in. Pellentesque vel velit eget purus mollis
  placerat sed sit amet enim. Sed efficitur orci sapien, ac laoreet erat fringilla sodales.
</div>

这是一个简单的JsFiddle

这是您的JsFiddle 更新(确实是其中的一部分)

这是一个完美的(在我看来)菜单、描述和一切不是非常不可预测的解决方案,但正如您之前指出的那样,需要设置一个较高的最大高度,并且可能会被截断一个惊人的高动态内容。在这种特定情况下,我将使用 jQuery/JavaScript 来为高度设置动画。由于内容的更新已经使用某种 JavaScript 来完成,所以我看不出使用 Js 动画方法有什么坏处。

希望我能帮助到那里的人!

【讨论】:

这很漂亮!我把你的 sn-p 放到一个可运行的 Stack Snippet 中;无需依赖演示的小提琴链接:) 谢谢@misterManSam!感谢 Stack Snippet,我不知道 *** 的这个功能……这就是我喜欢的地方,你在自己的答案中学到了一些新东西! :)【参考方案3】:

你应该使用 scaleY。

html

<p>Here (scaleY(1))</p>
<ul>
  <li>Coffee</li>
  <li>Tea</li>
  <li>Milk</li>
</ul>

CSS:

ul 
    background-color: #eee;
    transform: scaleY(0);    
    transform-origin: top;
    transition: transform 0.26s ease;


p:hover ~ ul 
    transform: scaleY(1);

我在 jsfiddle 上制作了上述代码的供应商前缀版本,http://jsfiddle.net/dotnetCarpenter/PhyQc/9/

【讨论】:

这种方法的问题是元素在全高时应该占据的空间仍然被占用。因此,如果您正在构建可折叠菜单,则不能使用它。

以上是关于寻求一种优雅的、纯 CSS 的方法来隐藏/显示自动高度内容(带过渡)的主要内容,如果未能解决你的问题,请参考以下文章

Css 仅条纹文本阴影效果

CSS3:根据节点内容显示/隐藏

css怎样让HTML中超出的内容显示为省略号

请问用CSS如何控制自动隐藏多余的内容?

css轻松搞定显示隐藏的效果

css div 隐藏网站内容