为什么不能正确地使用 align-items=center 居中图像来弯曲方向列

Why doesn't flex direction column with align-items=center center image properly

我偶然发现了 direction:column 的 flexbox 中图像居中的问题。

假设您在 flexbox 中有两个元素,其中第一个包含图像:

<div class="container">
    <div class="image-container">
        <img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg">
    </div>
    <div class="another-flex-child">
        Random content here
    </div>
</div>


.container {
  height: 300px;
  background-color: green;
  display: flex;
  flex-direction: column;

  .image-container {
    flex: 1;
    align-self: center;

    .img {
      height: 100%;
    }
  }

  .another-flex-child {
    flex: none;
    background-color: red;
  }
}

我希望图像在 div 内水平居中,但图像的左边框似乎恰好位于 div 的中心。

当我用包含一些文本的另一个 div 替换图像时,它按预期放置。

有人可以向我解释一下那里发生了什么吗?

Checkout this fiddle

因为包含图像(并且上面有 align-self: center)的 <div> 默认是块级元素,并且 width100%默认。因此,它相对于 parent.

受到限制

为了让您的图片正确居中,您需要添加 display: contents

container .image-container {
  display: inline;
}

这可以在下面看到:

.container {
  height: 300px;
  background-color: green;
  display: flex;
  flex-direction: column;
}

.container .image-container {
  flex: 1;
  align-self: center;
  display: contents;
}

.container .image-container .img {
  height: 100%;
}

.another-flex-child {
  flex: none;
  background-color: red;
}

.spacer {
  height: 20px;
}
<div class="container">
  <div class="image-container">
    <img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg">
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>

<div class="spacer"></div>

<div class="container">
  <div class="image-container">
    <div>Properly centered content</div>
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>

问题是您使用的 SVG 没有固有尺寸,只有固有比例,因此您的图像的宽度等于 0,这使得它的居中容器的宽度也等于 0。

这里是使用前height:100%

.container {
  height: 300px;
  background-color: green;
  display: flex;
  flex-direction: column;
}

.image-container {
  flex: 1;
  align-self: center;
  border:2px solid blue;
}

.img {
  /*height: 100%;*/
}

.another-flex-child {
  flex: none;
  background-color: red;
}

.spacer {
  height: 20px;
}
<div class="container">
  <div class="image-container">
    <img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg">
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>

<div class="spacer"></div>

<div class="container">
  <div class="image-container">
    <div>Properly centered content</div>
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>

设置 height:100% 后,图像将填满所有 space 并保持其比例,但您会出现溢出,因为浏览器不会返回再次计算容器的宽度:

.container {
  height: 300px;
  background-color: green;
  display: flex;
  flex-direction: column;
}

.image-container {
  flex: 1;
  align-self: center;
  border:2px solid blue;
}

.img {
  height: 100%;
}

.another-flex-child {
  flex: none;
  background-color: red;
}

.spacer {
  height: 20px;
}
<div class="container">
  <div class="image-container">
    <img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg" >
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>

<div class="spacer"></div>

<div class="container">
  <div class="image-container">
    <div>Properly centered content</div>
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>

为避免这种情况,给图像一个宽度并确保添加

.container {
  height: 300px;
  background-color: green;
  display: flex;
  flex-direction: column;
}

.image-container {
  flex: 1;
  align-self: center;
  border:2px solid blue;
  min-height:0;
}

.img {
  height: 100%;
}

.another-flex-child {
  flex: none;
  background-color: red;
}

.spacer {
  height: 20px;
}
<div class="container">
  <div class="image-container">
    <img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg" width="250">
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>

<div class="spacer"></div>

<div class="container">
  <div class="image-container">
    <div>Properly centered content</div>
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>


如果您最初使用的是具有固有尺寸的图像,则不会遇到此问题,也不需要定义宽度。您只需添加 min-height:0 即可避免溢出:

.container {
  height: 300px;
  background-color: green;
  display: flex;
  flex-direction: column;
}

.image-container {
  flex: 1;
  align-self: center;
  border:2px solid blue;
  min-height:0;
}

.img {
  height: 100%;
}

.another-flex-child {
  flex: none;
  background-color: red;
}

.spacer {
  height: 20px;
}
<div class="container">
  <div class="image-container">
    <img class="img" src="https://picsum.photos/id/1/400/400">
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>

<div class="spacer"></div>

<div class="container">
  <div class="image-container">
    <div>Properly centered content</div>
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>

请注意,以上内容在 Firefox 中的工作方式不同,您需要添加 text-aling:center 以确保它在任何地方都工作相同:

.container {
  height: 300px;
  background-color: green;
  display: flex;
  flex-direction: column;
}

.image-container {
  flex: 1;
  align-self: center;
  border:2px solid blue;
  text-align:center;
  min-height:0;
}

.img {
  height: 100%;
}

.another-flex-child {
  flex: none;
  background-color: red;
}

.spacer {
  height: 20px;
}
<div class="container">
  <div class="image-container">
    <img class="img" src="https://picsum.photos/id/1/400/400">
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>

<div class="spacer"></div>

<div class="container">
  <div class="image-container">
    <div>Properly centered content</div>
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>

您会注意到差异与容器的宽度计算有关,由于使用 height:100%

,容器的宽度计算有点复杂

如果图像的尺寸非常小,情况可能会变得更糟:

.container {
  height: 300px;
  background-color: green;
  display: flex;
  flex-direction: column;
}

.image-container {
  flex: 1;
  align-self: center;
  border:2px solid blue;
  text-align:center;
  min-height:0;
}

.img {
  height: 100%;
}

.another-flex-child {
  flex: none;
  background-color: red;
}

.spacer {
  height: 20px;
}
<div class="container">
  <div class="image-container">
    <img class="img" src="https://picsum.photos/id/1/50/50">
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>

<div class="spacer"></div>

<div class="container">
  <div class="image-container">
    <div>Properly centered content</div>
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>

在 Firefox 中 text-align:center 什么都不做,您可能需要一个嵌套的 flexbox 容器

.container {
  height: 300px;
  background-color: green;
  display: flex;
  flex-direction: column;
}

.image-container {
  flex: 1;
  align-self: center;
  justify-content:center;
  border:2px solid blue;
  display:flex;
  min-height:0;
}

.img {
  height: 100%;
}

.another-flex-child {
  flex: none;
  background-color: red;
}

.spacer {
  height: 20px;
}
<div class="container">
  <div class="image-container">
    <img class="img" src="https://picsum.photos/id/1/50/50">
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>

<div class="spacer"></div>

<div class="container">
  <div class="image-container">
    <div>Properly centered content</div>
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>

以下几乎与您在使用初始 SVG 时遇到的问题相同,可以使用相同的代码修复,但不会消除溢出:

.container {
  height: 300px;
  background-color: green;
  display: flex;
  flex-direction: column;
}

.image-container {
  flex: 1;
  align-self: center;
  display:flex;
  justify-content:center;
  border:2px solid blue;
}

.img {
  height: 100%;
}

.another-flex-child {
  flex: none;
  background-color: red;
}

.spacer {
  height: 20px;
}
<div class="container">
  <div class="image-container">
    <img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg" >
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>

<div class="spacer"></div>

<div class="container">
  <div class="image-container">
    <div>Properly centered content</div>
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>


另一个需要注意的有趣的事情是,如果您将 height:100% 添加到容器中,使嵌套高度的计算更容易,您的初始代码可能会正常工作:

.container {
  height: 300px;
  background-color: green;
  display: flex;
  flex-direction: column;
}

.image-container {
  flex: 1;
  align-self: center;
  border:2px solid blue;
  box-sizing:border-box;
  height:100%;
}

.img {
  height: 100%;
  display:block;
}

.another-flex-child {
  flex: none;
  background-color: red;
}

.spacer {
  height: 20px;
}
<div class="container">
  <div class="image-container">
    <img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg" >
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>

<div class="spacer"></div>

<div class="container">
  <div class="image-container">
    <div>Properly centered content</div>
  </div>
  <div class="another-flex-child">
    Random content here
  </div>
</div>

添加如下对齐内容:

.image-container {
    flex: 1;
    align-self: center;
    justify-content:center;
}

它应该有效