【问题标题】:How to reset 'display' property for flex-item如何重置弹性项目的“显示”属性
【发布时间】:2015-01-24 12:26:28
【问题描述】:

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

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

我尝试了各种定义,例如display:inheritdisplay:initial,但没有一个能够将显示定义重置为作为弹性项目正常工作。

<!-- 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 在显示中设置什么,它都不能作为弹性项目工作,也不会增长以填充剩余空间。

知道如何在不使用 JS 检测浏览器版本和切换样式的情况下覆盖它吗?

我已经尝试在谷歌上搜索解决方案,但大多数结果只是关于 Flexbox 的一般文章;唯一类似的是this test,它根本没有解决向后兼容性问题。

更新 1: 这是一个JSFiddle demo 的纯 Flexbox 和 Flexbox 结合表格布局。如果调整结果窗口的大小,纯布局的缩小方式与底部结合表格和 Flexbox 的布局不同。 注意:在 Chrome 中可以正常工作,在 Firefox、IE、Safari 等中尝试。

更新 2: Safari 使用前缀定义正常工作...updated JSFiddle demo

【问题讨论】:

    标签: css tablelayout flexbox


    【解决方案1】:

    正如 Danield 所提到的,flex 容器的所有子项(由 display: flexdisplay: inline-flex 指定)都会自动成为 flex 项。弹性项目没有display 属性;相反,您可以将其设置为其他值,具体取决于您希望 flex 项目的子 的布局方式。如果浏览器正在识别display: flex-item,那么它们可能对“flexbox”有一些奇怪的非标准实现,因为该值从未存在于 Flexbox 规范的任何化身中(而且我不知道它到底对应于什么确实)。

    display的初始值为inline,所以display: initial等价于display: inline。见this answer。您要做的是将元素重置为浏览器给出的默认display。您需要提前知道这个值;对于div 元素,它是display: block

    不幸的是,这将覆盖所有浏览器中现有的table-cell 声明,原因很明显。在这种情况下,如果您需要支持不支持 flexbox 的浏览器,那么您最好还是坚持使用表格布局。

    【讨论】:

    • 您的权利,在正常页面上将弹性项目设置为阻止或内联可以正常工作。不幸的是,我的页面布局似乎很混乱,以至于浏览器很困惑,它无法正确布局它。我将不得不重新设计整个页面以仅使用 flexbox :( .
    【解决方案2】:

    没有display:flex-item,因为一旦在容器元素上设置display:flex,子元素就会自动成为弹性项目。

    这里是 a demo 表明子级上的 display:table-cell 不会影响子级上 flex 属性的功能

    编辑: 对于 Firefox 和 IE,如果您在 display:table-cell 规则之后添加规则 display:flex,则子代上的 display:table-cell 不会影响子代上 flex 属性的功能

    /* 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-item 的工作方式与表格单元格。试试这个演示:jsfiddle.net/nothrem/do525ff3/1 并让结果窗口太窄 - 上部布局(纯 flexbox)与底部布局(flexbox 内的表格单元格)的收缩方式不同。
    • 您使用的是哪个浏览器 - 在我看来,即使在窄屏幕上它们看起来也一样
    • 在 Chrome 中它可以正常工作,但是 FF、IE 和 Safari 坏了。 (在初始评论中更新)
    • @RadekPech - 有趣的是,如果您在弹性项目的display:table-cell 规则之后添加规则display:flex,它似乎也适用于其他浏览器。 cssdeck.com/labs/bctqezgs
    • 使用 flexbox 有帮助 - 浏览器可能期望 flex-item 既是 flex-item 又是内部 flexbox,但它破坏了内部布局,因为 table-cell 内的项目本身变成了 flex-item。您需要将旧表格单元格的内容包装到另一个元素中,以保持其布局不变。不方便,但仍然是最好的解决方案。最终演示:jsfiddle.net/nothrem/do525ff3/4
    【解决方案3】:
    .child {
      flex-shrink: 0;
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-24
      • 2018-05-30
      • 2014-08-09
      • 1970-01-01
      • 1970-01-01
      • 2017-12-22
      • 1970-01-01
      • 2017-10-10
      相关资源
      最近更新 更多