如何在CSS中使一个未知宽度的盒子居中?

25

我有这个 html:

<div class="object-box">
    <img ... />
    <span class="caption">This is the caption</span>
</div>

这段 CSS 配合使用:

.object-box .caption, .object-box img {
    display: block;
}
.object-box {
    border: 1px solid;
}

我希望周围的div能够紧贴其内容而收缩。我可以通过使用float: ...display: inline-block来实现这一点。但是,我也希望它以margin: auto的方式居中于页面上。这两种方法似乎不兼容。

是否可能创建这样一个紧包裹的、居中的容器,而不添加包装元素?

编辑:

jsFiddle在这里


18
CSS的混乱程度可以从一些看起来本应该很简单的操作却并不明显的事情中得到体现。这并不是在责怪NXT,完全是CSS规范及其编写人员的问题。像display: center;position: center或者某些其他选项本应该成为内置的单属性选项。 - Nick Craver
1
这段代码是否表示“不,这是不可能的”? - NXTBoy
4
没有问题,请看这里:http://haslayout.net/css-tuts/Horizontal-Centering。它不应该那么复杂,这是一种非常常见的操作,应该容易实现。 - Nick Craver
7个回答

20
<!doctype html>
<html>
    <head>
    <title>ugh</title>
    <style>
        div#not-floated {
        display:table;
        margin:0 auto;
        }

        div#floated {
        float:right;
        position:relative;
        right:50%;
        }

        div#floated-inner {
        float:left;
        position:relative;
        left:50%;
        }

    </style>
    <!--[if lt IE 8]>
        <style type="text/css">

            #container { text-align: center; }
                #container * { text-align: left; }
                div#not-floated {
                    zoom: 1;
                    display: inline;
                }
        </style>
    <![endif]-->

    </head>

    <body>


    <div id="container">
        <div id="not-floated">
        <img src="http://www.google.co.uk/logos/d4g_worldcup10_uk-hp.jpg"><br>
        ok.
        </div>
    </div>
    <div id="floated-container">
        <div id="floated"><div id="floated-inner">
        <img src="http://www.google.co.uk/logos/d4g_worldcup10_uk-hp.jpg">
        </div></div>
    </div>

    </body>

</html>

简单地说,display:table; 会导致现代浏览器中的块级元素收缩包裹,这是在现代浏览器中居中宽度不定的块级元素唯一的方法 使用 margin:0 auto;

在IE中,只需使用父元素设置文本居中即可使您的收缩包装的display:inline 块级元素居中。

对于浮动元素,在IE中只需使用容器的50%计算即可。


注意:没有在IE8中进行测试。如果无法正常工作,请告诉我。 - meder omuraliev
适用于IE9。 - Calmarius

17

几个月后,我想插一嘴。居中一个宽度未知的div是一个常见的问题,所以你可能需要创建一个可重用的解决方案。

包裹着宽度未知的div的HTML,你想要它居中:

<div class="centered-block-outer">
 <div class="centered-block-middle">
  <div class="centered-block-inner">

   <!-- div that you'd like to center goes here -->

  </div>
 </div>
</div>
 /* To center a block-level element of unknown width */
 .centered-block-outer { 
   overflow: hidden;
   position: relative;/* ie7 needs position:relative here*/
 }
.centered-block-middle {
  float: left;
  position:relative;
  left:50%;
}
.centered-block-inner {
  position:relative;
  left:-50%;
}
这个方法之所以有效是因为在这里解释:http://www.tightcss.com/centering/center_variable_width.htm
烦人的部分是你需要创建三个div才能使其正常工作 - CSS真的应该提供更好的解决方案。但好消息是,这个解决方案可以跨浏览器和整个网站使用。
祝好运!

+1:请看一下我的答案,针对您的回答提出了完善建议。很高兴听到您的想法。干杯! - Luca Borrione
1
对我来说可以工作,但必须将 overflow: hidden 更改为 overflow: visible - chim

1
CSS现在有一个叫做“flex”布局的东西,在我有限的使用中,它表现得非常好。

https://www.w3.org/TR/css-flexbox-1/

尝试按照以下方式进行操作:
<html>
<head>
<style>
body {
    display: flex;
    align-items: center;
    justify-content: center;
}

.object-box {
    border: 1px solid;
}
</style>
</head>
<body>
  <div class="object-box">
    <img ... />
    <span class="caption">This is the caption</span>
  </div>
</body>
</html>

1
一个 div 标签似乎不起作用,但是 span 标签可以缩小以适应。希望代码能够解释清楚。我还添加了一些对齐方式。
<html>
    <head>
        <title>TEST!</title>
        <style type="text/css"> 
            .object-box-wrapper{width:100%;text-align:center;}
            .object-box {
                border: 1px solid;
                text-align:left;
            }
        </style>
    </head>
    <body>
        <div class="object-box-wrapper">
            <span class="object-box">
                <span class="caption">This is the caption</span>
            </span>
        </div>
    </body>
</html>

2
我不能在body元素上使用text-align:center - NXTBoy
这确实会带来一些问题;但是通过一个“包装器”,它可以完成;否则我看不到其他方法。抱歉。我已经编辑了我的帖子,展示了一个可能的包装器解决方案。 - PlagueEditor

0

应该可以用类似这样的代码

HTML:

<msgbox>
    <p>
        foo
    </p>
</msgbox>

以及CSS:

msgbox {
    width: 100%;
    display: block;
    text-align: center;
}
p {
    display: inline-block;
}

唯一令人遗憾的是,当使用绝对定位时,msgbox元素会阻止通过它进行点击(但这只是一个相关问题,可能不是您的问题)


-1
我所知道的不使用JavaScript实现的唯一方法是将你的
设置为position:absoluteleft:50%

1
我可以使用额外的包装 div 来完成它。 - NXTBoy
1
我认为你想要它没有包装器? - edl

-3
我为了一个jQuery相册不得不这样做...我最终的解决方案是当选择一张照片时,当前照片会渐隐而新照片会被加载,然后计算容器的一半宽度减去照片一半宽度的差值。我会用这个值设置margin-left(以及margin-top垂直方向上)。
    thewidth = $('#thephoto').width();
    theheight = $('#thephoto').height();
    $('#thephoto').css("margin-top",250-(theheight/2));
    $('#thephoto').css("margin-left",287.5-(thewidth/2));
    $('#thephoto').fadeIn(300);

这就是我Flash背景的好处 :)


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