当被其他伸缩项包围时,在容器中的伸缩项居中



我有一个flex-box(参见下面的示例代码片段)。

我想设置它,以便在所有情况下,<h2>都位于flex-box的中心,其他span将根据其标记围绕它流动。

我基本上是在寻找一个align-self CSS代码,但对于主轴,而不是交叉轴(这可能有助于解释我的问题)。

我也将margin: auto;应用到我的<h2>中,这是我在阅读这篇文章后了解到的(一个很棒的页面,但它仍然让我有以下问题-除非我没有完全理解它)。

这是我得到的代码:

.container {
  align-items: center;
  border: 1px solid red;
  display: flex;
  justify-content: center;
  width: 100%;
}
h2 {
  margin: auto;
]
<div class="container">
  <h2>I'm an h2</h2>
  <span>I'm span 1</span>
  <span>I'm span 2</span>
  <span>I'm span 3</span>
</div>
<div class="container">
  <span>I'm span 1</span>
  <span>I'm span 2</span>
  <span>I'm span 3</span>
  <h2>I'm an h2</h2>
  <span>I'm span 4</span>
  <span>I'm span 5</span>
  <span>I'm span 6</span>
</div>
<div class="container">
  <span>I'm span 1</span>
  <span>I'm span 2</span>
  <h2>I'm an h2</h2>
  <span>I'm span 3</span>
</div>

为了充分重申我的问题:我想知道如何在我的页面上居中<h2>,以便无论其他<span>在哪里,<h2>将始终在中心的弹性盒。

注::我愿意使用JavaScript和jQuery,但我更喜欢用纯CSS的方式来实现这一点。


Michael Benjamin回答后:

他的回答引起了我的思考。虽然我还没有找到这样做的方法,但我相信以下是朝着正确方向迈出的一步:

<div class="container">
  <div>
    <span>I'm span 1</span>
    <span>I'm span 2</span>
    <span>I'm span 3</span>
  </div>
  <h2>I'm an h2</h2>
  <div>
    <span>I'm span 4</span>
    <span>I'm span 5</span>
    <span>I'm span 6</span>
  </div>
</div>
CSS

.container div {
  flex: 1 1 auto;
  text-align: center;
}
h2 {
  flex: 0 0 auto;
  margin: auto;
}

.container {
  align-items: center;
  border: 1px solid red;
  display: flex;
  justify-content: center;
  width: 100%;
}
.container div {
  flex: 1 1 auto;
  text-align: center;
}
h2 {
  flex: 0 0 auto;
  margin: auto;
}
<div class="container">
  <div>
  </div>
  <h2>I'm an h2</h2>
  <div>
    <span>I'm span 1</span>
    <span>I'm span 2</span>
    <span>I'm span 3</span>
  </div>
</div>
<div class="container">
  <div>
    <span>I'm span 1</span>
    <span>I'm span 2</span>
    <span>I'm span 3</span>
  </div>
  <h2>I'm an h2</h2>
  <div>
    <span>I'm span 4</span>
    <span>I'm span 5</span>
    <span>I'm span 6</span>
  </div>
</div>
<div class="container">
  <div>
    <span>I'm span 1</span>
    <span>I'm span 2</span>
  </div>
  <h2>I'm an h2</h2>
  <div>
    <span>I'm span 3</span>
  </div>
</div>

基本上,理论是,虽然总<span>的数量是未知的,但已知总共有三种元素:<div><h2><div>

正如您在上面的代码片段中看到的,我已经尝试(flex: 0 0 autoflex: 1 1 auto等)使其工作,但没有成功。有没有人能给我一些建议,告诉我这是否是朝着正确方向迈出的一步,以及如何将其推向实际的产品?

Flex对齐属性通过分配容器中的空闲空间来工作。

因此,当一个伸缩项与其他项共享空间时,没有单步方法来居中,除非兄弟项的总长度在两边相等。

在第二个示例中,h2两侧的跨度的总长度相等。因此,h2在容器中完全居中。

.container {
    display: flex;
    justify-content: center;
    align-items: center;
    border: 1px solid red;
    margin: 5px;
    padding: 5px;
}
p { text-align: center;}
p > span { background-color: aqua; padding: 5px; }
<div class="container">
  <span>I'm span 1</span>
  <span>I'm span 2</span>
  <span>I'm span 3</span>
  <h2>I'm an h2</h2>
  <span>I'm span 4</span>
  <span>I'm span 5</span>
  <span>I'm span 6</span>
</div>
<p><span>TRUE CENTER</span></p>

请记住,将h2justify-content: center(或space-aroundspace-between)居中,只有在两边有相等的平衡时才有效。两边之间的每一个像素差都将使h2偏离相应的量。

在你的第一个和最后一个例子中,双方明显不平衡。标准对齐属性,如justify-contentmargin将不起作用,因为它们居中于可用空间,而不是总空间

您可以使用visibility: hidden在相反的两侧插入重复的跨度,以达到相同的平衡。但是,这会使你的标记膨胀为语义上毫无价值的元素。

相反,如果你有能力计算每个span的宽度,你可以插入伪元素来达到相等的平衡。

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px solid red;
  margin: 5px;
  padding: 5px;
}
span {
  flex: 0 0 75px;
  border: 1px dashed black;
  box-sizing: border-box;
}
div.container:first-child::before {
  content: "";
  width: 225px;
}
.container:nth-child(2)::after {
 content: "";
  width: 75px;
}
p { text-align: center;}
p > span { background-color: aqua; padding: 5px; border: none; }
<div class="container">
  <h2>I'm an h2</h2>
  <span>I'm span 1</span>
  <span>I'm span 2</span>
  <span>I'm span 3</span>
</div>
<div class="container">
  <span>I'm span 1</span>
  <span>I'm span 2</span>
  <h2>I'm an h2</h2>
  <span>I'm span 3</span>
</div>
<p><span>TRUE CENTER</span></p>

最后,作为使用CSS的最后手段,您可以使用绝对定位将h2居中。这将从文档流中删除元素,但始终保持它在容器中的完美居中。

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px solid red;
  position: relative; /* NEW */
  height: 50px;
}
h2 {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
  margin: 0;
}  
.container:nth-child(1) { justify-content: flex-end; }
.container:nth-child(2) > span:nth-of-type(4) { margin-left: auto; }  
.container:nth-child(3) > span:nth-of-type(2) { margin-right: auto; }
p { text-align: center;}
p > span { background-color: aqua; padding: 5px; }
<div class="container">
  <h2>I'm an h2</h2>
  <span>I'm span 1</span>
  <span>I'm span 2</span>
  <span>I'm span 3</span>
</div>
<div class="container">
  <span>I'm span 1</span>
  <span>I'm span 2</span>
  <span>I'm span 3</span>
  <h2>I'm an h2</h2>
  <span>I'm span 4</span>
  <span>I'm span 5</span>
  <span>I'm span 6</span>
</div>
<div class="container">
  <span>I'm span 1</span>
  <span>I'm span 2</span>
  <h2>I'm an h2</h2>
  <span>I'm span 3</span>
</div>
<p><span>TRUE CENTER</span></p>


UPDATE(基于修改的问题)

基本上,理论是,虽然总<span>的数量是未知的,但已知的是总共有三种元素:<div><h2><div> .

所以,如果我们知道总是有三个元素,那么使用flex属性是一个潜在的解决方案。

.container {
  display: flex;
}
.container > * {
  flex: 1;  /* KEY RULE */
}
h2 { 
  text-align: center;
  margin: 0;
}
.container > div {
  display: flex;
  justify-content: space-around;
}
/* non-essential decorative styles */
.container { background-color: lightgreen; border: 1px solid #ccc; padding: 5px; }
.container > * { border: 1px dashed red; }
p { text-align: center;}
p > span { background-color: aqua; padding: 5px; }
<div class="container">
  <div>
    <span>I'm span 1</span>
    <span>I'm span 2</span>
    <span>I'm span 3</span>
  </div>
  <h2>I'm an h2</h2>
  <div>
    <span>I'm span 4</span>
    <span>I'm span 5</span>
    <span>I'm span 6</span>
  </div>
</div>
<p><span>TRUE CENTER</span></p>

情况如下:

  • 这三个元素都是flex项,因为它们的父元素是一个flex容器
  • 每个物品都有一个flex: 1,这使得它们在自己之间平均分配容器空间。最终的结果是三个相同宽度的项目。
  • 现在,在h2元素中居中h2文本也会在容器中居中。
  • 每个div都可以做成一个嵌套的flex容器,并且span可以与flex属性对齐。

更多信息和解决方案:

  • 居中并右对齐flexbox元素
  • 当侧边物品宽度不同时,保持中间物品居中

一种方法是在两边都添加空span,然后将span和h2设置为特定的伸缩值,如下所示:

.container {
  align-items: center;
  border: 1px solid red;
  display: flex;
  justify-content: center;
  width: 100%;
}
h2 {
  margin: auto;
  text-align: center;
  flex: 3 0;
}
span{
  flex: 1 0;
}
<div class="container">
<span></span>
<span></span>
<span></span>
  <h2>I'm an h2</h2>
  <span>I'm span 1</span>
  <span>I'm span 2</span>
  <span>I'm span 3</span>
</div>
<div class="container">
  <span>I'm span 1</span>
  <span>I'm span 2</span>
  <span>I'm span 3</span>
  <h2>I'm an h2</h2>
  <span>I'm span 4</span>
  <span>I'm span 5</span>
  <span>I'm span 6</span>
</div>
<div class="container">
  <span>I'm span 1</span>
  <span>I'm span 2</span>
  <span></span>
  <h2>I'm an h2</h2>
  <span>I'm span 3</span>
  <span></span>
  <span></span>
</div>

保证两边的空间相等。唯一的问题是,你必须确定你想要多少宽度的h2采取

最新更新