You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:46:39