Html 如何居中弹性容器但左对齐弹性项目

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32802202/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 18:17:12  来源:igfitidea点击:

How to center a flex container but left-align flex items

htmlcssflexbox

提问by Etienne No?l

I want the flex items to be centered but when we have a second line, to have 5 (from image below) under 1 and not centered in the parent.

我希望 flex 项目居中,但是当我们有第二行时,在 1 下有 5 个(来自下图)而不是在父项中居中。

enter image description here

在此处输入图片说明

Here's an example of what I have:

这是我所拥有的一个例子:

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;
}
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
</ul>

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

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

采纳答案by Michael Benjamin

Flexbox Challenge & Limitation

Flexbox 挑战与限制

The challenge is to center a group of flex items and left-align them on wrap. But unless there is a fixed number of boxes per row, and each box is fixed-width, this is currently not possible with flexbox.

挑战是将一组 flex 项目居中并在 wrap 上左对齐它们。但是除非每行有固定数量的框,并且每个框都是固定宽度的,否则目前 flexbox 无法做到这一点。

Using the code posted in the question, we could create a new flex container that wraps the current flex container (ul), which would allow us to center the ulwith justify-content: center.

使用问题中发布的代码,我们可以创建一个新的 flex 容器来包装当前的 flex 容器 ( ul),这将允许我们将ulwith居中justify-content: center

Then the flex items of the ulcould be left-aligned with justify-content: flex-start.

然后 的 flex 项ul可以左对齐justify-content: flex-start

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

ul {
    display: flex;
    justify-content: flex-start;
}

This creates a centered group of left-aligned flex items.

这将创建一组居中的左对齐 flex 项目。

The problem with this method is that at certain screen sizes there will be a gap on the right of the ul, making it no longer appear centered.

这种方法的问题在于,在某些屏幕尺寸下, 右侧会出现间隙ul,使其不再显示居中。

enter image description hereenter image description here

在此处输入图片说明在此处输入图片说明

This happens because in flex layout (and, actually, CSS in general) the container:

发生这种情况是因为在 flex 布局(实际上,一般来说,CSS)中的容器:

  1. doesn't know when an element wraps;
  2. doesn't know that a previously occupied space is now empty, and
  3. doesn't recalculate its width to shrink-wrap the narrower layout.
  1. 不知道元素何时换行;
  2. 不知道以前占用的空间现在是空的,并且
  3. 不会重新计算其宽度以收缩包装较窄的布局。

The maximum length of the whitespace on the right is the length of the flex item that the container was expecting to be there.

右边空白的最大长度是容器期望在那里的弹性项目的长度。

In the following demo, by re-sizing the window horizontally, you can see the whitespace come and go.

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

DEMO

演示



A More Practical Approach

更实用的方法

The desired layout can be achieved without flexbox using inline-blockand media queries.

无需使用 flexboxinline-block媒体查询即可实现所需的布局。

HTML

HTML

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
</ul>

CSS

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

The above code renders a horizontally-centered container with left-aligned child elements like this:

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

enter image description here

在此处输入图片说明

DEMO

演示



Other Options

其他选项

回答by Joe82

You can achieve it with CSS Grid, just use repeat(autofit, minmax(width-of-the-element, max-content))

您可以使用 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;
}
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
</ul>

http://jsfiddle.net/rwa20jkh/

http://jsfiddle.net/rwa20jkh/

回答by RameshVel

As @michael suggested, this is a limitation with current flexbox. But if you want to still use flexand justify-content: center;, then we can workaround this by adding a dummy lielement and assign margin-left.

正如@michael 所建议的,这是当前 flexbox 的一个限制。但是,如果您仍然想使用flexand justify-content: center;,那么我们可以通过添加一个虚拟li元素和 assign来解决这个问题margin-left

    const handleResize = () => {
        const item_box = document.getElementById('parentId')
        const list_length  = item_box.clientWidth
        const product_card_length = 200 // length of your child element
        const item_in_a_row = Math.round(list_length/product_card_length)
        const to_be_added = item_in_a_row - parseInt(listObject.length % item_in_a_row) // listObject is the total number items
        const left_to_set = (to_be_added - 1 ) * product_card_length // -1 : dummy item has width set, so exclude it when calculating the left margin 
        const dummy_product = document.querySelectorAll('.product-card.dummy')[0]
        dummy_product.style.marginLeft = `${left_to_set}px`
    }
    handleResize() // Call it first time component mount
    window.addEventListener("resize", handleResize); 

Check this fiddle (resize and see )or video for reference

检查此小提琴(调整大小并查看)视频以供参考

回答by Patrik Rikama-Hinnenberg

One way to get the desired style with margins is to do the following:

获得带有边距的所需样式的一种方法是执行以下操作:

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

#innercontainer {
    display: flex;
    flex: 0.9; -> add desired % of margin
    justify-content: flex-start;
}