【问题标题】:Does the CSS flexbox module work on direct child elements only?CSS flexbox 模块是否仅适用于直接子元素?
【发布时间】:2013-01-03 22:17:56
【问题描述】:

看看我拥有并运行的网站的这个页面设计:

http://www.jungledragon.com/image/9472/barn_owl_close-up.html

如您所见,这涉及经典的两列布局。事情的顺序很重要。例如,您可以直接在照片旁边看到这所关注的物种。

我现在正在为这个网站编写一个响应式设计,并面临一个挑战。想象一下狭窄的智能手机视口上的那个页面。经典的策略是简单地将右列“堆叠”在左列下方,让用户垂直滚动。然而,就元素的排序而言,这远非理想。 'specie' 块将位于照片下方,用户必须先滚动浏览诸如 cmets 之类的内容,然后才能看到照片和 specie 之间的关系。

我正在尝试解决这个问题,而这篇将 CSS 的 flexbox 解释为可能的解决方案的文章听起来很有希望:

http://www.jordanm.co.uk/post/21863299677/building-with-content-choreography

这里的想法是只使用 CSS,可以改变元素的视觉顺序,这正是我所需要的。不幸的是,从那以后我了解到这篇文章使用了过时的规范,并且几乎没有任何浏览器支持新规范:

http://css-tricks.com/old-flexbox-and-new-flexbox/

这种方式对我来说很糟糕。尽管如此,我仍然想在概念层面提出我的问题:

我见过的所有关于 flexbox 的演示都有这么简单的标记:

<div id="somecontainer">
  <div id="child1"></div>
  <div id="child2"></div>
</div>

接下来,容器被声明为一个弹性盒子,方向垂直。最后,为每个子元素分配一个顺序。例如,这允许使用单个 CSS 语句将 child2 移动到 child1 上方。

现在问题来了。如果实际标记更复杂,因为有额外的层次结构在起作用怎么办?一个例子:

<div id="somecontainer">

  <div id="colmain">

    <div id="content1"></div>
    <div id="content2"></div>
    <div id="content3"></div>

  </div>

  <div id="colside">

    <div id="content4"></div>
    <div id="content5"></div>
    <div id="content6"></div>

  </div>

</div>

如您所见,此标记具有额外的层次结构,要重新排序的实际内容块不是最高级别容器的直接子元素。他们是孩子,但不是直系孩子。

flexbox 和子元素的重新排序可以在这种情况下工作吗?例如,“content5”可以在“content1”和“content2”之间移动吗?

不管浏览器支持如何,我都在尝试从概念上理解是否支持。我问的原因是因为额外的列层次结构在标记中非常常见,如果 flexbox 重新排序仅适用于直接子级,那将完全糟糕。

【问题讨论】:

  • 我认为答案是否定的,但即使它有效,现实世界的浏览器对“新”规范的支持还有一段路要走。在所有性感的新 CSS 布局东西都在起作用的遥远必杀技中,如果你想将元素从嵌套中拉出来,那么使用Grid Layout 可能会更好。
  • @robertc 现在让我们暂时不考虑浏览器支持,我只是好奇如果浏览器支持它是否会/可以/应该工作,这意味着它会按照规范工作?还是重新排序仅适用于直接子代?
  • 就像我说的,我认为不会。

标签: css flexbox


【解决方案1】:

回答你的问题标题:是的,这实际上是规范中的stated quite clearly

伸缩容器的内容由零个或多个伸缩项组成:伸缩容器的每个子项都成为伸缩项

如果规范中的措辞让您感到困惑,那是因为您的措辞有点偏离:

他们是孩子,但不是直接孩子。

child 根据定义是直接的...内部 divs 被称为 descendants,但不是子代,因为它们不直接嵌套在 flex 中容器。

现在,任何带有display: flexdisplay: inline-flex 的东西都被指定为弹性容器。虽然每个 flex 项都参与 flex 容器的格式化上下文,但 flex 项的后代是独立格式化的,并且与 flex 容器无关,就好像容器一开始就没有进行过伸缩一样。

因此,您不能重新排序弹性项目的后代,除非弹性项目本身也成为其后代的弹性容器,但即便如此,您也不能在此内部容器之外和容器的兄弟姐妹周围重新排序它们到外容器。

【讨论】:

    【解决方案2】:

    BoltClockanswer 很棒,但我想补充一点:

    这是弹性容器的(直接)子盒子成为弹性项目。但这些不一定对应于(直接)子元素。

    一些例子:

    • 弹性容器的::before::after 伪元素生成弹性项目。
    • 直接包含在 flex 容器中的每个连续文本运行都包装在一个匿名 flex 项中。
    • 如果 flex 容器的子元素具有 display: contents,则不会呈现,其子元素(flex 容器的孙子元素)将显示为 flex 项。

    然后,如果您在 flex 容器内有一个复杂的结构,并且您希望树的叶子成为外部容器的 flex 项,您可以使用 display: contents 设置所有中间元素的样式。

    但是,请注意 display: contents 是最近添加的,因此尚未得到广泛支持。

    【讨论】:

    • 我发现桌面 Safari 在 flex 容器内运行文本时似乎表现不同。因此,如果您遇到问题,请尝试消除它们。
    【解决方案3】:

    一些潜在的解决方案将是 CSS 网格布局:http://dev.w3.org/csswg/css3-grid-layout/ 但是在撰写本文时只有 IE10 支持它:http://caniuse.com/css-grid

    和模板布局http://www.w3.org/TR/2009/WD-css3-layout-20090402/

    不确定是否正在开发中,或者我们是否会有另一个具有许多相似但不断变化的语法的 flex-box 类型的东西

    【讨论】:

      猜你喜欢
      • 2017-05-05
      • 2018-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-03
      相关资源
      最近更新 更多