CSS咨询:如何用单个元素实现两层颜色叠加的月亮效果?
用单个div实现叠加月亮效果的方案
嘿,这个需求很实用,咱们来一步步优化你的代码,同时实现用单个div达到相同效果的目标~
先说说原代码的小优化点
你的代码整体结构已经很清晰了,但有几个小细节可以更规范:
opacity: 60%虽然浏览器能识别,但CSS标准里更推荐使用0到1的小数(比如opacity: 0.6),兼容性和规范性更好;- 两个月亮元素的定位、尺寸、圆角完全一致,你已经通过
.moon类统一设置了,这点做得很棒!不需要额外重复写这些属性; #sky设置了z-index: -100,如果页面后续添加其他元素,可能需要注意z-index的层级关系,避免意外遮挡。
方案1:伪元素实现(单个div,逻辑和原代码一致)
这种方法不需要修改HTML结构太多,只保留一个月亮div,用::before伪元素模拟上层的金色纹理层,完全还原你原来的叠加效果:
修改后的HTML
<div id="sky"> <div id="moon" class="moon"></div> </div> <div id="sea"></div>
修改后的CSS
* { padding: 0; margin: 0; border: 0; box-sizing: border-box; } /* ~~~~~~~~~~SKY~~~~~~~~~~ */ #sky { position: relative; z-index: -100; width: 100vw; height: 100vh; background-image: linear-gradient( to top, midnightblue, black); } /* ~~~~~~~~~~MOON~~~~~~~~~~ */ .moon { position: absolute; top: 3%; right: 0%; width: 200px; height: 200px; border-radius: 50%; background-color: silver; /* 底层银色月亮 */ } #moon::before { content: ''; position: absolute; inset: 0; /* 自动覆盖父元素的全部区域,等价于top/right/bottom/left:0 */ border-radius: inherit; /* 继承父元素的圆角,保证是圆形 */ background-color: goldenrod; background-image: radial-gradient(dimgrey 20%, transparent 16%), radial-gradient(dimgrey 15%, transparent 16%); background-size: 60px 60px; background-position: 0 0, 30px 30px; opacity: 0.6; /* 对应原效果的60%透明度 */ } /* ~~~~~~~~~~SEA~~~~~~~~~~ */ #sea { position: absolute; bottom: 0%; width: 100vw; height: 25vh; background-color: #48B; }
方案2:纯背景叠加(无伪元素,单个div)
如果不想用伪元素,可以利用CSS的多重背景和颜色混合,直接在一个div的background属性里实现叠加效果:
.moon { position: absolute; top: 3%; right: 0%; width: 200px; height: 200px; border-radius: 50%; /* 从下到上的背景层:银色底 → 60%透明度的金色 → 两层网点纹理 */ background: radial-gradient(dimgrey 20%, transparent 16%), radial-gradient(dimgrey 15%, transparent 16%), rgba(goldenrod, 0.6), silver; background-size: 60px 60px; background-position: 0 0, 30px 30px, 0 0, 0 0; /* 保持纹理的正常显示,金色层和银色底用multiply混合模拟叠加效果 */ background-blend-mode: normal, normal, multiply, normal; }
额外思路:直接使用混合后的单一颜色
如果你能提前算出两种颜色叠加后的最终颜色,也可以直接用这个单一颜色作为背景,再加上网点纹理。不过因为金色是带透明度的,叠加后的颜色会和底层银色有关,你可以用CSS的color-mix()函数(现代浏览器支持):
.moon { position: absolute; top: 3%; right: 0%; width: 200px; height: 200px; border-radius: 50%; /* 直接混合银色和60%透明度的金色 */ background-color: color-mix(in srgb, silver, goldenrod 60%); background-image: radial-gradient(dimgrey 20%, transparent 16%), radial-gradient(dimgrey 15%, transparent 16%); background-size: 60px 60px; background-position: 0 0, 30px 30px; }
这个方法最简洁,但要注意color-mix()是CSS Color Module Level 5的特性,现代浏览器(Chrome 111+、Firefox 113+)都支持,如果需要兼容旧浏览器,还是用前两种方案更稳妥。
内容的提问来源于stack exchange,提问作者anotherOne
相关产品推荐
相关产品推荐

