Flexbox布局中的填充底部/顶部


75

我有一个Flexbox布局,其中包含两个项目。其中之一使用padding-bottom

调整页面大小时,蓝色元素会根据其宽度保持其宽高比这适用于Chrome和IE,如下所示:

chrome和IE在flexbox布局上的padding-bottom

但是,在FirefoxEdge中,我得到以下信息(它忽略了保持长宽比的蓝色框上的填充):

Firefox在flexbox布局上的padding-bottom

我对于Flexbox来说还太陌生,以至于无法真正了解它是否应该工作。flexbox的全部目的是调整大小,但是我不确定为什么它会忽略固​​有的填充,而将绝对大小放在蓝色元素上。

我想最终我甚至不确定Firefox或Chrome是否在做正确的事情!任何Firefox flexbox专家都可以提供帮助吗?


上面的解释非常有帮助。有关进一步的上下文和解释,我建议Smashing Magazine的“在响应的iFrame中使嵌入式内容工作”(smashingmagazine.com/2014/02/…)。本文给出了为何该填充和div包装器解决方案有效的清晰简洁的上下文。
Jess

Answers:


104

2020年9月更新

FireFox和edge已从规格中实现了行为,并且flex元素的margin + padding均根据包含块的宽度进行计算。
就像块元素一样。

2018年2月更新

Firefox和edge同意更改其在flex(和网格)项目的顶部,底部页边距和填充的行为:

例如,在水平书写模式下,左/右/上/下百分比全都根据其包含块的宽度来解析。[来源]

尚未实现(已在FF 58.0.2上测试)。

2016年4月更新

于2017年5月仍然有效

规格已更新为:

可以根据以下任一条件解决弹性项目上的边距和填充百分比:

  • 自己的轴(左/右百分比针对宽度,顶部/底部百分比针对高度),或者,
  • 内联轴(左/右/上/下百分比均针对宽度进行解析)

来源:CSS Flexible Box Layout Module Level 1

这意味着chrome IE FF和Edge(即使它们没有相同的行为)也遵循规范推荐。

规格还说:

作者应避免在弹性项目的填充或边距中完全使用百分比,因为它们在不同的浏览器中会出现不同的行为。[来源]


解决:

您可以将flex容器的第一个子元素包装在另一个元素中,然后将其padding-bottom 放在第二个子元素上:

我在现代浏览器(IE,chrome,FF和Edge)中对此进行了测试,它们都具有相同的行为。由于第二个子级的配置是“与往常相同”,因此我认为较旧的浏览器(该支持aslo支持flexbox布局模块)将呈现相同的布局。


先前的答案:

根据规范,Firefox具有正确的行为

说明:

与根据容器宽度计算其百分比边距/填充的块项目不同,在弹性项目上:

弹性项目的边距和填充百分比始终根据其各自的尺寸进行解析;与块不同,它们并不总是针对其包含块的内联维进行解析。

来源dev.w3.org

这意味着padding-bottom / top / top和margin-bottom-bottom / top是根据容器的高度计算的,而不是根据非flexbox布局中的宽度计算的。

由于您尚未在父级伸缩项上指定任何高度,因此该子级的底部填充应为0px。
这是在父级上固定高度的小提琴,它表示填充底部是根据display:flex;容器的高度计算的。



@ web-tiki嗨,我也是flex的新手,只是注意到了这一点。只是为了澄清一下,Chrome / IE的行为是否不正确?如果是这种情况,则将百分比与Padding和Margin一起使用对Flex完全无效!
周星驰

1
有关此Firefox错误的更多信息,请在此处进行处理,显然将其归类为INVALID,但是似乎CSS规范已更新,可以允许我们许多人寻找这种行为。我们只需要确保立即提出问题即可;)
zanona 2016年

1
当前的CSSWG草案规定“左/右/上/下百分比均根据其包含块的宽度进行解析”
Qtax,

1
本期中, Edge&FF同意(大约在2018年1月发布)采用width / Blink行为,并将予以实现。+1
Qtax

1
@AleksandrH我已为答案添加了更新。由于FF和Edge都实现了相同的行为。我将在此保留此答案以供参考。
web-tiki

35

可接受的答案是正确的,但我通过使用伪元素而不是在HTML中添加新元素来改进了解决方案。

示例:http//jsfiddle.net/4q5c4ept/

HTML:

<div id='mainFlexbox'>
  <div id='videoPlaceholder'>
    <iframe id='catsVideo' src="//www.youtube.com/embed/tntOCGkgt98?showinfo=0" frameborder="0" allowfullscreen></iframe>
  </div>
  <div id='pnlText'>That's cool! This text is underneath the video in the HTML but above the video because of 'column-reverse' flex-direction.    </div>
</div>

CSS:

#mainFlexbox {
  border: 1px solid red;
  width: 50%;
  margin: 0 auto;
  padding: 1em;
  display: flex;
  flex-direction: column-reverse;
}
#pnlText {
  border: 1px solid green;
  padding: .5em;
}
#videoPlaceholder {
  position: relative;
  margin: 1em 0;
  border: 1px solid blue;
}
#videoPlaceholder::after {
  content: '';
  display: block;
  /* intrinsic aspect ratio */
  padding-bottom: 56.25%;
  height: 0;
}
#catsVideo {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

2
这是一个非常聪明且无损的解决方法。在我看来,它比先前的建议更具优势。
zanona '16

完美的解决方案!救生员。
nsilva '17

-3

我用vh代替%在Safari,Firefox和Edge中完美运行


1
vh是一个视口单位,而不是相对于元素或其父元素。在您的元素应相对于视口调整大小(而不是一般而言)(并且不考虑此问题)的情况下,它将起作用。
alpipego,2016年

-3
    <div class="flex-parent">
      <div class="flexchild">
        <div class="pad"></div>
      </div>
    </div>  

.flex-child{
   height:100%;
}
.padd{
   padding-top:100% /* write 100%, or instead your value*/;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.