Vertically centering a flex item works in Chrome but not Firefox

拜拜、爱过 提交于 2019-12-24 06:36:16

问题


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:

Chromium:

I need the inner div to remain absolutely positioned.


回答1:


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:

  • Element will not stay centered, especially when re-sizing screen



回答2:


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>


来源:https://stackoverflow.com/questions/41007243/vertically-centering-a-flex-item-works-in-chrome-but-not-firefox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!