Mixing two colors for a background in CSS

Viewed 5260

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?

3 Answers

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;
}

Another option that only involves setting one background property would be to "stretch and displace" a linear-gradient in such a way that the result is a single color.

--base-col and --blend-col defines the gradient, --blend-amount sets the color mix, and --stretch-factor determines how much stretch is applied to the gradient:

* {
  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 {
  --blend-amount: 60%;
  --base-col: silver;
  --blend-col: goldenrod;
  --stretch-factor: 100;
  background: linear-gradient(
    var(--base-col)  calc((  0% - var(--blend-amount)) * var(--stretch-factor)), 
    var(--blend-col) calc((100% - var(--blend-amount)) * var(--stretch-factor))
  );
}

#light-moon {
  background-image: radial-gradient(dimgrey 20%, transparent 16%), radial-gradient(dimgrey 15%, transparent 16%);
  background-size: 60px 60px;
  background-position: 0 0, 30px 30px;
}


/* ~~~~~~~~~~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>

You can try to get the hex code for the mixed color first using online color mixer tool such as this one https://colordesigner.io/color-mixer. After that you can use the result color in one div.

Related