skip to Main Content

I’ve created a custom progress bar component in React that uses a gradient background. To achieve this effect, I’m using the CSS mask property. The progress bar works perfectly in Firefox, but I’m encountering an issue in Chrome.

The mask doesn’t seem to apply correctly on Chrome until I force a rerender by resizing the browser or unchecking and checking the mask property again.

The problem does not happen here in stack overflow, only on the code sandbox:

https://codesandbox.io/s/progress-bar-7czghg

    function increaseWidthUntil100Percent(element, currentWidth = 0) {
      if (currentWidth < 100) {
        const newWidth = currentWidth + 5;
        element.style.width = `${newWidth}%`;

        setTimeout(() => {
          increaseWidthUntil100Percent(element, newWidth);
        }, 1000);
      }
    }

    const myDiv = document.getElementById('bar');
    increaseWidthUntil100Percent(myDiv);
.progress-bar {
  height: 0.5rem;
  border-radius: 3rem;
  background-color: #c0c6df;
  padding: 0.25rem;
  width: 100%;
  position: relative;
}

.progress-bar > .progress-bar__bar::before {
  content: "";
  border-radius: 3rem;
  background: linear-gradient(
    90deg,
    rgba(209, 107, 165, 1) 0%,
    rgba(132, 166, 228, 1) 50%,
    rgba(1, 22, 42, 1) 100%
  );
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

.progress-bar > .progress-bar__bar {
  height: 100%;
  border-radius: 3rem;
  -webkit-mask: linear-gradient(#fff 0 0);
  mask: linear-gradient(#fff 0 0);
  transition: 0.3s ease;
}
<div class="progress-bar">
  <div id="bar" style="width: 0" class="progress-bar__bar"></div>
</div>

Thank you for your help!

2

Answers


  1. Adding

    {
      position: relative;
      z-index: 1;
    }
    

    to .progress-bar__bar should do the trick. No idea why it works after you resize the window. I would have thought it shouldn’t.

    Login or Signup to reply.
  2. Not sure if it will solve your issue but here is a different idea using clip-path and CSS variables

    function increaseWidthUntil100Percent(element, currentWidth = 0) {
          if (currentWidth < 100) {
            const newWidth = currentWidth + 5;
            element.style.setProperty('--w',`${newWidth}%`);
    
            setTimeout(() => {
              increaseWidthUntil100Percent(element, newWidth);
            }, 1000);
          }
        }
    
        const myDiv = document.getElementById('bar');
        increaseWidthUntil100Percent(myDiv);
    .progress-bar {
      height: 0.5rem;
      border-radius: 3rem;
      background-color: #c0c6df;
      padding: 0.25rem;
      display: grid;
    }
    
    .progress-bar > .progress-bar__bar {
      background: linear-gradient(
        90deg,
        rgba(209, 107, 165, 1) 0%,
        rgba(132, 166, 228, 1) 50%,
        rgba(1, 22, 42, 1) 100%
      );
      transition: 0.3s ease;
      clip-path:inset(0 calc(100% - var(--w,0%)) 0 0 round 3rem);
    }
    <div class="progress-bar">
      <div id="bar" class="progress-bar__bar"></div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search