16

I want to have a square div inside a flexbox. So I use:

.outer {
  display: flex;
  width: 100%;
  background: blue;
}
.inner {
  width: 50%;
  background: yellow;
  padding-bottom: 50%;
}
<div class="outer">
  <div class="inner">
    <a>hehe</a>
  </div>
</div>

This works fine in Chrome. But in Firefox, the parent squeezes to just one line.

How do I solve this in Firefox? I use version 44.

You can also view the code at https://jsbin.com/lakoxi/edit?html,css

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Yiou
  • 770
  • 1
  • 10
  • 19

2 Answers2

20

2018 Update

The flexbox specification has been updated.

4.2. Flex Item Margins and Paddings

Percentage margins and paddings on flex items, like those on block boxes, are resolved against the inline size of their containing block, e.g. left/right/top/bottom percentages all resolve against their containing block’s width in horizontal writing modes.


Original Answer - applies to FF and Edge versions released before 2018

From the flexbox specification:

Authors should avoid using percentages in paddings or margins on flex items entirely, as they will get different behavior in different browsers.

Here's some more:

4.2. Flex Item Margins and Paddings

Percentage margins and paddings on flex items can be resolved against either:

  • their own axis (left/right percentages resolve against width, top/bottom resolve against height), or,
  • the inline axis (left/right/top/bottom percentages all resolve against width)

A User Agent must choose one of these two behaviors.

Note: This variance sucks, but it accurately captures the current state of the world (no consensus among implementations, and no consensus within the CSSWG). It is the CSSWG’s intention that browsers will converge on one of the behaviors, at which time the spec will be amended.

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 1
    @Lichtbringer, I was able to use `display: block` to get around the issue on one site. See the last bullet point in my answer here: http://stackoverflow.com/a/39310591/3597276 – Michael Benjamin Mar 12 '17 at 17:12
  • Not a real workaround to me, as I "need" to use flexbox. –  Mar 13 '17 at 10:57
  • @Lichtbringer There is a workaround, check my answer – Asons May 16 '17 at 09:38
  • 2
    The spec has now been amended: UAs must resolve percentage padding/margin against the inline size: https://drafts.csswg.org/css-flexbox/#item-margins – preaction May 06 '18 at 20:06
4

In addition to Michael_B's answer, here is a possible workaround.

When using percent we often relate that to the viewport width, so with that in mind, viewport units vw/vh can be an option, since it works similar (responsive).

Stack snippet

.outer {
  display: flex;
  width: 100%;
  background: blue;
}
.inner {
  width: 50%;
  background: yellow;
  padding-bottom: 50vw;
}
<div class="outer">
  <div class="inner">
    <a>hehe</a>
  </div>
</div>

Updated based on a comment

If a square is a must, and viewport units or script can't be used, here is another trick using a dummy image.

Note, as image also a SVG or a Base64 could be used as a datauri to save an extra round trip to the server

.outer {
  display: flex;
  width: 100%;
  background: blue;
}
.inner {
  width: 50%;
  background: yellow;
}
.inner img {
  display: block;
  width: 100%;
  visibility: hidden;
}
<div class="outer">
  <div class="inner">
    <img src="http://placehold.it/10" alt="">
  </div>
</div>
Asons
  • 84,923
  • 12
  • 110
  • 165
  • I wouldn't consider this a real workaround. I mean yes, in certain constellations it may be what you're after, but if you want the dimensions be reliant on the parent node then working with viewport units is tedious, because you (probably) need to change other nodes as well then. –  Sep 10 '17 at 21:29
  • 1
    @Lichtbringer Thats why I wrote _"...we often relate that to the viewport width, so with that in mind..."_ and since there is no other way to get a _percentage based_ value, it is the only CSS workaround – Asons Sep 10 '17 at 22:27
  • @Lichtbringer I also added a 2nd sample to my answer – Asons Sep 10 '17 at 22:39