1

I've written this simple code for centering my inner div:

<div style="display: flex;align-items: center;width: 100%;height: 600px;background-color: gray;">
  <div style="background-color: white;width: 100px;height: 300px;position: absolute;"></div>
</div>

And it works fine in Chromium. but not in Firefox.

In Firefox the inner div is not centered.

Firefox:

enter image description here

Chromium:

enter image description here

I need the inner div to remain absolutely positioned.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
mlibre
  • 2,460
  • 3
  • 23
  • 32

2 Answers2

3

It's important to note that absolutely positioned flex items do not participate in flex layout.

From the spec:

4.1. Absolutely-Positioned Flex Children

As it is out-of-flow, an absolutely-positioned child of a flex container does not participate in flex layout.

In other words, flex properties, such as align-items: center on the flex container (like in your code) are not respected by out-of-flow flex items.

Your item appears centered in Chrome simply because that's where Chrome positions an absolutely positioned element with default offset values (i.e., top, bottom, left and right are all set to auto.) Firefox positions it somewhere else.

To vertically center your item in all browsers use the offset properties:

flex-container {
  display: flex;
  /* align-items: center; */
  width: 100%;
  height: 600px;
  background-color: gray;
  position: relative;
}

flex-item {
  background-color: white;
  width: 100px;
  height: 100px;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}
<flex-container>
  <flex-item></flex-item>
</flex-container>

jsFiddle

For more details about centering with CSS positioning properties see this post:

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
1

For your given HTML and CSS, with the inner <div> element set to position: absolute, you are trying to vertically center a div that is taken out of the document flow.

You have a couple options for a solution.

Option 1.

You can set the inner <div> to be position: relative and that will allow it's parent <div> to properly apply the behavior of align-items: center to the inner <div> (because the default flex-direction is row). Then you can absolutely position content within the inner div if needed. codepen.io flex example

CSS

.container {
  align-items: center;
  background-color: #888;
  display: flex;
  height: 100vh;
  width: 100%;
}

.inner {
  background-color: #fff;
  height: 100px;
  position: relative;
  width: 100px;
}

HTML

<div class="container">
  <div class="inner"></div>
</div>

Option 2.

If you truly need the inner <div> to be position: absolute, then you can set position: relative on the parent <div> element, then set a top and transform: translateY() on the inner <div>. codepen.io position:absolute example

CSS

// display: flex and align-items: center
// are not needed to vertically align
// an element that is absolutely 
// positioned

.container {
  // align-items: center;
  background-color: #888;
  // display: flex;
  height: 100vh;
  position: relative;
  width: 100%;
}

.inner {
  background-color: #fff;
  left: 0;
  height: 100px;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 100px;
}

HTML

<div class="container">
  <div class="inner"></div>
</div>
CSSDevMonkey
  • 118
  • 1
  • 9