为何margin与padding相差1px会导致按钮hover时移位?
问题原因
这个偏移的核心逻辑非常直接:按钮默认是inline-block类型元素,它在文档流里占据的水平总宽度为「文字内容宽度 + 左右padding + 左右margin + 左右边框宽度」,只要hover前后这个总宽度保持恒定,周围的按钮就不会出现任何位移。
你觉得两边代码只差1px,是单看每个padding、margin属性的取值差,实际上四个水平方向的属性(padding-left、padding-right、margin-left、margin-right)每个都差1px,总宽度差被放大到了4px,足以产生非常明显的移位。
数值验证
我们可以直接算两边代码hover前后的水平占位(两边都设了border:none,边框宽度为0,文字内容不变所以内容宽度固定,只需要算padding和margin的和即可):
讲师的代码
- 普通状态:
15px(左padding) + 15px(右padding) + 10px(左margin) + 10px(右margin) = 50px - hover状态:
25px(左padding) + 25px(右padding) + 0(左margin) + 0(右margin) = 50px
两个状态下总占位宽度完全相等,当前按钮hover时不会挤占或者释放多余空间,旁边的按钮位置自然纹丝不动。
你的代码
- 普通状态:
16px(左padding) + 16px(右padding) + 11px(左margin) + 11px(右margin) = 54px - hover状态:
25px(左padding) + 25px(右padding) + 0(左margin) + 0(右margin) = 50px
两个状态总宽度差了4px,相当于hover时当前按钮会突然收缩4px的宽度,周围的按钮会顺着文档流补位,再加上过渡动画的效果,位移感会非常明显。
修正方法
你不需要额外加容器,只要保证普通状态下「左右padding之和 + 左右margin之和」等于hover状态的对应总和即可。你现在hover状态左右padding总和是50px、margin为0,总和固定为50px,只要调整普通状态的padding/margin取值凑够50px就行,比如保留11px的左右margin,把左右padding改成14px,就能实现和讲师代码一样的无偏移效果。
注:inline-block元素的水平margin不会发生块级元素那样的外边距折叠,所以左右margin都是全额计入元素占位宽度的,计算的时候不要漏加。
内容的提问来源于stack exchange,提问作者eraafay
相关产品推荐
相关产品推荐

