等距DIV的流体宽度


329

我有一个宽度可变的容器DIV。

在此我有4个DIV,所有300px x 250px ...

<div id="container">
   <div class="box1"> </div>
   <div class="box2"> </div>
   <div class="box3"> </div>
   <div class="box4"> </div>
</div>

我想发生的是框1向左浮动,框4向右浮动,框2和3在它们之间均匀间隔。我希望间距也要流畅,以便将浏览器做得更小,空间也要变小。

在此处输入图片说明


2
为什么不做display:inline-block;浮动呢?
2011年

1
因为IE6 / IE7仅inline-blockinline元素上支持
Lee Price

好的,不确定要使用哪种浏览器。
2011年

1
我能想到的最接近的解决方案是将每个子.box div包裹在另一个25%宽度的div中。然后,将子.box div居中到包装器。.box div将均匀分布,但左和右div不会在边缘右边。
Paul Sham

5
我把@Paul Sham的想法变成了JSFiddle
Sparky

Answers:


440

参见: http : //jsfiddle.net/thirtydot/EDp8R/

  • 可以在IE6 +和所有现代浏览器中使用!
  • 我将您要求的尺寸减半,以使其易于使用。
  • text-align: justify结合在一起.stretch是在处理定位。
  • display:inline-block; *display:inline; zoom:1修复inline-blockIE6 / 7,请参见此处
  • font-size: 0; line-height: 0 修复了IE6中的一个小问题。

#container {
  border: 2px dashed #444;
  height: 125px;
  text-align: justify;
  -ms-text-justify: distribute-all-lines;
  text-justify: distribute-all-lines;
  /* just for demo */
  min-width: 612px;
}

.box1,
.box2,
.box3,
.box4 {
  width: 150px;
  height: 125px;
  vertical-align: top;
  display: inline-block;
  *display: inline;
  zoom: 1
}

.stretch {
  width: 100%;
  display: inline-block;
  font-size: 0;
  line-height: 0
}

.box1,
.box3 {
  background: #ccc
}

.box2,
.box4 {
  background: #0ff
}
<div id="container">
  <div class="box1"></div>
  <div class="box2"></div>
  <div class="box3"></div>
  <div class="box4"></div>
  <span class="stretch"></span>
</div>

多余的span.stretch)可以替换为:after

仍然工作在所有的浏览器相同的上述溶液。:after不适用于IE6 / 7,但distribute-all-lines无论如何他们都在使用,所以没关系。

参见: http : //jsfiddle.net/thirtydot/EDp8R/3/

有一个小的缺点:after:要使最后一行在Safari中完美工作,您必须注意HTML中的空白。

具体来说,这是行不通的:

<div id="container">
    ..
    <div class="box3"></div>
    <div class="box4"></div>
</div>

这样做:

<div id="container">
    ..
    <div class="box3"></div>
    <div class="box4"></div></div>

您可以将其用于任意数量的child,div而无需boxN通过更改将其添加到每个子类中

.box1, .box2, .box3, .box4 { ...

#container > div { ...

这将选择作为div的第一个子元素的任何div #container,并且其下没有其他任何div 。要泛化背景色,可以使用CSS3 n阶选择器,尽管只有IE9 +和其他现代浏览器才支持它:

.box1, .box3 { ...

变成:

#container > div:nth-child(odd) { ...

请参阅此处的jsfiddle示例。


123
我花了3h的时间发现html中每个框之间都应该有空格。“ Justify”在元素之间延伸空间,如果您的内容<div/><div/><div/>不起作用。您需要拥有<div/> <div/> <div/>
venimus,2012年

5
只是想注意一下:),因为如果要处理生成的内容(这是常见的情况),则很难注意。我本来打算使用justify这种情况,但感谢您提供有效的解决方案。为我节省了很多实验(尽管进行了3h调试:D)。另外,我可以添加一条注释,如果您希望最后一行保持对齐,则应添加一些额外的不可见框(以完成该行)
venimus 2012年

4
@venimus:我用这种技术写了另一个答案:stackoverflow.com/questions/10548417/…。您采取了什么措施来消除因添加隐形框而导致的额外高度?
2012年

11
有人可以解释为什么需要.stretch吗?
2013年

6
@HartleySan:需要.stretch/ :after,因为(通常)使用对齐文本,最后一行对齐。在这里,我们确实希望最后一行是合理的,因此需要:after。至于您的第二个问题,我在上一个答案中做了探讨。在该答案中,需要JavaScript。如果您需要支持较旧的浏览器(IE8),那么我相信您确实需要JavaScript。
thirtydot

140

现在最简单的方法是使用flexbox:

http://css-tricks.com/snippets/css/a-guide-to-flexbox/

CSS就是:

#container {
    display: flex;
    justify-content: space-between;
}

演示:http : //jsfiddle.net/QPrk3/

但是,当前只有相对较新的浏览器(http://caniuse.com/flexbox)支持此功能。另外,flexbox布局的规范已经更改了几次,因此可以通过另外包含一个较旧的语法来覆盖更多浏览器:

http://css-tricks.com/old-flexbox-and-new-flexbox/

http://css-tricks.com/using-flexbox/


1
谢谢您,如此简单,我将其应用于固定在页面底部的页脚中的四个均匀间隔的列表。在FF28.0,Chrome 34.0.1847.116 m和IE11中工作。
user1063287

1
Flexbox并不是网络上最受支持的工具,它没有超越边距和填充的经典方法。
TheBlackBenzKid

对于希望用未定义宽度来证明多个div合理的每个人:使用flex-wrap和display:flex选项。它将使用动态宽度包装div。
卡米尔·布兹维斯基

20

如果css3是一个选项,则可以使用css calc()函数来完成。

情况1:单行对齐框(FIDDLE

标记很简单-一堆具有一些容器元素的div。

CSS看起来像这样:

div
{
    height: 100px;
    float: left;
    background:pink;
    width: 50px;
    margin-right: calc((100% - 300px) / 5 - 1px); 
}
div:last-child
{
    margin-right:0;
}

其中-1px修复的IE9 +钙/舍入的错误-看到这里

情况2:在多行上对齐框(FIDDLE

在这里,除了calc()功能外,media queries还必须。

基本思想是为每个#columns状态设置一个媒体查询,然后在其中使用calc()来计算每个元素(上一列中的元素除外)的页边距右边。

这听起来很麻烦,但是如果您使用的是LESS或SASS,则可以轻松完成

(它仍然可以使用常规的CSS完成,但是您必须手动执行所有计算,然后如果更改框的宽度-您必须重新计算所有内容)

下面是使用LESS的示例:(您可以在此处复制/粘贴此代码以进行操作,[这也是我用来生成上述提琴的代码])

@min-margin: 15px;
@div-width: 150px;

@3divs: (@div-width * 3);
@4divs: (@div-width * 4);
@5divs: (@div-width * 5);
@6divs: (@div-width * 6);
@7divs: (@div-width * 7);

@3divs-width: (@3divs + @min-margin * 2);
@4divs-width: (@4divs + @min-margin * 3);
@5divs-width: (@5divs + @min-margin * 4);
@6divs-width: (@6divs + @min-margin * 5);
@7divs-width: (@7divs + @min-margin * 6);


*{margin:0;padding:0;}

.container
{
    overflow: auto;
    display: block;
    min-width: @3divs-width;
}
.container > div
{
    margin-bottom: 20px;
    width: @div-width;
    height: 100px;
    background: blue;
    float:left;
    color: #fff;
    text-align: center;
}

@media (max-width: @3divs-width) {
    .container > div {  
        margin-right: @min-margin;
    }
    .container > div:nth-child(3n) {  
        margin-right: 0;
    }
}

@media (min-width: @3divs-width) and (max-width: @4divs-width) {
    .container > div {  
        margin-right: ~"calc((100% - @{3divs})/2 - 1px)";
    }
    .container > div:nth-child(3n) {  
        margin-right: 0;
    }
}

@media (min-width: @4divs-width) and (max-width: @5divs-width) {
    .container > div {  
        margin-right: ~"calc((100% - @{4divs})/3 - 1px)";
    }
    .container > div:nth-child(4n) {  
        margin-right: 0;
    }
}

@media (min-width: @5divs-width) and (max-width: @6divs-width) {
    .container > div {  
        margin-right: ~"calc((100% - @{5divs})/4 - 1px)";
    }
    .container > div:nth-child(5n) {  
        margin-right: 0;
    }
}

@media (min-width: @6divs-width){
    .container > div {  
        margin-right: ~"calc((100% - @{6divs})/5 - 1px)";
    }
    .container > div:nth-child(6n) {  
        margin-right: 0;
    }
}

因此,基本上,您首先需要确定一个框宽和两个框之间的最小边距。

这样,您可以计算出每个状态需要多少空间。

然后,使用calc()计算右边距,使用nth-child从最后一列的框中删除右边距。

此答案优于公认的答案的优点text-align:justify是,当您有多于一行的框时-最后一行上的框不会“合理化”,例如:如果最后一行上还有2个框,则-不想第一个框位于左侧,下一个框位于右侧-而是使框彼此依序排列。

关于浏览器支持:这将在IE9 +,Firefox,Chrome,Safari6.0 +上运行-(请参阅此处以了解更多详细信息)但是我注意到在IE9 +上,媒体查询状态之间存在一些故障。[如果有人知道如何解决此问题,我真的很想知道:)] <-已在此处修复


13

其他文章提到了flexbox,但是如果需要多于一行的内容,则flexbox的space-between属性会失败(请参阅文章结尾)

迄今为止,唯一的清洁解决方案是

CSS网格布局模块Codepen演示

基本上,相关的代码归结为:

ul {
  display: grid; /* (1) */
  grid-template-columns: repeat(auto-fit, 120px); /* (2) */
  grid-gap: 1rem; /* (3) */
  justify-content: space-between; /* (4) */
  align-content: flex-start; /* (5) */
}

1)使容器元素成为网格容器

2)根据需要使用“自动”列数设置网格。这是为响应式布局完成的。每列的宽度为120像素。(请注意,auto-fit(对于auto-fill)的使用(针对1行布局)会将空轨道折叠为0-允许项目扩展以占用剩余空间。(查看此演示,了解我在说什么))。

3)为网格的行和列设置间隙/装订线-在这里,由于需要“间隔”布局-间隙实际上是最小间隙,因为它会根据需要增大。

4)和5)-类似于flexbox。

body {
  margin: 0;
}
ul {
  display: grid;
  grid-template-columns: repeat(auto-fit, 120px);
  grid-gap: 1rem;
  justify-content: space-between;
  align-content: flex-start;
  
  /* boring properties: */
  list-style: none;
  width: 90vw;
  height: 90vh;
  margin: 2vh auto;
  border: 5px solid green;
  padding: 0;
  overflow: auto;
}
li {
  background: tomato;
  height: 120px;
}
<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

Codepen演示(调整大小以查看效果)


浏览器支持-Caniuse

目前受Chrome(闪烁),Firefox,Safari和Edge支持!...在IE的部分支持下(请参阅Rachel Andrew的这篇文章


注意:

Flexbox的space-between属性非常适合单行项目,但是当应用于包装它的项目的Flex容器时(带有flex-wrap: wrap)会失败,因为您无法控制最后一行项目的对齐方式。最后一行将始终是合理的(通常不是您想要的)

展示:

Codepen(调整大小以查看我在说什么)


进一步阅读CSS网格:


1
答案很低估。这是实现我想要做的最简单,最有效的方法。谢谢。
Barnaby Mercer,

1
这是生成所需功能的最小CSS(没有JS!),并且对大小和空间进行了一些调整。
EKW

1
我已经寻找了一段时间,终于找到了!感谢@Danield
nareeboy

2

这为我制作了5张不同尺寸的图像。

  1. 创建一个容器div
  2. 图片的无序列表
  3. 在CSS上,未排列的内容必须垂直显示且没有项目符号
  4. 调整容器div的内容

这是因为justify-content:space-between,并且在列表中水平显示。

在CSS上

 #container {
            display: flex;
            justify-content: space-between;
 }
    #container ul li{ display:inline; list-style-type:none;
}

在HTML上

<div id="container"> 
  <ul>  
        <li><img src="box1.png"><li>
        <li><img src="box2.png"><li>
        <li><img src="box3.png"><li>
        <li><img src="box4.png"><li>
        <li><img src="box5.png"><li>
    </ul>
</div>

尽管此代码可能很好用,但一个好的答案将包括对它如何工作以及为什么它是一个好的解决方案的解释。
Blackwood


这个反应灵敏吗?
stackdave

1

jQuery你可能会直接针对家长。

如果您不确切地知道有多少儿童会被动态添加,或者只是无法计算出他们的人数,那么这是有用的。

var tWidth=0;

$('.children').each(function(i,e){
tWidth += $(e).width();

///Example: If the Children have a padding-left of 10px;..
//You could do instead:
tWidth += ($(e).width()+10);

})
$('#parent').css('width',tWidth);

这将使beng添加时parent水平生长children

注意:这假定'.children'有一个widthHeight设置

希望对您有所帮助。


1

如果知道每个“行”的元素数和容器的宽度,则可以使用选择器为需要产生合理外观的元素添加边距。

我有三列,我想证明是合理的,所以使用了:

.tile:nth-child(3n+2) { margin: 0 10px }

这样一来,每行的中心div都具有一定的边距,可将第1格和第3 div强制到容器的外部边缘

也非常适合其他事情,例如边框背景颜色等

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.