Search code examples
csscolorstransparencybackground-coloralpha-transparency

Calculate RGB value at 50% opacity on a white background to match RGB value at 100% opacity


I'm embedding some Facebook posts in a blog. I made a nice wrapper for my iframe styled with the same background color that Facebook uses: rgb(240, 242, 245).

Now I want to embed an iframe in a div that has its own background color: #f2f0fc. The gray on light purple is jarring. Instead of using Facebook's gray, I'd like to darken my div by the same amount that Facebook's gray darkens white.

Originally I had thought that I could just cut each of Facebook's color components in half and apply a 0.5 opacity, but this clearly is not right.

Edit: My second thought was that because I'm cutting three components in half, it's actually a cubic operation, and thus I must set my opacity to 0.5^3 = 0.125. This is much closer, but still a little off.

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 1rem;
}

.facebook-wrapper {
  display: flex;
  background-color: rgb(240, 242, 245);
  padding: 1rem;
}
  .facebook-wrapper.transparent {
    background-color: rgba(120, 121, 122, 0.5);
  }
  
  .facebook-wrapper.transparent-2 {
    background-color: rgba(120, 121, 122, 0.125);
  }
  
  .facebook-wrapper > .post {
    max-width: 680px;
    width: 100% !important;
    margin-left: auto;
    margin-right: auto;
    background-color: white;
    padding: 0.5rem 1rem;
  }

.white {
  padding: 1rem 0;
  background-color: white;
  border: 1px solid gray;
}

.alert {
  background-color: #f2f0fc;
  padding: 1rem 0;
}
<div class="grid">
  <h2>Opaque</h2><h2>50% transparent</h2><h2>12.5% transparent</h2>
  <div class="white">
    <div class="facebook-wrapper">
      <div class="post">Facebook post!</div>
    </div>
  </div>
  <div class="white">
    <div class="facebook-wrapper transparent">
      <div class="post">Facebook post!</div>
    </div>
  </div>
    <div class="white">
    <div class="facebook-wrapper transparent-2">
      <div class="post">Facebook post!</div>
    </div>
  </div>
  <div class="alert">
    <div class="facebook-wrapper">
      <div class="post">Facebook post!</div>
    </div>
  </div>
  <div class="alert">
    <div class="facebook-wrapper transparent">
      <div class="post">Facebook post!</div>
    </div>
  </div>
    <div class="alert">
    <div class="facebook-wrapper transparent-2">
      <div class="post">Facebook post!</div>
    </div>
  </div>
</div>

How can I calculate the proper component values or the proper opacity values? In the above rendered snippet, the goal is to get a color/opacity combination that matches the top-left box, but which can be applied to shade the bottom boxes' background color.


Solution

  • Per Termani's comment, this answer gives us the formula:

    ColorF = (ColorT*opacityT + ColorB*OpacityB*(1 - OpacityT)) / factor
    

    ColorF is our final color. ColorT/ColorB are respectively the top and bottom colors. opacityT/opacityB are respectively the top and bottom opacities defined for each color:

    The factor is defined by this formula OpacityT + OpacityB*(1 - OpacityT).

    OpacityB in this case is 1 and ColorB is rgb(255, 255, 255).

    Plug the desired values into the equation and we get:

    rgb(240, 242, 245) = (ColorT * 0.5 + rgb(255, 255, 255) * 1 * (1 - 0.5)) / (0.5 + 1 * (1 - 0.5))
    rgb(240, 242, 245) = (ColorT * 0.5 + rgb(255, 255, 255) * 0.5) / 1
    rgb(240, 242, 245) = ColorT * 0.5 + rgb(255, 255, 255) * 0.5
    rgb(240, 242, 245) / 0.5 = ColorT + rgb(255, 255, 255)
    2 * rgb(240, 242, 245) - rgb(255, 255, 255) = ColorT
    rgb(480 - 255, 484 - 255, 490 - 255) = ColorT
    rgb(225, 229, 235) = ColorT
    

    .grid {
      display: grid;
      grid-template-columns: 1fr 1fr;
      grid-gap: 1rem;
    }
    
    .facebook-wrapper {
      display: flex;
      background-color: rgb(240, 242, 245);
      padding: 1rem;
    }
      .facebook-wrapper.transparent {
        background-color: rgba(225, 229, 235, 0.5);
      }
        
      .facebook-wrapper > .post {
        max-width: 680px;
        width: 100% !important;
        margin-left: auto;
        margin-right: auto;
        background-color: white;
        padding: 0.5rem 1rem;
      }
    
    .white {
      padding: 1rem 0;
      background-color: white;
      border: 1px solid gray;
    }
    
    .alert {
      background-color: #f2f0fc;
      padding: 1rem 0;
    }
    <div class="grid">
      <h2>Opaque</h2><h2>50% transparent adjusted</h2>
      <div class="white">
        <div class="facebook-wrapper">
          <div class="post">Facebook post!</div>
        </div>
      </div>
      <div class="white">
        <div class="facebook-wrapper transparent">
          <div class="post">Facebook post!</div>
        </div>
      </div>
      <div class="alert">
        <div class="facebook-wrapper">
          <div class="post">Facebook post!</div>
        </div>
      </div>
      <div class="alert">
        <div class="facebook-wrapper transparent">
          <div class="post">Facebook post!</div>
        </div>
      </div>
    </div>