Search code examples
htmlcssbackground-image

Mixing two colors for a background in CSS


I want to stack two colors one on top of the other. I did it by creating and sovrapposing two divs, having the one on the top with an opacity of 60%. I wonder if there's a simpler way requiring only one div with two colors or maybe just one color that is a mix of the two.

I post here my code, If you notice any bad practice let me know please. I am eager to improve my skills.

* {
  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%;
}

#dark-moon {
  background-color: silver;
}

#light-moon {
  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: 60%;
}


/* ~~~~~~~~~~SEA~~~~~~~~~~ */

#sea {
  position: absolute;
  bottom: 0%;
  width: 100vw;
  height: 25vh;
  background-color: #48B;
}
<div id="sky">
  <div id="dark-moon" class="moon"></div>
  <div id="light-moon" class="moon"></div>
</div>

<div id="sea"></div>

As you can see there's a golden moon over a silver one. How can I get the same result having only one moon?


Solution

  • You can do it with 0 elements using pseudo element and multiple backgrounds:

    html {
      min-height: 100%;
      background: linear-gradient( to top, midnightblue, black);
    }
    
    html::before {
      content:"";   
      position: absolute;
      top: 3%;
      right: 0;
      width: 200px;
      height: 200px;
      border-radius: 50%;
      background: 
        linear-gradient(rgba(192,192,192,0.4) 0 0),
        radial-gradient(dimgrey 20%, transparent 16%), 
        radial-gradient(dimgrey 15%, transparent 16%) 30px 30px,
        goldenrod;
      background-size: 60px 60px;
    }
    
    html::after {
      content:"";
      position: absolute;
      bottom: 0;
      left:0;
      right:0;
      height: 25vh;
      background: #48B;
    }

    Another fancy idea to optimize the code more:

    html {
      min-height: 100%;
      background: 
       linear-gradient(#48B 0 0) bottom/100% 25vh no-repeat fixed,
       linear-gradient(black,midnightblue);
    }
    
    html::before {
      content:"";   
      position: absolute;
      top: 3%;
      right: 0;
      width: 200px;
      height: 200px;
      border-radius: 50%;
      background: 
        linear-gradient(#48B 0 0) bottom/100% 25vh no-repeat fixed,
        linear-gradient(rgba(192,192,192,0.4) 0 0),
        radial-gradient(dimgrey 20%, transparent 16%) 0    0   /60px 60px, 
        radial-gradient(dimgrey 15%, transparent 16%) 30px 30px/60px 60px,
        goldenrod;
    }