【问题标题】:Exclude element with fixed positioning from justify-content in flex layout [duplicate]从flex布局中的justify-content中排除具有固定定位的元素[重复]
【发布时间】:2016-06-30 14:11:30
【问题描述】:

我目前正在尝试使用 flexbox 构建响应式网站布局。

根据屏幕大小,我希望元素具有position: fixed; 这本身就可以工作。但是当我在包含一个元素的列上使用justify-content: space-between; 时,该列本身使用position: fixed; 移出,空间分布将此元素用作0 高度元素。

为了演示,我设置了两个示例。两者都不使用媒体查询,因为它们不是问题。

在第一个示例中,我创建了我想要的最终结果。我不得不将#fixed 移到.column 之外,以便空间分配正常工作。

在第二个示例中,我创建了所需的 HTML 标记。当您并排比较两个示例时,您会注意到第二个示例的间距看起来很奇怪。浏览器在这里没有出错,因为在分配空间时它必须尊重一个元素。我(简而言之)希望浏览器假装#fixed 不在容器内,因此在分配空间时不考虑它。

结果应该是这样的:https://jsfiddle.net/5nu9nsyL/3/

这就是 html 的外观:https://jsfiddle.net/5nu9nsyL/4/
(只有 Chrome 和 Safari 才能正确呈现它。因此,如果两者看起来相同,请使用 Firefox 或 IE 等不同的浏览器查看)

我希望我说清楚了我想要什么。

(注意我必须在容器.column上使用display: flex

(我还需要一个免费的、仅 CSS 的解决方案)

【问题讨论】:

  • 如果我理解正确,您希望第二列中项目之间的间距与第一列中项目之间的间距相同吗?
  • 没错!这就是我想要的。 (第二个元素必须仍然留在标记中)
  • 我明白你在说什么。要考虑的一个问题是浏览器。在 Chrome 47 和 48 中,您发布的两个示例都呈现相同的效果。您提到的差异存在于 Firefox 和 IE11 中,但不存在于 Chrome 中。
  • 我提供了一个类似问题的答案:stackoverflow.com/q/32991051/3597276
  • 可能值得注意的是,容器在 FF/IE11 中使用 display: nonespace-between 计算中删除了一个弹性项目。

标签: html css flexbox


【解决方案1】:

这是 Firefox bug 874718spec

justify-content 属性与 flex items 沿 main axis flex 容器的当前行。

由于一个绝对(包括固定)定位的元素是外流的,它不是flex item(这在Absolutely-Positioned Flex Children 中有完整的定义)。所以justify-content 应该忽略它。

但根据old spec 的说法,Firefox 将其包装在一个匿名的弹性项目中:

flex 容器的绝对定位子元素不是它们自己 弹性项目,但它们在正常情况下留下“占位符” 在箱形树中的位置。这些占位符是匿名内联的 宽度、高度和行高为“0”的框,它们交互 通常使用 flexbox 布局算法。特别是,他们将 触发匿名弹性项目的创建,或加入相邻 匿名弹性项目中的内联元素。

为了解决这个问题,我推荐aligning with auto margins,而不是使用justify-content

.column > div:not(:first-child) {
  margin-top: auto;
}

这将在 flex 容器的孩子之前平均分配可用空间,除了第一个。效果应该类似于justify-content: space-between

在固定元素的情况下,auto 边距将仅计算为 0

.column {
  display: flex;
  flex-flow: column nowrap;
  height: 300px;
  float: left;
  margin: 10px;
  border: 3px solid black;
}
.column > div:not(:first-child) {
  margin-top: auto;
}
.column > div,
#fixed {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 200px;
  height: 50px;
  background-color: red;
}
#fixed {
  position: fixed;
  top: 0;
  right: 0;
}
<div class="column">
  <div>Element 1</div>
  <div id="fixed">Element 2</div>
  <div>Element 3</div>
  <div>Element 4</div>
  <div>Element 5</div>
</div>

【讨论】:

  • 非常感谢。我从来不知道margin: auto 也适用于垂直间距。 firefox bugtracker 中是否存在错误?如果不是,我会建议报告它(如果我知道如何查找或报告,我会自己做。但我不知道如何做这两件事)
  • @BrainStone margin: auto 在 flexbox 中垂直工作,但在块布局中不行。该问题已在bug 874718 中报告。
  • 好吧,我对 flexbox 还很陌生,这对我来说也是新的。看来这个错误不会很快得到修复,所以我想我将不得不使用你的解决方案(一旦我确认它在实际站点上有效,我就会接受它。我会在星期一或星期二检查它)
【解决方案2】:

更新

再次查看 OP 后,目标如下:

当屏幕宽度在一定尺寸(我确定为720px+)时,#fixed(col2 ele2) 为position: fixed,如果屏幕宽度较小,则为position: static。当#fixed 被“固定”时,它不再在 col2 中,因此 col2 的子节点之间的间距会增加。需要的是所有 div 之间的间距一致(即 col2 间距必须与 col1 间距一致)。

OP 没有提供显示两种状态的方法:固定和静态;其中静态需要建立。我添加了两个媒体查询,以确保#fixed 的静态和固定状态都将在 720 像素处触发。

@media screen and (min-width: 721px) {
  .spacer {
    display: none;
  }
  #fixed {
    position: fixed;
  }
  .column.column {
    justify-content: space-between !important;
  }
}

@media screen and (max-width: 720px) {
  .spacer.spacer {
    display: none !important;
  }
  #fixed {
    position: static;
  }
  .column.column {
    justify-content: space-between !important;
  }
}

由于某种原因,当仅应用属性 displayposition 时,justify-content: space-between 会中断。所以我在两个媒体查询中都包含了justify-content: space-between,不幸的是这也不起作用。于是我加了!important,还是失败了。于是我使用了我的忍者秘技,将班级选择器.column.column翻了一番,我就赢了!在选择器上加倍会增加它胜过任何东西的特异性。

Plunker in Full Screen Mode 调整浏览器大小来看看魔法。

Plunker in Preview Mode


我不明白你想用#fixed 做什么。但我确实理解演示中描述的问题:

第二列元素 1 和元素 3 之间的空间应与其他空间的高度相同。

由于justify-content: space-between 的性质,由于第二列不能将其内容任意间隔预定长度,因此您需要与第一列一样多的 div 以获得与第一列相同的间距。据我了解,您不能对布局(HTML)进行硬编码,因此我编写了一个小 JS 来创建一个不可见的 div 并将其附加到第二列,从而使元素 1 和 3 之间的空间与子元素之间的空间相同第一列。

Fiddle

【讨论】:

  • 请不要使用 Javascript。你的例子也不起作用(对我来说)另见更新的问题。我提供了更好的例子
猜你喜欢
  • 1970-01-01
  • 2015-07-28
  • 1970-01-01
  • 2017-04-02
  • 1970-01-01
  • 2021-08-16
  • 2015-10-21
  • 2021-11-12
  • 2018-05-03
相关资源
最近更新 更多