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

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

问题描述

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

我想设置它,以便在所有情况下,

位于 flex-box 的中心,而其他跨度将围绕它流动,基于他们的标记.

我基本上是在寻找 align-self CSS 代码,但是对于主轴,而不是横轴 (这个 可能有助于解释我在问什么.

我还将 margin: auto; 应用到我的 <h2>,这是我在阅读 这个(很棒的页面,但是,仍然给我留下了以下问题-除非我没有完全理解所有内容).

这是我得到的代码:

.container {对齐项目:居中;边框:1px纯红色;显示:弹性;对齐内容:居中;宽度:100%;}h2{保证金:自动;]

<h2>我是一个h2</h2><span>我是跨度 1</span><span>我是跨度 2</span><span>我是跨度 3</span>

<div class="容器"><span>我是跨度 1</span><span>我是跨度 2</span><span>我是跨度 3</span><h2>我是一个h2</h2><span>我是跨度 4</span><span>我是跨度 5</span><span>我是跨度 6</span>

<div class="容器"><span>我是跨度 1</span><span>我是跨度 2</span><h2>我是一个h2</h2><span>我是跨度 3</span>

<块引用>

完全重申我的问题:我想知道如何将 <h2> 在我的页面上居中,以便其他 <span> 位于,

将始终位于 flex-box 的 死区 中心.

谢谢.

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

更新

这是@Michael_B

他的回答让我思考.虽然我还没有找到一种方法来做到这一点,但我相信以下是朝着正确方向迈出的一步:

HTML

<div><span>我是跨度 1</span><span>我是跨度 2</span><span>我是跨度 3</span>

<h2>我是一个h2</h2><div><span>我是跨度 4</span><span>我是跨度 5</span><span>我是跨度 6</span>

CSS

.container div {弹性:1 1 自动;文本对齐:居中;}h2{弹性:0 0 自动;保证金:自动;}

.container {对齐项目:居中;边框:1px纯红色;显示:弹性;对齐内容:居中;宽度:100%;}.container div {弹性:1 1 自动;文本对齐:居中;}h2{弹性:0 0 自动;保证金:自动;}

<div>

<h2>我是一个h2</h2><div><span>我是跨度 1</span><span>我是跨度 2</span><span>我是跨度 3</span>

<div class="容器"><div><span>我是跨度 1</span><span>我是跨度 2</span><span>我是跨度 3</span>

<h2>我是一个h2</h2><div><span>我是跨度 4</span><span>我是跨度 5</span><span>我是跨度 6</span>

<div class="容器"><div><span>我是跨度 1</span><span>我是跨度 2</span>

<h2>我是一个h2</h2><div><span>我是跨度 3</span>

基本上,理论是虽然 的总数未知,但已知的是总共会有三个元素:

;<h2><div>

<块引用>

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

再次感谢.

解决方案

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

因此,当一个 flex item 与其他 item 共享空间时,没有单步方法将其居中,除非两侧的兄弟元素的总长度相等.

在您的第二个示例中,h2 两侧的跨度总长度相等.结果,h2 在容器中完美地居中.

.container {显示:弹性;对齐内容:居中;对齐项目:居中;边框:1px纯红色;边距:5px;填充:5px;}p { 文本对齐:居中;}≥跨度{背景颜色:浅绿色;填充:5px;}

<span>我是跨度 1</span><span>我是跨度 2</span><span>我是跨度 3</span><h2>我是一个h2</h2><span>我是跨度 4</span><span>我是跨度 5</span><span>我是跨度 6</span>

<p><span>真实中心</span></p>

请记住,将 h2justify-content: center(或 space-aroundspace-between),只因为两边平衡.边之间的每个像素差异都会使 h2 甩掉相应的量.

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

您可以使用 visibility: hidden 在相对的两侧插入重复的跨度以实现相等的平衡.但这会使用语义上毫无价值的元素使您的标记膨胀.

相反,如果你有能力计算每个跨度的宽度,你可以插入伪元素来实现相等的平衡.

.container {显示:弹性;对齐内容:居中;对齐项目:居中;边框:1px纯红色;边距:5px;填充:5px;}跨度 {弹性:0 0 75px;边框:1px 黑色虚线;box-sizing: 边框框;}div.container:first-child::before {内容: "";宽度:225px;}.container:nth-child(2)::after {内容: "";宽度:75px;}p { 文本对齐:居中;}≥跨度{背景颜色:浅绿色;填充:5px;边界:无;}

<h2>我是一个h2</h2><span>我是跨度 1</span><span>我是跨度 2</span><span>我是跨度 3</span>

<div class="容器"><span>我是跨度 1</span><span>我是跨度 2</span><h2>我是一个h2</h2><span>我是跨度 3</span>

<p><span>真实中心</span></p>

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

.container {显示:弹性;对齐内容:居中;对齐项目:居中;边框:1px纯红色;位置:相对;/* 新的 */高度:50px;}h2{位置:绝对;顶部:50%;左:50%;变换:翻译(-50%,-50%);边距: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 { 文本对齐:居中;}≥跨度{背景颜色:浅绿色;填充:5px;}

<h2>我是一个h2</h2><span>我是跨度 1</span><span>我是跨度 2</span><span>我是跨度 3</span>

<div class="容器"><span>我是跨度 1</span><span>我是跨度 2</span><span>我是跨度 3</span><h2>我是一个h2</h2><span>我是跨度 4</span><span>我是跨度 5</span><span>我是跨度 6</span>

<div class="容器"><span>我是跨度 1</span><span>我是跨度 2</span><h2>我是一个h2</h2><span>我是跨度 3</span>

<p><span>真实中心</span></p>

<小时>

更新(基于修改后的问题)

<块引用>

基本上,理论是虽然 的总数未知,但已知的是总共会有三个元素:

;<h2><div>.

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

.container {显示:弹性;}.container >* {弹性:1;/* 关键规则 */}h2{文本对齐:居中;边距:0;}.container >div {显示:弹性;justify-content:空间环绕;}/* 非必要的装饰风格 */.container { 背景色:浅绿色;边框:1px 实心 #ccc;填充:5px;}.container >* { 边框:1px 红色虚线;}p { 文本对齐:居中;}≥跨度{背景颜色:浅绿色;填充:5px;}

<div><span>我是跨度 1</span><span>我是跨度 2</span><span>我是跨度 3</span>

<h2>我是一个h2</h2><div><span>我是跨度 4</span><span>我是跨度 5</span><span>我是跨度 6</span>

<p><span>真实中心</span></p>

这是正在发生的事情:

<小时>

更多信息和解决方案:

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:


More information and solutions:

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

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆