将左浮动的 div 元素水平居中对齐 x 个。

3

基本上,我希望有一个页面由等大小的div构建而成,例如100x100,还有类似200x100的变体。它们都使用float:left来根据窗口的调整而调整位置。问题是,在这种情况下,比如有时候一行中有3个div,有时候有7个,我不知道如何使它们居中,因为通常右侧会有更多的空间,使其看起来偏离中心。 提前致谢!


2
这是你想要的布局吗?http://i.imgur.com/JEmWoOT.png - Kos
1
请发布一些布局图片和/或您目前拥有的代码。 - yunzen
7个回答

4

你是否要寻找类似这样的效果? 在容器上设置自动 margin 将会水平居中它。从那里开始,你可以使用浮动或内联来展示你想要的布局方式。看一下下面的 CSS 和 HTML:

<div class="container">
    <div></div>
    <div class="variant"></div>
    <div></div>
    <div></div>
    ...
</div>

这段HTML语义化非常简单。理想情况下,我通常会将其作为无序列表来完成,但由于您的标题中提到了 divs,因此我选择了这种方式。

div.container div{
    border: solid 2px black;
    min-height: 100px;
    width: 100px;
    display: inline-block;
    background-color: white;
    vertical-align: top;
    margin: 10px;
}
div.container div.variant{
    width: 200px;
}
div.container{
    margin: auto;
    max-width: 620px;
    background-color: #ecefec;
    padding: 10px;
    font-size: 0;
}

JS Fiddle

这里发生了什么

我们通过属性display: inline-block将块元素内联; 为此,我们需要制定一些额外的规则,以便在它们具有不同高度的情况下正确显示它们(这些元素将自动清除行,而不像浮动元素)。

内联元素上的属性vertical-align:top确保它被排列,使其顶部边界与相邻元素的顶部边界齐平。

属性font-size:0确保标记空格未被计入块元素之间间距的计算中(否则,每个关闭一个div标签到打开另一个标签之间的空格都会被包括在内)。

应该可以实现您要达到的目标。

更新

在查看您对另一个问题的评论后,我们需要向容器div的CSS添加text-align:center;,因为这将使每个行居中在容器内。

示例


1
谢谢,这非常有用,但并没有解决一个特定的问题:当容器缩小到最大宽度以下时,盒子不再居中(空间只在右侧)(第一个演示)。如果使用 text-align: center,那么每一行都会单独居中,这完全破坏了它们类似网格的布局(第二个演示)。 - Kos
1
很遗憾,要实现所描述的场景需要使用一些相当复杂的JavaScript。即使是display: table布局也需要一个固定的宽度。否则,请尝试使用flexbox模式。它专门为像这样没有明确解决方案的复杂布局问题而设计。然而,目前浏览器的支持情况不太稳定。 - Josh Burgess

2
这个页面上有很多问题和答案,以至于很难弄清楚OP真正想要什么,但是我会尽力帮助。在漂亮的jsFiddle上构建,由Josh Burgess在他的回答中提供。我不确定他的jsFiddle是否已经完全符合Kos或OP的要求,但我想通过使用flexbox模型来补充他的答案,因为这样可以添加很多其他选项,您可能需要考虑。
首先,弹性盒模型在过去几年中发生了相当大的变化,目前 Chrome和Opera已经完全支持该模型,而其他主要浏览器则仅部分支持。就下面示例所需的功能支持而言,我认为除FireFox外,所有当前版本的主流浏览器都应该能够正常工作。预计FireFox将在版本22中完全支持新的弹性盒模型,该版本计划于2013年6月25日发布
现在,这里有一个 Josh Burgess jsFiddle 的副本,它展示了与他提供的更新示例 jsFiddle 完全相同的外观和行为,但是使用了弹性盒模型来实现。
div.container {
    margin: auto;
    max-width: 620px;
    background-color: #ecefec;
    padding: 10px;
    font-size: 0;

    display: -webkit-flex;    /* Chrome */
    display: -ms-flexbox;     /* IE 10 */    
    display: flex;            /* Opera 12.1, Firefox 20+ */

    /* Chrome */
    -webkit-flex-flow: row wrap;
    -webkit-justify-content: center;

    /* IE10 */
    -ms-flex-flow: row wrap;
    -ms-justify-content: center;

    /* Opera 12.1, Firefox 20+ */
    flex-flow: row wrap;
    justify-content: center;
}

现在看看当我将justify-content的值更改为以下内容时会发生什么:

如果您不介意div没有特定的宽度,甚至可以像我在这个jsFiddle中所做的那样将它们设置为自动调整大小的flex box,这实际上将div的width转换为min-width

div.container div {
  -webkit-flex: auto;        /* Chrome */
  -ms-flex: auto;            /* IE10 */
  flex: auto;                /* Opera 12.1, Firefox 20+ */
}

无论如何,我认为这是非常强大的东西。虽然我意识到它在所有主要浏览器中仍不能完美地工作可能已经足够成为当前实施此功能的任何人的一个巨大障碍,但我认为这个功能应该在像OP这样的页面上提到。

此外,如果Josh Burgess answer仍不完全符合Kos或OP所寻找的内容,一些提供的jsFiddles(在支持它们的浏览器中查看)可以用来解释他们究竟在寻找什么。

1
谢谢,我刚开始学习flexbox,这篇文章非常有用。然而,我认为它并不符合原帖的目标(是的,我明白可能没有描述得足够清楚)。请看一下James Holderness的演示;你认为使用flexbox可以简化它吗?我很想知道是否有这种可能。 - Kos

2
我有一个解决方案,我认为它可以满足你的需求。它使用媒体查询来调整容器的宽度,使其成为当前视口宽度中适合的最大块宽度的倍数。该容器然后使用自动边距居中,其中的块只是左对齐。
由于容器始终是块宽度的精确倍数,因此容器内永远不会有多余的空间。并且容器本身也是居中的,因此两侧的间距将完美平衡。
计算媒体查询有点繁琐,因此我更喜欢使用SASS进行计算,但如果您的块相当大(块越大,所需的媒体查询就越少),则不需要太多的媒体查询。 Codepen example using SASS 如果您更喜欢LESS或普通的CSS,我很乐意提供转换。

1
媒体查询胜利了?一个好的、出人意料的想法。这个方法实际上像我设想的那样有效,我希望它也能帮到OP。 :-) - Kos
1
很高兴你喜欢这个解决方案。这是一个非常棒的奖励。谢谢。 :) - James Holderness

2

错误的(红色空间): http://tinypic.com/view.php?pic=b4aqzl&s=5正确的(两侧相同的空间): http://tinypic.com/view.php?pic=334ntk0&s=5 - user1826176
1
好的,我想我明白了 - http://jsfiddle.net/VYUKf/ 你想要一个整体居中的布局,但保留“text-align: left”网格状外观,是吗? - Kos
是的,基本上就是这样,但在这种情况下,它不像我的图像示例那样保持在网格中,每行都有自己的中心。 - user1826176

1
你是在寻找类似这样的东西吗?

HTML:

<div class="container">
    <div class="small"></div>
    <div class="large"></div>
    <div class="small"></div>
    <div class="mini"></div>
    <div class="small"></div>
    <div class="mini"></div>
    <div class="small"></div>
</div>

CSS:

.container {
    text-align: center;
    letter-spacing:-0.25em;
    word-spacing: -0.25em;
}
.small, .large, .mini {
    display: inline-block;
    *display: inline;
    zoom: 1;
    height: 50px;
    letter-spacing:normal;
    word-spacing: normal;
}
.small {
    width: 25%;
    background: #f00;
}
.large {
    width: 50%;
    background: #0f0;
}
.mini {
    width: 12.5%;
    background: #00f;
}

1
据我所了解,这些块应该是固定大小的(100x100的增量),在流式宽度容器中换行(@原帖发布者:请确认一下 :-))。 - Kos
1
@Kos,我看了你的例子,但是用CSS似乎不可能。因为你需要将所有的div都包裹在一个具有动态div的容器中。在这种情况下,容器内的内容(div)将根据容器大小的宽度显示。但是你要寻找的情况是像容器一样,应该根据第一行的宽度调整。这意味着需要重新计算容器的宽度。这只能通过JavaScript实现。 - Tarun

1

如果我理解正确,您有一些不同宽度的元素,并且希望将这组元素水平居中在页面上。

如果是这种情况,对我有效的解决方案如下:

HTML:

<div class="container">
    <div class="outer">
        <div class="inner">
            <!-- your elements here -->
        </div>
    </div>
</div>

CSS:
.container {
    overflow: hidden;
}
.container .outer {
    float: left;
    position: relative;
    left: 50%;
}
.container .outer .inner {
    float: left;
    position: relative;
    left: -50%;
}

基本上,正在发生的是将 .outer div 向右移动,以使其左边缘位于其父元素的中心位置。然后,.inner 被向左移动50%,这意味着 .inner 的中心与 .outer 的左边缘对齐。最终,.inner 及其内容将在屏幕中心对齐,而不管 .inner 中元素的总宽度如何。
使用自动边距要求包含内容的元素具有定义的宽度。这种解决方案通过一些非语义标记牺牲了一些性能来避免这个问题。
以下是演示它的演示: JsFiddle DEMO

这是一个不错的解决方案,但在一些元素换行后,网格不再居中。 - Kos
正确;这个解决方案只适用于单行元素。目前仍不清楚发布者是否需要此功能适用于单个包含元素中的多行元素。如果他事先知道每行会出现多少项,他可以将每组元素包装在上述标记中。 - jackwanders

1

HTML:

<div id="container">
    <div class="small"></div>
    <div class="large"></div>
    <div class="small"></div>
    <div class="mini"></div>
    <div class="small"></div>
    <div class="mini"></div>
    <div class="small"></div>
</div>

CSS:
* {
    margin: 0;
    padding: 0;
}
#container {
    margin: 0px auto;
    overflow: hidden;
    border: 1px solid #f00;
    letter-spacing:-0.25em;
    word-spacing: -0.25em;
    line-height: 0;
}
.small, .large, .mini {
    display: inline-block;
    *display: inline;
    float: left;
    zoom: 1;
    height: 50px;
    letter-spacing:normal;
    word-spacing: normal;
    line-height: auto;
}
.small {
    width: 100px;
    background: #f00;
}
.large {
    width: 200px;
    background: #0f0;
}
.mini {
    width: 50px;
    background: #00f;
}

jQuery:

resizeContainer();

function resizeContainer() {
    var containerWidth = 0;
    $('#container > div').each(function () {
        var self = $(this);
        var offset = self.offset();
        if (offset.top < 2) {
            containerWidth += self.width();
        } else {
            $('#container').css('width', containerWidth);
            return false;
        }
    });
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接