伪元素背景无法覆盖可滚动内容且background-attachment:fixed变形如何解决
问题1 滚动时露出白色背景修复方案
问题原因
当前伪元素使用position: absolute定位,是相对于设置了position: relative的父div可视区域定位,尺寸默认匹配父div的可视宽高,不会跟随内部滚动内容的总高度拉伸,滚动时就会露出未被伪元素覆盖的区域。
修复代码
无需修改HTML结构,仅调整SCSS即可,背景图仍保留在伪元素中:
@mixin pseudo-element-background { content: ""; background-size: cover; background-position: top; // background-attachment: fixed; // 暂不启用,后面问题2会说明修改方式 position: sticky; top: 0; right: 0; left: 0; min-height: 100%; display: block; z-index: -1; } div { width: 20rem; max-height: 10rem; overflow-y: auto; &::before { background-image: url(http://www.freegreatpicture.com/files/147/18380-hd-color-background-wallpaper.jpg); @include pseudo-element-background; margin-bottom: -100%; } }
修改逻辑为移除父div的position: relative属性,将伪元素改为sticky定位,使其自动撑满整个滚动内容的高度,配合负margin让内容覆盖在伪元素上方,滚动时不会露出白边。
问题2 background-attachment: fixed导致背景变形的原因与修复
产生原因
background-attachment: fixed的规则是让背景图相对于整个浏览器视口定位,而非元素本身。搭配background-size: cover时,背景图会先拉伸铺满整个浏览器视口,再裁剪出和div元素重叠的区域显示,你看到的变形本质是大图被裁剪后的局部区域,不符合你预期的铺满div的效果。
修复方案
如果要实现背景相对于div固定、不跟随内容滚动的效果,不需要用fixed,改用background-attachment: local即可,它会让背景相对于元素的滚动内容固定,不会触发相对于视口的拉伸变形:
@mixin pseudo-element-background { content: ""; background-size: cover; background-position: top; background-attachment: local; /* 替换原来的fixed */ position: sticky; top: 0; right: 0; left: 0; min-height: 100%; display: block; z-index: -1; }
如果确实需要和视口绑定的fixed效果,又不想变形,可以固定背景图宽度和div宽度一致,避免拉伸:
@mixin pseudo-element-background { content: ""; background-size: 20rem auto; /* 和div宽度保持一致 */ background-position: top left; /* 对齐div左上角 */ background-attachment: fixed; position: sticky; top: 0; right: 0; left: 0; min-height: 100%; display: block; z-index: -1; }
内容的提问来源于stack exchange,提问作者AlwaysLearning
相关产品推荐
相关产品推荐

