将flex项放在容器中,当被其他flex项包围时 [英] Center flex item in container, when surrounded by other flex items

查看:131
本文介绍了将flex项放在容器中,当被其他flex项包围时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个弹出框(见下面的代码片段的例子)。



我想设置它,所以在所有情况下, < h2> 位于弹性框的中心,其他跨度将根据它们的标记流动。



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



我也将 margin:auto; 应用于我的< h2> 我在阅读这篇文章后了解到



这里是我得到的代码:



  .container {align-items:center; border:1px solid red;显示:flex; justify-content:center; width:100%;} h2 {margin:auto;]  

 < div class =container> < h2> I是h2< / h2> < span>我在span 1< / span> < span>我在span 2< / span> < span>我在span 3< / span>< / div>< div class =container> < span>我在span 1< / span> < span>我在span 2< / span> < span>我在span 3< / span> < h2> I是h2< / h2> < span>我在span 4< / span> < span>我在span 5< / span> < span>我是span 6< / span>< / div>< div class =container> < span>我在span 1< / span> < span>我在span 2< / span> < h2> I是h2< / h2> < span>我在span 3< / span>< / div>  


要完全重申我的问题:我想知道如何将< h2> 另一个< span> 是,< h2> / strong>弹性框中心。


谢谢。



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



UPDATE

/ p>

这是通过@ Michael_B 回答后更新的



他的回答让我想起了。虽然我没有找到办法做到这一点,我相信以下是朝正确的方向迈出的一步:



HTML

 < div class =container> 
< div>
< span>我在span 1< / span>
< span>我在span 2< / span>
< span>我在span 3< / span>
< / div>
< h2>我是h2< / h2>
< div>
< span>我在span 4< / span>
< span>我在span 5< / span>
< span>我在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;显示:flex; justify-content:center; width:100%;}。container div {flex:1 1 auto; text-align:center;} h2 {flex:0 0 auto; margin:auto;}  

 < div class = > < div> < / div> < h2> I是h2< / h2> < div> < span>我在span 1< / span> < span>我在span 2< / span> < span>我在span 3< / span> < / div>< / div>< div class =container> < div> < span>我在span 1< / span> < span>我在span 2< / span> < span>我在span 3< / span> < / div> < h2> I是h2< / h2> < div> < span>我在span 4< / span> < span>我在span 5< / span> < span>我是span 6< / span> < / div>< / div>< div class =container> < div> < span>我在span 1< / span> < span>我在span 2< / span> < / div> < h2> I是h2< / h2> < div> < span>我在span 3< / span>基本上,< / div>< / div>  



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


正如你在上面的代码片段中看到的,已尝试( flex:0 0 auto flex:1 1 auto 等)没有成功。任何人都可以给我一些洞察,如果这是一个正确的方向一步,也许如何推到一个实际的产品?



解决方案

Flex对齐属性通过在容器中分配可用空间来工作。



因此,当一个flex项目与其他项目共享空间时,没有单步方法来定中一个flex项目,除非两个兄弟节点的总长度相等。 / p>

在第二个示例中,跨度的总长度在 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>我在span 1< / span> < span>我在span 2< / span> < span>我在span 3< / span> < h2> I是h2< / h2> < span>我在span 4< / span> < span>我在span 5< / span> < span>我在span 6< / span>< / div>< p>< span> TRUE CENTER< / span>< / p>   



请记住,将 h2 justify-content:center (或空格空格 - ) ,只有工作,因为两边是平衡的。每个侧面之间的差异的像素将抛弃 h2 一个相应的金额。



在你的第一个和最后一个例子双方之间存在明显的不平衡。标准对齐属性(例如 justify-content margin )无效,因为它们位于可用空间<



您可以在对面插入重复的跨度 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 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是h2< / h2> < span>我在span 1< / span> < span>我在span 2< / span> < span>我在span 3< / span>< / div>< div class =container> < span>我在span 1< / span> < span>我在span 2< / span> < h2> I是h2< / h2> < span>我在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;位置:相对; / * NEW * / height:50px;} h2 {position:absolute; top:50%;左: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是h2< / h2> < span>我在span 1< / span> < span>我在span 2< / span> < span>我在span 3< / span>< / div>< div class =container> < span>我在span 1< / span> < span>我在span 2< / span> < span>我在span 3< / span> < h2> I是h2< / h2> < span>我在span 4< / span> < span>我在span 5< / span> < span>我是span 6< / span>< / div>< div class =container> < span>我在span 1< / span> < span>我在span 2< / span> < h2> I是h2< / h2> < span>我在span 3< / span>< / div>< p>< span> TRUE CENTER< / span>< / p>   






UPDATE / p>


基本上,理论是当< span> 是未知的,已知的是将有总共三个元素:< div>< h2>< div>


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



  .container {display:flex;}。 * {flex:1; / * KEY RULE * /} h2 {text-align:center; margin:0;}。container> div {display:flex; justify-content:space-around;} / *非必要的装饰风格* /。container {background-color:lightgreen; border:1px solid #ccc; padding:5px; } .container> * {border:1px broken red; } p {text-align:center;} p> span {background-color:aqua; padding:5px; }  

 < div class =container < div> < span>我在span 1< / span> < span>我在span 2< / span> < span>我在span 3< / span> < / div> < h2> I是h2< / h2> < div> < span>我在span 4< / span> < span>我在span 5< / span> < span>我是span 6< / span> < / div>< / div>< p>< span> TRUE CENTER< / span>< / p>   



这是发生了什么:




  • 它们的父级是一个flex容器

  • 每个项目都有一个 flex:1 c> h2 c> c> / code>元素也将使容器中的文本居中。

  • 每个div都可以作为嵌套的flex容器,并且跨度可以与flex属性对齐。


I have a flex-box (see below snippet for examples).

I want to set it so that in all cases, the <h2> is in the center of the flex-box and the other spans will flow around that, based on their markup.

I am basically looking for an align-self CSS code but for the main axis, not the cross axis (this might help explain what I am asking).

I am also applying margin: auto; to my <h2>, which I learned about after reading this (fantastic page but, still leaves me with my following question - unless I didn't fully understand all of it).

Here's the code I got:

.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>

To fully reiterate my question: I want to know how to center the <h2> on my page so that where ever the other <span>s are, the <h2> will always be in the dead center of the flex-box.

Thank you.

P.S. I am willing to use JS and jQuery but would prefer a pure CSS way of achieving this.

UPDATE

This is and update after an answer by @Michael_B

His answer got me thinking. While I have not found a way to do this, I believe the following is a step in the right direction:

HTML

<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>

basically, the theory is that while the amount of total <span>s are unknown, what is known is that there will be a total of three elements: <div><h2><div>

As you can see in my above snippet, I have tried (flex: 0 0 autoand flex: 1 1 auto, etc.) to get it to work but have not been successful. Can anyone give me some insight as to if this is a step in the right direction and maybe how to push it through to an actual product?

Thank you again.

解决方案

Flex alignment properties work by distributing free space in the container.

Hence, there's no single-step method to center one flex item when it shares space with other items, unless the total length of the siblings is equal on both sides.

In your second example, the total length of the spans is equal on either side of the h2. As a result, the h2 is perfectly centered in the container.

.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>

Just keep in mind that centering the h2 with justify-content: center (or space-around or space-between), only works because there is equal balance on both sides. Each pixel of difference between sides will throw off the h2 by a commensurate amount.

In your first and last examples there is a clear imbalance between sides. Standard alignment properties such as justify-content and margin will not work because they center within the available space, not the total space.

You could insert duplicate spans on opposite sides with visibility: hidden to achieve equal balance. But this bloats your mark-up with semantically worthless elements.

Instead, if you have the ability to calculate the width of each span, you can insert pseudo-elements to achieve equal balance.

.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>

Ultimately, as a last resort with CSS, you can center the h2 with absolute positioning. This will remove the element from the document flow, but keep it perfectly centered in the container at all times.

.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 (based on revised question)

Basically, the theory is that while the amount of total <span>s are unknown, what is known is that there will be a total of three elements: <div><h2><div>.

So, if we know there will always be three elements, there is a potential solution using flex properties.

.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>

Here's what's happening:

  • The three elements are flex items, as their parent is a flex container
  • Each item is given a flex: 1, which causes them to distribute container space equally among themselves. The end result is three items of equal width.
  • Now, centering the h2 text in the h2 element will also center the text in the container.
  • Each div can be made a nested flex container, and the spans can be aligned with flex properties.

这篇关于将flex项放在容器中,当被其他flex项包围时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆