元素移动的奇怪现象
假设你有一个包含红色背景的 main
元素,其中嵌套了一个 avatar
图片。你通过设置 margin-top
为负值试着将 main
元素向上移动。但是你发现,虽然 avatar
图片确实向上移动了,但红色背景却没有移动。这是什么原因呢?
可替换元素
首先,我们需要理解“可替换元素”是什么。可替换元素(如图片、输入框)不同于普通元素。它们的显示内容是由其属性决定的,而不是由其内部内容控制的。例如,<img>
标签的内容由 src
属性决定,而不是标签内的内容。这些元素的绘制可以分为两个部分:
- 元素本身:包括边框、外边距等。
- 元素内容:如图片的实际显示部分。
例如,当你给 bg-top
图片添加边框时,边框实际上是加在图片元素本身的,而不是图片的内容上。图片内容的显示不会因边框的添加而改变,只是元素本身的绘制区域扩大了。
堆叠上下文
另一个相关的概念是“堆叠上下文”。想象一下网页就像一幅油画。画师先涂上一层油漆,这层油漆包含了一些元素。然后他再涂上另一层油漆,新的层次中也包含一些元素。这些层次是分开的,每一层都在不同的“上下文”中绘制。
- 背景颜色:属于一个绘制层。
- 边框:属于另一个绘制层。
- …
当你使用 margin-top
移动 main
元素时,它的背景和内容分属于不同的层次。图片和背景颜色的移动不总是同步的,因为它们在不同的绘制层上。
解决方案
给 main 元素设置一个 position: relative
,或者 transform
创建一个单独的堆叠上下文。这样在绘制的时候,就先绘制盒子再绘制内容。再次设置 margin-top 时,main 元素背景颜色也会跟随着变化。