在 flexbox 中过渡 flex-grow 项目

Posted

技术标签:

【中文标题】在 flexbox 中过渡 flex-grow 项目【英文标题】:Transition flex-grow of items in a flexbox 【发布时间】:2015-06-19 22:14:57 【问题描述】:

是否可以转换 flexbox 中的项目? 当您单击时,我希望所有项目都折叠,但单击的项目除外。 单击的那个应该使用容器中的所有可用空间。

// only works once!
$(".item").click(function() 
  $(".item").not(this).each(function() 
    $(this).addClass("collapse");
  );
);
html, body 
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  overflow: hidden;

.container 
  flex-grow: 1;
  flex-shrink: 0;
  flex-basis: auto;
  display: flex;
  flex-direction: column;
  height: 100%;

.item 
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: auto;
  transition: all 2s;

.collapse 
  flex-grow: 0;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div class="item" style="background: red">a</div>
  <div class="item" style="background: green">b</div>
  <div class="item" style="background: blue">c</div>
  <div class="item" style="background: purple">d</div>
</div>

JSFiddle:http://jsfiddle.net/clankill3r/L8hktsgn/

【问题讨论】:

你不能将flex-grow从/到0转换。oli.jp/2010/css-animatable-properties 谁能告诉我为什么 jQuery 的 animate 方法在这种情况下不起作用? 【参考方案1】:

flex-grow is animatable 但仅当值为 &lt;number&gt; 时。但是,如果将值设置为 0,Google Chrome (v41) 似乎不会触发动画。

解决方法可能是使用一个非常小的值,例如 0.0001:

Updated example.

$(".item").click(function() 
    $(".item").addClass("collapse");
    $(this).removeClass("collapse");    
);
html, body 
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    border: 0;
    overflow: hidden;    


.container 
    flex-basis: auto;
    display: flex;
    flex-direction: column;
    height: 100%;


.item 
    flex-grow: 1;
    flex-shrink: 1;
    flex-basis: auto;
    transition: all 2s;


.collapse 
    flex-grow: 0.001;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
    <div class="item" style="background: red">a</div>
    <div class="item" style="background: green">b</div>
    <div class="item" style="background: blue">c</div>
    <div class="item" style="background: purple">d</div>
</div>

【讨论】:

这只是我的印象,还是在转换 flex-grow 时忽略了 transition-timing-function(我无法真正区分缓动之间的区别)? @nils 它似乎工作正常(在 Chrome 46 中测试)。可以通过在开发工具中使用三次贝塞尔编辑器来验证,例如:cubic-bezier(0.19, 1.41, 0.54, -0.43) 作为计时功能。 如果我们不能使用 flex-grow,因为我们的容器没有定义高度怎么办?我的用例是我想构建一个 toast 系统(用户反馈系统),可以同时显示 3 个 toast。当第一个 toast 消失时,第二个应该通过动画将自己定位到第一个 toast 的先前位置。有什么想法吗? 很好地抓住了 0.0001,这是我们必须编写的常见的讨厌的猴子补丁之一。 刚刚发现这会在 IE11 上中断。所以你可能不应该使用它,除非你可以排除 IE 用户。【参考方案2】:
$(".item").click(function() 
    $(this).removeClass('collapse');
    $(".item").not(this).each(function() 
        $(this).addClass("collapse");    
    );


);

您可以将 flex-grow 动画从 20 变为 1

.item 
    flex-grow: 20;
    transition: all 1s;


.collapse 
    flex-grow: 1;


http://jsfiddle.net/L8hktsgn/11/

【讨论】:

我在动画中添加了 jsfiddle【参考方案3】:

如果你只想要一行,这可以工作https://codepen.io/balvin/pen/gKrXdM,但如果你想包装它们,你可以使用https://codepen.io/balvin/pen/wXGyYw 似乎这是一个 hack,但设置 width:0;flex-grow:1 是解决方案,但是为了包装元素,您需要明确告诉浏览器 width,因为它不知道您希望元素包装的宽度,考虑到这一点,您只需使用 setTimeout。检查代码

【讨论】:

【参考方案4】:

您可以使用max-height

.item

  max-height:100%;


.collapse

  max-height: 64px;

http://jsfiddle.net/L8hktsgn/9/

【讨论】:

以上是关于在 flexbox 中过渡 flex-grow 项目的主要内容,如果未能解决你的问题,请参考以下文章

没有行的 Flexbox 垂直网格/仪表板

文本正在调整 flexbox 子项的大小而不是换行(使用 flex-grow)[重复]

理由 - 内容和flex-grow被忽略

flex-grow 和 width 有啥区别?

溢出:隐藏在 Flexbox 中无法按预期工作

4手把手教React Native实战之flexbox布局(伸缩属性)