如何重置flex项的'display'属性

16

我正在尝试将基于表格和JS的旧布局转换为新的Flexbox,并通过在旧浏览器(特别是IE8、IE9和Opera 10+)中保留表格实现向后兼容性。

问题是没有 display:flex-item 来覆盖旧样式的 display:table-cell

我已经尝试了各种定义,如 display:inheritdisplay:initial,但都无法重新设置显示定义以正确地工作为flex-item。

<!-- HTML user list -->
<div class="userDetails layout">
    <div class="picture"><img src="..."></div>
    <div class="details">username, email, etc.</div>
</div>

/* CSS Table Layout */
.layout { display: table; width: 100%; }
.layout > .picture { display: table-cell; width: 30%; }
.layout > .details { display: table-cell; width: auto; }

/* CSS Flexbox - ignored by browsers that does not support it */
/* just an example - should use all versions for best compatibility */
.layout { display: flex; }
.layout > .picture { display: ???; flex: 0 1 30%; }
.layout > .details { display: ???; flex: 1 1 auto; }
无论我在.details中设置什么显示方式,它都不能作为flex项目工作,并且不会增长以填充剩余空间。 有什么办法可以在不使用JS检测浏览器版本并切换样式的情况下覆盖此设置吗? 我已经尝试过搜索解决方案,但大多数结果只是关于Flexbox的一般文章;唯一相似的是这个测试,但它并没有解决向后兼容性。 更新1: 这是一个纯Flexbox和结合表格布局的JSFiddle演示。如果你调整结果窗口的大小,纯布局会与组合表格和Flexbox的底部不同程度地缩小。 注意:在Chrome中,这个工作是正确的,在Firefox、IE、Safari等中尝试一下。 更新2: Safari使用前缀定义可以正常工作...更新的JSFiddle演示
3个回答

15
如Danield所述,flex容器(由display:flexdisplay:inline-flex指定)的所有子元素都会自动成为flex项目。没有用于flex项目的display属性;相反,您可以根据需要设置它为其他值,具体取决于您希望flex项目的子元素如何布局。如果浏览器识别display:flex-item,那么它们可能有一些奇怪的非标准实现的" flexbox",因为该值从未存在于任何Flexbox规范的版本中(如果存在,我不知道它将对应什么)。 display的初始值是inline,因此display:initial等同于display:inline。请参见这个答案。您要尝试的是将元素重置为浏览器给出的默认display值。您需要预先知道此值;对于div元素,它的值为display:block
不幸的是,由于明显的原因,这将覆盖所有浏览器中现有的table-cell声明。在这种情况下,如果已经适用于您并且需要支持不支持flexbox的浏览器,则最好坚持表格布局。

你是正确的,在普通页面设置下,将flex-item设置为block或inline可以正常工作。不幸的是,我的页面布局非常混乱,以至于浏览器非常困惑,不知道如何正确地布局它。我必须重新设计整个页面,只使用flexbox :( . - Radek Pech

5

在容器元素上设置display:flex后,子元素会自动成为弹性项目,因此不存在display:flex-item

这里有一个演示,展示了子元素上的display:table-cell不会影响子元素的弹性属性功能。

编辑:对于Firefox和IE浏览器,如果在display:table-cell规则之后添加规则display:flex,那么子元素上的display:table-cell就不会影响子元素的弹性属性功能。

/* flex layout with display:table falllback */

.layout {
  display: table; /* falllback */
  width: 100%; /* falllback */
  display: flex;
}

.layout > .picture {
  display: table-cell; /* falllback */
  width: 30%; /* falllback */
  display:flex; /* to make FF and IE happy */
  flex: 0 1 30%;
  background: tomato;
}

.layout > .details {
  display: table-cell; /* falllback */
  width: auto; /* falllback */
  display:flex; /* to make FF and IE happy */
  flex: 1 1 auto;
  background: aqua;
}
<div class="layout">
  <div class="picture">
    <img src="...">
  </div>
  <div class="details">username, email, etc.</div>
</div>


不,它似乎工作正常,因为在正常情况下,flex-item和table-cell的工作方式相同,但是如果你进入极端条件(例如小屏幕),flex-items开始与table-cells有所不同。尝试这个演示:http://jsfiddle.net/nothrem/do525ff3/1/并使结果窗口过窄-上部布局(纯flexbox)与底部布局(flexbox内的table-cells)缩小方式不同。 - Radek Pech
您使用的是哪个浏览器 - 对我来说,即使在窄屏幕上,它们看起来都一样。 - Danield
在Chrome中它可以正常工作,但是在FF、IE和Safari中出现了问题。 (在初始评论中更新) - Radek Pech
@RadekPech - 有趣的是,如果在flex项目的display:table-cell规则之后添加display:flex规则,则其他浏览器似乎也可以正常工作。http://cssdeck.com/labs/bctqezgs - Danield
使用flexbox有助于 - 浏览器可能希望flex项既是flex项又是内部flexbox,但这会破坏内部布局,因为表格单元格内的项目本身变成了flex项。您需要将旧表格单元格的内容包装到另一个元素中,以保持其布局不变。虽然不太方便,但仍然是最佳解决方案。最终演示:http://jsfiddle.net/nothrem/do525ff3/4/ - Radek Pech

1
.child {
  flex-shrink: 0;
}

添加flex-shrink属性以防止收缩超过其内容


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接