Home > Software design >  CSS Marquee With Fade In/Out Effect
CSS Marquee With Fade In/Out Effect

Time:01-25

I am trying to make a CSS marquee whose text fades in from the right edge and fades out on the left edge. Only the letters on the edges should turn transparent. I'd call it an "opacity mask" that is feathered onto the left/right edges.

I can find CSS marquee code samples but none with such a fade in/out effect. I'd also like the background to be completely transparent, with just the text having the edge effects.

I've tried adding a gradient to the container but, in hind sight, that doesn't seem to be the right path. Below is the code I've come up with thus far. Please assist, thanks!

@Bernard Borg: I've updated my code with the second new sample. Other than this not using opacity - and therefore being A) dependent on being hardcoded to the underlying background color and B) only working on a solid background - this is acceptable for my use case. Thanks! (Any idea how to cover the marquee with opacity rather than a color?)

div#container {
  width: 60%;
  height: 100%;
  position: absolute;
  background-color: #e6e9eb;
}

div#marquee-container {
  overflow: hidden;
}

p#marquee {
  animation: scroll-left 10s linear infinite;
}
            
@keyframes scroll-left {
  0%   {transform: translateX( 140%)}
  100% {transform: translateX(-140%)}
}

div#marquee-cover {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 40px;
  background: linear-gradient(to right, rgba(230, 233, 235, 1) 0%, rgba(230, 233, 235, 0) 15%, rgba(230, 233, 235, 0) 85%, rgba(230, 233, 235, 1) 100%);
}
<div id="container">
  <div id="marquee-container">
    <p id="marquee">The quick brown fox jumps over the lazy dog</p>
    <div id="marquee-cover"/> <!--thanks Bernard Borg-->
  </div>
</div>

CodePudding user response:

For anyone coming to this question in the future - the answer to this question was a joint effort. Find the answer in the question.

This is the closest I was able to get to your updated question;

body {
  margin: 0;
}

#container {
  width: 100%;
  height: 100vh;
  background-color: grey;
  display: flex;
  align-items: center;
}

#marquee-container {
  overflow: hidden;
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

p#marquee {
  font-family: 'Segoe UI', sans-serif;
  font-size: 30px;
  font-weight: bold;
  height: 80%;
  animation: scroll-left 5s linear infinite;
  white-space: nowrap;
}

#first-cover,
#second-cover {
  height: 100vw;
  backdrop-filter: opacity(50%);
  width: 30vw;
  z-index: 100;
}

#first-cover {
  background: linear-gradient(90deg, rgba(0, 0, 0, 0.8), rgba(128, 128, 128, 0.2));
}

#second-cover {
  background: linear-gradient(-90deg, rgba(0, 0, 0, 0.8), rgba(128, 128, 128, 0.2));
}

@keyframes scroll-left {
  0% {
    transform: translateX(130%);
  }
  100% {
    transform: translateX(-130%);
  }
}
<div id="container">
  <div id="marquee-container">
    <div id="first-cover"></div>
    <p id="marquee">The quick brown fox jumps over the lazy dog</p>
    <div id="second-cover"></div>
  </div>
</div>

For some reason backdrop-filter (specifically with opacity) isn't doing anything. Weird.

Edit:

You could probably define an image for the background of the marquee (with gradients on each side) and then use mix-blend-mode in some way to fade the text. Perhaps I'm overcomplicating this. ¯\(ツ)

CodePudding user response:

Animate the opacity property (cleaned up the code for better readability);

body {
  margin: 0;
}

div#marquee-container {
  width: 600px;
  height: 150px;
  background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 15%, rgba(255, 255, 255, 1) 85%, rgba(255, 255, 255, 0) 100%);
}

p#marquee {
  text-align: right;
  animation: scroll-left 10s linear infinite;
}

@keyframes scroll-left {
  0% {
    opacity: 0;
  }
  
  20% {
     opacity: 1;
  }
  
  80% {
    opacity: 1;
  }

  100% {
    transform: translateX(-80%);
    opacity: 0;
  }
}
<div style="background-color: black; width: 100%; height: 100%;">
  <div id="marquee-container">
    <p id="marquee">Testing</p>
  </div>
</div>

Side note: You don't need vendor prefixes for animation anymore.

CodePudding user response:

div#container {
  width: 100%;
  height: 100%;
  position: absolute;
  background-color: grey;
}

div#marquee-container {
  width: 600px;
  height: 150px;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translateX(-50%) translateY(-50%);
  
  background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 15%, rgba(255,255,255,1) 85%, rgba(255,255,255,0) 100%);
}

p#marquee {
  width: 80%;
  height: 80%;
  --opacity: 0;
  moz-animation:     scroll-left 1s  linear infinite;
  -webkit-animation: scroll-left 1s  linear infinite;
  animation:         scroll-left 10s linear infinite;
}
            
  @-moz-keyframes scroll-left {
    0%   {-moz-transform: translateX( 100%);}
    100% {-moz-transform: translateX(-100%);}
  }
            
  @-webkit-keyframes scroll-left {
    0%   {-webkit-transform: translateX( 100%)}
    100% {-webkit-transform: translateX(-100%)}
  }
            
  @keyframes scroll-left {
    0%   {-moz-transform: translateX( 100%); -webkit-transform: translateX( 100%); transform: translateX( 100%); opacity: 0;}
    30%{
    opacity: 1;
    }
      60%{
    opacity: 0;
    }
    100% {-moz-transform: translateX(-100%); -webkit-transform: translateX(-100%); transform: translateX(-100%);opacity: 0; }
  }
}
<div id="container">
  <div id="marquee-container">
    <p id="marquee">Testing</p>
  </div>
</div>

  • Related