Unfortunately this is simply an artifact of how fixed positioning works in CSS and there is no way around it in pure CSS - you have to use Javascript.
The reason this happens is due to the combination of background-attachment: fixed
and background-size: cover
. When you specify background-attachment: fixed
it essentially causes the background-image
to behave as if it were a position: fixed
image, meaning that it's taken out of the page flow and positioning context and becomes relative to the viewport rather than the element it's the background image of.
So whenever you use these properties together, the cover
value is being calculated relative to the size of the viewport irrespective of the size of the element itself, which is why it works as expected when the element is the same size as the viewport but is cropped in unexpected ways when the element is smaller than the viewport.
To get around this you basically need to use background-attachment: scroll
and bind an event listener to the scroll
event in JS that manually updates the background-position
relative to how far the window has been scrolled in order to simulate fixed positioning but still calculate background-size: cover
relative to the container element rather than the viewport.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…