How to fix clipped text disappearing in Firefox?

Tags: , ,



I have made a program where it alternates a word, after a short duration.

I am using background-clip to add a gradient to the text. This program works fine on Chrome, but breaks in Firefox. The Text disappears after coming into view.
I checked that the text is still there, since it is selectable, but is fully transparent.

function rotate() {
  let show = document.querySelector(".mask span[data-show]");
  let next =
    show.nextElementSibling || document.querySelector("span:first-child");
  let up = document.querySelector(".mask span[data-up]");

  if (up) {
    up.removeAttribute("data-up");
  }

  show.removeAttribute("data-show");
  show.setAttribute("data-up", "");

  next.setAttribute("data-show", "");
}

setInterval(rotate, 2000);
body {
  display: flex;
  height: 100vh;
  justify-content: center;
  align-items: center;
}

h2 {
  width: 100vw;
  color: #1D1D1F;
  font-size: 6.25rem;
  line-height: 1.06em;
  font-family: Arial, Helvetica, sans-serif;
  letter-spacing: -0.02em;
}

.mask {
  height: 21vh;
  overflow: hidden;
  position: relative;
  margin-top: 6px;
}

.mask span {
  display: block;
  box-sizing: border-box;
  position: absolute;
  top: 100px;
  padding-bottom: 6px;
  background-size: 100% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  background-repeat: no-repeat;
}

.mask span[data-show] {
  transform: translateY(-100%);
  transition: transform 0.5s ease-in-out;
}

.mask span[data-up] {
  transform: translateY(-200%);
  transition: transform 0.5s ease-in-out;
}

.mask span:nth-child(1) {
  background-image: linear-gradient(45deg, #0ECFFE 50%, #0AB5F6);
}

.mask span:nth-child(2) {
  background-image: linear-gradient(45deg, #18E198 50%, #13D17B);
}

.mask span:nth-child(3) {
  background-image: linear-gradient(45deg, #8A7CFB 50%, #7256C1);
}

.mask span:nth-child(4) {
  background-image: linear-gradient(45deg, #FA7671 50%, #F6677A);
}
<body>
  <h2>
    Turn your living room into
    <div class="mask">
      <span data-show>a theater.</span>
      <span>a gym.</span>
      <span>a concert hall.</span>
      <span>an arcade.</span>
    </div>
  </h2>
</body>

Fiddle Link – https://jsfiddle.net/TechySharnav/w089ucza/ (Run in Maximized Window)

How do I fix this issue? Is there any fallback that I can implement?

Any help is greatly appreciated.

Answer

I fiddled around a bit with your code and this is what I came up with. I don’t know really, why this works and your code doesn’t, because your code looked fine to me (except for the height: 21vh of the .mask with seems to be a magic value that is based on your screen size).

What I did is, that I made calculations based on font-size of the h2. Also I thought it would be better, if the translation of the [data-show] element should be zero and not -100%. So I based every translation off of that assumption.

function rotate() {
  let show = document.querySelector(".mask span[data-show]");
  let next =
    show.nextElementSibling || document.querySelector("span:first-child");
  let up = document.querySelector(".mask span[data-up]");

  if (up) {
    up.removeAttribute("data-up");
  }

  show.removeAttribute("data-show");
  show.setAttribute("data-up", "");

  next.setAttribute("data-show", "");
}

setInterval(rotate, 2000);
body {
  display: flex;
  height: 100vh;
  justify-content: center;
  align-items: center;
}

h2 {
  width: 100vw;
  color: #1D1D1F;
  font-size: 6.25rem;
  line-height: 1.06em;
  font-family: Arial, Helvetica, sans-serif;
  letter-spacing: -0.02em;
}

.mask {
  height: 1.2em;
  overflow: hidden;
  position: relative;
  /*margin-top: 6px;*/
}

.mask span {
  display: block;
  box-sizing: border-box;
  position: absolute;
  top: 0;
  transform: translateY(1.2em);
  padding-bottom: 6px;
  background-size: 100% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  background-repeat: no-repeat;
  
  white-space: nowrap;
}

.mask span[data-show] {
  transform: translateY(0);
  transition: transform 0.5s ease-in-out;
}

.mask span[data-up] {
  transform: translateY(-1.2em);
  transition: transform 0.5s ease-in-out;
}

.mask span:nth-child(1) {
  background-image: linear-gradient(45deg, #0ECFFE 50%, #0AB5F6);
}

.mask span:nth-child(2) {
  background-image: linear-gradient(45deg, #18E198 50%, #13D17B);
}

.mask span:nth-child(3) {
  background-image: linear-gradient(45deg, #8A7CFB 50%, #7256C1);
}

.mask span:nth-child(4) {
  background-image: linear-gradient(45deg, #FA7671 50%, #F6677A);
}
<body>
  <h2>
    Turn your living room into
    <div class="mask">
      <span data-show>a theater.</span>
      <span>a gym.</span>
      <span>a concert hall.</span>
      <span>an arcade.</span>
    </div>
  </h2>
</body>


Source: stackoverflow