这几天由于某项任务,暂时转型了成为了前端码农(实际上就是个写初级CSS的屌丝)。在这期间,我有一个需求大致是这样的:
我有一个父类容器,比如div,这个div的宽度是固定的。我现在要在这个div中插入5个img,这5个img等宽。同时伴随这5个img的当然还有四个间隙,这四个间隙也是等宽的。
当然,需要根据百分比宽度进行简单适配。
是不是觉得很简单呢?呵呵,别说专业的前端工程师,我这种半吊子都觉得简单。
根据PSD效果图,我量出了对应的百分比尺寸,于是写出来如下的HTML和CSS代码:
// HTML 文件
<div class="parent">
<img class="element" src="http://xxxxxxx.com/shshshshs.png" />
<img class="element" src="http://xxxxxxx.com/shshshshs.png" />
<img class="element" src="http://xxxxxxx.com/shshshshs.png" />
<img class="element" src="http://xxxxxxx.com/shshshshs.png" />
<img class="element" src="http://xxxxxxx.com/shshshshs.png" />
</div>
// css 文件
.parent {
width:x%;
}
.parent img {
width:y%;
height:auto;
margin-left:k%;
}
.parent img:first-child {
margin-left:0;
}
这段代码相当简洁明了吧,我通过量好的百分比,对各个图片和之间的间距进行了控制,基本上业界大多数也是这么做的吧。
按理说事情到这基本就结束了,毕竟img是个行内可替换元素,会自动布局在一行之内,当然前提是父容器宽度足够的前提下。不过既然我都身体力行的量过了,那自然不应该出现问题。
但是,卧槽,你越担心的事就越会发生。整个界面出现了非常奇葩的现象:
这是正常情况:
[图<->图<->图<->图<->图]
这是实际情况:
[图<->图<->图<->图<->]
图]
卧槽,竟然宽度不够,换行了。尝试了很长时间,后来发现,将.parent img
中添加float:left
就可以完美解决,但这什么原因呢?
原因
经过一番探索研究,我发现,这是由于空白符对inline类型的元素造成的影响。
- 首先,img元素是一种行内可替代元素,效果基本可以理解为inline-block。
第二,我们在HTML的时候,为了在编辑器内写的美观,常常会使用回车,而回车在HTML中会被识别为空白符。
比如 <img src = "xxxx" />(空白符) <img src = "xxxx" />
第三,空白符具备宽度(和font-size有关),不具备高度。
所以,表面上我们根据设计好的图片进行了精准的测量,构造了完全匹配父类宽度的元素和间距,但是实际上却由于空白符所具备的宽度而产生了偏差。
用一张图来表示拥有空白符后的效果:
[图(空白)<->图(空白)<->图(空白)<->
图<->]
为什么float可以解决这个问题
A floated box is shifted to the left or right until its outer edge touches the containing block edge or the outer edge of another float
看到这个关于float的定义了吗?float要么依赖前一个(或者后一个)float元素的边界,要么就依赖于父元素的边界。而一个空白符,既不是包含块(父容器)的边界,也不是另一个float元素,因此不受影响,也不会对其余float元素有影响。
所以,当你对.parent img
启用float:left
之后,效果就成了下图所示:
[float<->float<->float<->float<->float]
[空白符]
这次我们测量的宽度正好匹配完全,所以将空白符自然而然的挤到了下一行。还记得我们前面说过空白符不具备高度吗?因此,这个空白符压根没起作用!
文中的 [] 代表父容器,<-> 代表间隔。
其余方案
- 将父容器的
font-size
设置为0。 - 避免换行,写出 这样的代码。
- 启用HTML压缩。
最后:感谢美团大神FTR和淘宝大神YWJ对本菜比的指导。