Search code examples
cssopacitypseudo-elementoverlapping

How to remove double opacity caused by use of pseudo elements


I am using pseudo elements to dynamically draw segments of circles. My problem is now that I want to use opacity of 0.7 but when the elements are overlapping the opacity is higher. What can I do to have the same opacity for the overlapping parts? Is there a way to style them?

I am using styled components but the static version looks like this:

.circle {
  background-color: #d6dadc;
  width: 400px;
  height: 400px;
  overflow: hidden;
  border-radius: 50%;
  position: relative;
}

.circle_segment {
  height: 100%;
  width: 100%;
  position: absolute;
  overflow: undefined;
  background-color: rgba(75, 0, 250, 0.7);
  transform-origin: 50% 100%;
  transform: translate(-100%, -50%) rotate(90deg);
}

.circle_segment:before {
  height: 100%;
  content: " ";
  width: 100%;
  position: absolute;
  background-color: rgba(75, 0, 250, 0.7);
  transform-origin: center bottom;
  transform: translate(0%, -100%) rotate(-90deg)
}

.circle_segment:after {
  height: 100%;
  width: 100%;
  background-color: rgba(75, 0, 250, 0.7);
  content: " ";
  position: absolute;
  opacity: 1;
}
<!DOCTYPE html>
<html>

<head>
</head>

<body>
  <div class="circle">
    <div class="circle_segment" />
  </div>
</body>

If someone had an idea, I would be happy to know. Thank you in advance.


Solution

  • Ok, I see the problem now. If you don't want specific elements to be partially opaque between them but want to be partially opaque with the rest, I recommend to add all those elements inside another element and use the opacity CSS property. Because :before and :after pseudo-elements are already inside its "parent" element, you can simply modify the parent opacity, like so:

    .circle {
      background-color: #d6dadc;
      width: 400px;
      height: 400px;
      overflow: hidden;
      border-radius: 50%;
      position: relative;
    }
    
    .circle_segment {
      height: 100%;
      width: 100%;
      position: absolute;
      top: 0;
      left: 0;
      overflow: undefined;
      opacity: 0.7;
      background-color: rgb(75, 0, 250);
      transform-origin: 50% 100%;
      transform: translate(-100%, -50%) rotate(90deg);
    }
    
    .circle_segment:before {
      height: 100%;
      content: " ";
      width: 100%;
      position: absolute;
      background-color: rgb(75, 0, 250);
      transform-origin: center bottom;
      transform: translate(0%, -100%) rotate(-90deg)
    }
    
    .circle_segment:after {
      height: 100%;
      width: 100%;
      background-color: rgb(75, 0, 250);
      content: " ";
      position: absolute;
    }
    .wildelement {
      position: absolute;
      left: 0px;
      top: 190px;
      height: 20px;
      width: 450px;
      background-color: red;
    }
    <!DOCTYPE html>
    <html>
    
    <head>
    </head>
    
    <body>
      <div class="circle">
        <div class="wildelement"></div>
        <div class="circle_segment" />
      </div>
    </body>