如何使Flex容器居中但左对齐flex项目

Eti*_*oël 67 html css css3 flexbox

我希望flex项目居中,但是当我们有第二行时,将5(从下面的图像)下调到1并且不在父项中居中.

在此输入图像描述

这是我的一个例子:

ul {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  margin: 0;
  padding: 0;
}
li {
  list-style-type: none;
  border: 1px solid gray;
  margin: 15px;
  padding: 5px;
  width: 200px;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/8jqbjese/2/

Mic*_*l_B 61

Flexbox挑战与局限

挑战在于将一组柔性物品居中并将它们对齐在左侧.但除非每行有固定数量的盒子,并且每个盒子都是固定宽度的,所以目前这对于flexbox来说是不可能的.

使用张贴在问题的代码,我们可以创建一个包装目前柔性容器(一个新的Flex容器ul),这将使我们能够居中uljustify-content: center.

然后ul可以将左侧的柔性项目与左侧对齐justify-content: flex-start.

#container {
    display: flex;
    justify-content: center;
}

ul {
    display: flex;
    justify-content: flex-start;
}
Run Code Online (Sandbox Code Playgroud)

这将创建一个居中的左对齐弹性项目组.

这种方法的问题在于,在某些屏幕尺寸的右侧会有一个间隙ul,使其不再显示居中.

在此输入图像描述 在此输入图像描述

发生这种情况是因为在flex布局中(实际上,通常是CSS)容器:

  1. 不知道什么时候元素包裹;
  2. 不知道以前占用的空间现在是空的,并且
  3. 不会重新计算其宽度以收缩包装较窄的布局.

右边的空白的最大长度是容器期望在那里的flex项的长度.

在下面的演示中,通过水平调整窗口大小,您可以看到空白来去.

DEMO


更实用的方法

无需使用flexbox inline-block媒体查询即可实现所需的布局.

HTML

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

CSS

ul {
    margin: 0 auto;                  /* center container */
    width: 1200px;
    padding-left: 0;                 /* remove list padding */
    font-size: 0;                    /* remove inline-block white space;
                                        see https://stackoverflow.com/a/32801275/3597276 */
}

li {
    display: inline-block;
    font-size: 18px;                 /* restore font size removed in container */
    list-style-type: none;
    width: 150px;
    height: 50px;
    line-height: 50px;
    margin: 15px 25px;
    box-sizing: border-box;
    text-align: center;
}

@media screen and (max-width: 430px) { ul { width: 200px; } }
@media screen and (min-width: 431px) and (max-width: 630px) { ul { width: 400px; } }
@media screen and (min-width: 631px) and (max-width: 830px) { ul { width:600px;  } }
@media screen and (min-width: 831px) and (max-width: 1030px) { ul { width: 800px; } }
@media screen and (min-width: 1031px) and (max-width: 1230px) { ul { width: 1000px; } }
Run Code Online (Sandbox Code Playgroud)

上面的代码呈现一个水平居中的容器,其中包含左对齐的子元素,如下所示:

在此输入图像描述

DEMO


其他选择

  • 是的,很多人想要做的事情并最终使用flexbox实际上只是创建一个网格.幸运的是,当这个到达时,CSS Grids将覆盖更多的最终状态. (3认同)

Joe*_*e82 22

您可以使用 CSS Grid 实现它,只需使用 repeat(autofit, minmax(width-of-the-element, max-content))

ul {
       display: grid;
       grid-template-columns: repeat(auto-fit, minmax(210px, max-content));
       grid-gap: 16px;
       justify-content: center;
       padding: initial;
}

li {
    list-style-type: none;
    border: 1px solid gray;
    padding: 5px;
    width: 210px;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/rwa20jkh/

  • @Red 有一点是错误的。我将 `justify-items: center` 更改为 `justify-content:center`,现在它完美居中了。 (2认同)

Mar*_*ten 10

不知何故,@Joe82 的答案对我不起作用。然而,我发现这是正确的方法。阅读这篇文章后auto-fitauto-fill我发现自动调整会在可能的情况下创建新列;然而,它会折叠它们,以便网格项填充整个可用空间(如果它们的最大宽度允许的话)。

对于那些感兴趣的人: auto-fill在可能的情况下也会创建新列,但不会让它们折叠,因此它会创建空的可见列,这会占用空间。您可以在下图中看到这一点:自动填充和自动调整的区别图解

因此,我使用了repeat(auto-fit, minmax(10rem, 1fr))“网格模板列”。

然后我设置justify-itemscenter,这会将网格区域内的项目在内联轴上对齐。

我还希望列和行之间有一些“边距”,因此我添加了 arow-gap和 a column-gapof1rem速记。

因此,我将以下 CSS 添加到我的 div 中,其中包含网格项:

.card-section {
  width: 100%;
  display: grid;
  justify-items: center;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
}
Run Code Online (Sandbox Code Playgroud)

我知道这并不完全是OP想要实现的目标,但也许它可以帮助那些和我有同样问题并偶然发现这个问题的人。