2017-04-01
FE
3px
当你信心满满的打出 三个 inline-block 的 img 标签,并让他们宽度为 33.3% 的时候,以为他们应该能占满父元素,并置于同一行。(33.3% * 3 = 99.9% ≈ 100%)
00.img-container {
01    position: relative;
02    text-align: center;
03}
04.img-children {
05    display: inline-block;
06    width: 33.3%; 
07}
00<div class="img-container">
01    <img src="img/00.jpg" alt="00.jpg" />
02    <img src="img/01.jpg" alt="01.jpg" />
03    <img src="img/11.jpg" alt="11.jpg" />
04</div>
而事实你会看到割裂,只有前两个 img 在同一行,最后一个 img 却换行到下一行了 ———— 就好像 img 的宽度不是真正的 33.3% 一样
与实际期望不符
与实际期望不符

# 原因

我曾经因为这个debug花了很多时间,我不知道问题在哪,最后我采取折中的办法,让那个img的宽度为 30% 这样就能在一行了。
这件事之后我曾怀疑过我对 CSS width 的理解是不是出现根源性的错误。
然后有件很滑稽的事情让我明白了这个错误的根源:
有一天我又遇到这种情况,当时突然就想起来 “哦哦 确实是不能33.3%”,我马上让子元素为 30% 来完成让元素都在同一行,然而随后我不经意的鼠标文本选择,瞬间让我肾上腺爆炸:
这中间的空格是哪儿来的?
这中间的空格是哪儿来的?
问题的根源在于浏览器对html的处理,他会把回车和tab缩进解析为 node-type 为 3 的 dom节点 换句话说就是 空格,而这个空格的宽度大概是 3px 因此这个问题被称为 3px问题。

# 最佳解决

因为是多出来的空格,给 .img-container 一个 font-size: 0; 就可以了。
00.img-container-fixed {
01    position: relative;
02    text-align: center;
03    font-size: 0; 
04}
05
06.img-container-fixed > * {
07    font-size: 1rem; 
08}
这段代码很好的解决了这个问题,也可以得到期望的画面了。此外我还额外写多了一个 .img-container-fixed > * 选择器来避免子元素 font-size 的继承问题。 (没有的话,子元素的 font-size 都会继承为0)

# 其他方法

  1. 把回车及tab去掉,把全部写进一行。
    显然 这样不利于编码,更别说维护了。
    00<div class="img-container"><span class="green">在同一行</span><span class="red">在同一行</span><span class="blue">在同一行</span>
  2. 给元素添加 margin-left: -3px;
    不一定所有浏览器的一个空格都是3px,这样做兼容性有比较大的问题
  3. 让宽度为33%而不是33.3%。这是一个折中的方案。
以上方法个人认为都不如 font-size: 0; 简单易行,完全消除空格的影响。

# inpage-demo

在同一行 在同一行 不在同一行
在同一行 在同一行 在同一行




回到顶部