使用 CSS 创建等距对象

Avatar of Chris Coyier
Chris Coyier 发布

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

请直接带我到解决方案。

创建水平排列的一行等距对象是网页设计中另一项比它应该更困难的事情。这可能是一项非常有用的功能,尤其是在流体宽度布局中,您试图充分利用可用的水平空间时。

equidistant.png

以下是我们试图实现的目标

  • 最左侧的对象与其父元素左对齐
  • 最右侧的对象与其父元素右对齐
  • 每个对象始终彼此等距
  • 当浏览器窗口变窄时,对象将停止重叠
  • 当浏览器窗口变窄时,对象不会换行
  • 该技术可在流体宽度环境中工作。甚至在一个居中的环境中。

我尝试了许多不同的技术来实现这一点。让我们回顾一下我所有的失败尝试,然后转向最终似乎效果很好的技术。

失败:为每个对象设置百分比左定位

首先,我为每个图像赋予了一个唯一的类

<img src="images/shape-red.png" class="first-r">
<img src="images/shape-green.png" class="second-r">
<img src="images/shape-yellow.png" class="third-r">
<img src="images/shape-blue.png" class="fourth-r">

然后,我为每个类设置了基于百分比的左定位

img.first-r  { left: 0%; position: relative; }
img.second-r { left: 25%; position: relative; }
img.third-r  { left: 50%; position: relative; }
img.third-r  { left: 75%; position: relative; }

请注意相对定位。这是为了让最左侧的图像尊重父元素而必需的,假设内容居中而不是左对齐。问题在于应用于最右侧对象的左外边距是浏览器窗口宽度的 75%,但它是从父元素的左侧开始应用,而不是从浏览器窗口的左侧开始。这可能导致最右侧的元素超出屏幕(不尊重父元素的右边缘)。此外,不可思议的是,如果您将浏览器窗口缩小到足够窄,这些元素最终将换行。

如果您在此处切换到绝对定位,则可以解决上述部分问题,但随后您的对象将左对齐,并完全忽略父元素的左位置。此外,在浏览器窗口尺寸足够窄的情况下,图像将重叠。但是,至少对象是等距的!

失败:为对象设置公共百分比左外边距

我的下一次尝试是为每个元素(第一个元素除外)设置一个公共百分比左外边距。

<span class="do-not-wrap">
  <img src="images/shape-red.png">
  <img src="images/shape-green.png" class="mover">
  <img src="images/shape-yellow.png" class="mover">
  <img src="images/shape-blue.png" class="mover">
</span>

应用外边距

img.mover {
  margin-left: 15%;
}

您应该能够从查看该百分比看出此技术注定会失败。我只是选择了一个看起来效果最佳的百分比。我无法想到任何在这里可行的数学方法。因为父元素是浏览器窗口宽度的百分比,而外边距是浏览器窗口的百分比,而不是父元素的百分比,所以增长率将非常难以匹配。还要注意“不换行”跨度,这是为了防止……等等……换行而必需的。但是,至少对象是等距的!

失败:直接使用表格!

即使“放弃”CSS 似乎也无法解决此问题。我认为这肯定可以奏效,因为表格具有有时有用、有时令人恼火的自动均匀间隔单元格的能力。

<table>
	<tr>
		<td class="leftalign">
			<img src="images/shape-red.png">
		</td>
		<td>
			<img src="images/shape-green.png">
		</td>
		<td>
			<img src="images/shape-yellow.png">
		</td>
		<td class="rightalign">
			<img src="images/shape-blue.png">
		</td>
	</tr>
</table>

请注意第一个和最后一个单元格中的额外对齐类。如果所有单元格都居中,则允许对象等距,但最左侧的对象或最右侧的对象都不会与父元素的边缘对齐。这可以通过对最左侧单元格应用左对齐,对最右侧单元格应用右对齐来解决——但这会导致对象不再等距。回到绘图板。

成功:Flexbox 对齐

我于 2015 年 6 月(7 年后!)添加了此内容,因为它是最佳解决方案(如果您能够使用 Flexbox)。
<div class="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>​
.container {
  display: flex;
  justify-content: space-between;
}

查看 Chris Coyier 在 CodePen 上的笔 等距对象@chriscoyier)。

成功:第一个在左侧,其余的在右侧以相等大小的盒子浮动

幸运的是,表格的想法引发了一些思考。第一个图像需要左对齐,但其余所有图像都可以右对齐。事实上,如果它们是右对齐的,并且还在均匀分割其余空间的盒子内,那可能就可以了。也许用视觉方式解释这一点最好。

floatytechnqiue.png

HTML

<img src="images/shape-red.png">
<div id="movers-row">
	<div><img src="images/shape-green.png"></div>
	<div><img src="images/shape-yellow.png"></div>
	<div><img src="images/shape-blue.png"></div>
</div>

CSS

#movers-row {
	margin: -120px 0 0 120px;
}
#movers-row div {
	width: 33.3%;
	float: left;
}
#movers-row div img {
	float: right;
}

有一个 示例页面,我在那里进行这项工作。它不太漂亮……但您可以在底部看到获胜者。我相信你们中的一些人对此有一些更好的解决方案,所以请告诉我!

成功:使用内联块和两端对齐文本

这可以通过将元素设置为display: inline-block;并将父元素设置为text-align: justify;来完成。好吧,它稍微复杂一些,我称之为真正的 CSS 技巧。您添加一个额外的元素(通过伪元素),该元素宽度为 100%,并且之前的内联块将对齐。

<div id="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>​
#container {
  height: 125px;
  text-align: justify;
  border: 10px solid black;
  font-size: 0.1px; /* IE 9/10 don't like font-size: 0; */
  min-width: 600px;
}
#container div {
  width: 150px;
  height: 125px;
  display: inline-block;
  background: red;
}
#container:after {
  content: '';
  width: 100%; /* Ensures there are at least 2 lines of text, so justification works */
  display: inline-block;
}

演示

Check out this Pen!