关于html:当副商品的宽度不同时,使中间商品居中

Keep the middle item centered when side items have different widths

enter image description here

想象一下以下布局,其中的点表示框之间的空间:

1
[Left box]......[Center box]......[Right box]

当我删除右框时,我希望中心框仍位于中心,如下所示:

1
[Left box]......[Center box].................

如果我要删除左框,也是如此。

1
................[Center box].................

现在,当中心框中的内容变长时,它将在保持居中状态的同时占用所需的可用空间。左框和右框永远不会缩小,因此,当没有空间的地方overflow:hiddentext-overflow: ellipsis会生效以破坏内容。

1
[Left box][Center boxxxxxxxxxxxxx][Right box]

以上是我的理想情况,但我不知道如何实现此效果。因为当我创建如下的flex结构时:

1
2
3
4
5
.parent {
    display : flex; // flex box
    justify-content : space-between; // horizontal alignment
    align-content   : center; // vertical alignment
}

如果左右框的大小完全相同,我将获得所需的效果。但是,如果两者之一的大小不同,则居中框不再真正居中。

有没有人可以帮助我?

更新资料

justify-self会很好,这将是理想的:

1
2
3
4
5
6
7
.leftBox {
     justify-self : flex-start;
}

.rightBox {
    justify-self : flex-end;
}


If the left and right boxes would be exactly the same size, I get the desired effect. However when one of the two is a different size the centered box is not truly centered anymore. Is there anyone that can help me?

这是一种使用flexbox将中间项目居中的方法,而与兄弟姐妹的宽度无关。

主要特征:

  • 纯CSS
  • 没有绝对定位
  • 没有JS / jQuery

使用嵌套的伸缩容器和auto边距:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.container {
  display: flex;
}
.box {
  flex: 1;
  display: flex;
  justify-content: center;
}

.box:first-child > span { margin-right: auto; }

.box:last-child  > span { margin-left: auto;  }

/* non-essential */
.box {
  align-items: center;
  border: 1px solid #ccc;
  background-color: lightgreen;
  height: 40px;
}
p {
  text-align: center;
  margin: 5px 0 0 0;
}
1
2
3
4
5
6
7
  <span>short text</span>
  <span>centered text</span>
  <span>loooooooooooooooong text</span>

<p>
 true center
</p>

运作方式如下:

  • 顶级div(.container)是Flex容器。
  • 现在,每个子div(.box)都是一个弹性项目。
  • 为每个.box项目指定了flex: 1,以便平均分配容器空间(更多详细信息)。
  • 现在,这些项目占用了该行中的所有空间,并且宽度相等。
  • 使每个项目成为一个(嵌套的)flex容器,并添加justify-content: center
  • 现在,每个span元素都是一个居中的flex项目。
  • 使用flex auto边距左右移动外部span

您也可以放弃justify-content并仅使用auto边距。

但是justify-content可以在这里工作,因为auto边距始终具有优先级。

8.1. Aligning with auto
margins

Prior to alignment via justify-content and align-self, any
positive free space is distributed to auto margins in that dimension.


  • 在容器中使用三个伸缩物品
  • flex: 1设置为第一个和最后一个。这使它们平均增长以填充中间一个剩余的可用空间。
  • 因此,中间的人倾向于居中。
  • 但是,如果第一个或最后一个项目的内容广泛,则该弹性项目也会由于新的min-width: auto初始值而增长。

    注意Chrome似乎无法正确实现此目的。但是,您可以将min-width设置为-webkit-max-content-webkit-min-content,它也将起作用。

  • 只有在这种情况下,中间元素才会被推出中心。

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    .outer-wrapper {
      display: flex;
    }
    .item {
      background: lime;
      margin: 5px;
    }
    .left.inner-wrapper, .right.inner-wrapper {
      flex: 1;
      display: flex;
      min-width: -webkit-min-content; /* Workaround to Chrome bug */
    }
    .right.inner-wrapper {
      justify-content: flex-end;
    }
    .animate {
      animation: anim 5s infinite alternate;
    }
    @keyframes anim {
      from { min-width: 0 }
      to { min-width: 100vw; }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        Left
     
     
        Center
     
     
        Right
     

    <!-- Analogous to above --> LeftCenterRightLeftCenterRight


    这是使用网格而不是flexbox的答案。此解决方案不需要HTML中多余的孙元素,就像接受的答案一样。即使一侧的内容足够长以溢出到中心,它也可以正常工作,这与2019年的网格答案不同。

    该解决方案不做的一件事就是显示省略号或将多余的内容隐藏在中心框中,如问题中所述。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    section {
      display: grid;
      grid-template-columns: 1fr auto 1fr;
    }

    section > *:last-child {
      white-space: nowrap;
      text-align: right;
    }

    /* not essential; just for demo purposes */
    section {
      background-color: #eee;
      font-family: helvetica, arial;
      font-size: 10pt;
      padding: 4px;
    }

    section > * {
      border: 1px solid #bbb;
      padding: 2px;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <section>
      left
      center
      right side is longer
    </section>

    <section>
      left
      center
      right side is much, much longer
    </section>

    <section>
      left
      center
      right side is much, much longer, super long in fact
    </section>


    代替使用默认的flexbox,使用grid可以在CSS的2行代码中解决它,而在顶级子代中则无需额外的标记。

    HTML:

    1
    2
    3
    4
    5
    <header class="header">
      variable content
      variable content
      variable content which happens to be very long
    </header>

    CSS:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    .header {
      display: grid;
      grid-template-columns: [first] 20% auto [last] 20%;
    }
    .middle {
      /* use either */
      margin: 0 auto;
      /* or */
      text-align: center;
    }

    Flexbox摇摇欲坠,但不应成为所有解决方案的答案。在这种情况下,网格显然是最干净的选择。

    甚至为您的测试乐趣制作了一个Codepen:
    https://codepen.io/anon/pen/mooQOV


    您可以这样做:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    .bar {
        display: flex;    
        background: #B0BEC5;
    }
    .l {
        width: 50%;
        flex-shrink: 1;
        display: flex;
    }
    .l-content {
        background: #9C27B0;
    }
    .m {
        flex-shrink: 0;
    }
    .m-content {    
        text-align: center;
        background: #2196F3;
    }
    .r {
        width: 50%;
        flex-shrink: 1;
        display: flex;
        flex-direction: row-reverse;
    }
    .r-content {
        background: #E91E63;
    }
    1
    2
    3
    4
    5
    6
    7
            This is really long content.  More content.  So much content.
       
       
            This will always be in the center.
       
       
            This is short.


    这是另一种方法,在父母和孩子中使用display: flex

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    .Layout{
        display: flex;
        justify-content: center;
    }
    .Left{
        display: flex;
        justify-content: flex-start;
        width: 100%;
    }
    .Right{
        display: flex;
        justify-content: flex-end;
        width: 100%;
    }
    1
    2
    3
        I'm on the left
        Centered
        I'
    m on the right


    您还可以使用这种简单的方法来实现中间元素的精确中心对齐:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    .container {
        display: flex;
        justify-content: space-between;
    }

    .container .sibling {
        display: flex;
        align-items: center;
        height: 50px;
        background-color: gray;
    }

    .container .sibling:first-child {
        width: 50%;
        display: flex;
        justify-content: space-between;
    }

    .container .sibling:last-child {
        justify-content: flex-end;
        width: 50%;
        box-sizing: border-box;
        padding-left: 100px; /* .center's width divided by 2 */
    }

    .container .sibling:last-child .content {
        text-align: right;
    }

    .container .sibling .center {
        height: 100%;
        width: 200px;
        background-color: lightgreen;
        transform: translateX(50%);
    }

    codepen:https://codepen.io/ErAz7/pen/mdeBKLG