CSS:图片自带3px下边距的问题

有个朋友有这样一个需求,在一张图片上放置一个半透明的遮罩层,当鼠标悬停其上,减少遮罩的透明度,让图片显示更清晰,效果图如下(查看代码实例):


简化HTML如下:


<div class="item">
 
<img src="http://wx3.sinaimg.cn/mw600/007bk2ovgy1ftedeqwhntj30hs0plwko.jpg" />
 
<div class="mask">Mask Text</div>
 
</div>

CSS样式文件如下:


.item {
 
width: 200px;
 
margin: 100px auto;
 
position: relative;
 
overflow: hidden;
 
background: yellow;
 
}
 
.item img {
 
width: 100%;
 
max-width: 100%;
 
}
 
.mask {
 
position: absolute;
 
top: 0;
 
bottom: 0;
 
width: 100%;
 
width:50%;
 
padding-top: 49%;
 
color: #fff;
 
text-align: center;
 
background: rgba(0, 0, 0, 0.5);
 
background: red;
 
}
 
.mask:hover {
 
background: rgba(0, 0, 0, 0.1);
 
}
 

最终得到的效果为(查看错误示例):

为了让bug更为明显,将遮罩层的宽度设置成50%,背景颜色为red,无透明度,同时将包含块.item背景设置为黄色。效果如下:

可见,包含块的的高度与遮罩层等高,却比图片高度多出几像素。

分析

遮罩层已经设置了绝对定位,已经被移出正常的文档流,上下紧贴父元素,它的高度取决于父元素,并且无法影响父元素。

而作为父元素的.item只有一个子元素,就是图片。所以,影响父元素高度只能是图片元素。

为了测试图片元素,先把图片元素替换成段落文本,发现一切正常。所以,确定是图片影响了父元素的高度。

原因

因为图片是行内(inline)元素,而行内元素涉及到一个垂直方面对齐(vertical align)的问题。比如一行文字:

行内元素vertical-align默认值为:baseline。即默认情况下,会把图片当成sphinx单词中的字母s、n、x,会自动预留一定位置给p字母这样的元素。效果如下:

解决办法

  • 将图片属性值 vertical-align:middle或bottom
  • 将图片转化为块级(block)元素

参考资料

  • https://stackoverflow.com/questions/10844205/html-5-strange-img-always-adds-3px-margin-at-bottom
  • https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align