CSS CRT/Scanline Demo

dracula pixel artdracula pixel artdracula pixel art
Pixel art example, here dracula from Castlevania: Symphony of the Night
scanline.css
/* CSS courtesy of https://dev.to/ekeijl/retro-crt-terminal-screen-in-css-js-4afh
 * and http://aleclownes.com/2017/02/01/crt-display.html */
.crt::before {
  content: " ";
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.25) 50%),
              linear-gradient(90deg, rgba(255, 0, 0, 0.04) 5%, rgba(255, 0, 0, 0.02) 20%, rgba(0, 255, 0, 0.02) 50%, rgba(255, 0, 0, 0.02) 80%, rgba(0, 0, 255, 0.04) 95%);
  z-index: 7;
  background-size: 100% 4px, 100% 4px;
  pointer-events: none;
}

.crt {
  position: relative;
  width: 100%;
  height: 100%;
  background-color: #161616;
}

.crt-text {
  animation: textShadow 1.6s infinite;
}

.pixel-art {
  image-rendering: pixelated;
}

@keyframes textShadow {
  0% {
    text-shadow: 0.4389924193300864px 0 4px rgba(0,30,255,0.5), -0.4389924193300864px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  5% {
    text-shadow: 2.7928974010788217px 0 4px rgba(0,30,255,0.5), -2.7928974010788217px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  10% {
    text-shadow: 0.02956275843481219px 0 4px rgba(0,30,255,0.5), -0.02956275843481219px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  15% {
    text-shadow: 0.40218538552878136px 0 4px rgba(0,30,255,0.5), -0.40218538552878136px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  20% {
    text-shadow: 3.4794037899852017px 0 4px rgba(0,30,255,0.5), -3.4794037899852017px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  25% {
    text-shadow: 1.6125630401149584px 0 4px rgba(0,30,255,0.5), -1.6125630401149584px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  30% {
    text-shadow: 0.7015590085143956px 0 4px rgba(0,30,255,0.5), -0.7015590085143956px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  35% {
    text-shadow: 3.896914047650351px 0 4px rgba(0,30,255,0.5), -3.896914047650351px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  40% {
    text-shadow: 3.870905614848819px 0 4px rgba(0,30,255,0.5), -3.870905614848819px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  45% {
    text-shadow: 2.231056963361899px 0 4px rgba(0,30,255,0.5), -2.231056963361899px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  50% {
    text-shadow: 0.08084290417898504px 0 4px rgba(0,30,255,0.5), -0.08084290417898504px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  55% {
    text-shadow: 2.3758461067427543px 0 4px rgba(0,30,255,0.5), -2.3758461067427543px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  60% {
    text-shadow: 2.202193051050636px 0 4px rgba(0,30,255,0.5), -2.202193051050636px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  65% {
    text-shadow: 2.8638780614874975px 0 4px rgba(0,30,255,0.5), -2.8638780614874975px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  70% {
    text-shadow: 0.48874025155497314px 0 4px rgba(0,30,255,0.5), -0.48874025155497314px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  75% {
    text-shadow: 1.8948491305757957px 0 4px rgba(0,30,255,0.5), -1.8948491305757957px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  80% {
    text-shadow: 0.0833037308038857px 0 4px rgba(0,30,255,0.5), -0.0833037308038857px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  85% {
    text-shadow: 0.09769827255241735px 0 4px rgba(0,30,255,0.5), -0.09769827255241735px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  90% {
    text-shadow: 3.443339761481782px 0 4px rgba(0,30,255,0.5), -3.443339761481782px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  95% {
    text-shadow: 2.1841838852799786px 0 4px rgba(0,30,255,0.5), -2.1841838852799786px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  100% {
    text-shadow: 2.6208764473832513px 0 4px rgba(0,30,255,0.5), -2.6208764473832513px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
}

@keyframes imageShadow {
  0% {
    box-shadow: 0.4389924193300864px 0 4px rgba(0,30,255,0.5), -0.4389924193300864px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  5% {
    box-shadow: 2.7928974010788217px 0 4px rgba(0,30,255,0.5), -2.7928974010788217px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  10% {
    box-shadow: 0.02956275843481219px 0 4px rgba(0,30,255,0.5), -0.02956275843481219px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  15% {
    box-shadow: 0.40218538552878136px 0 4px rgba(0,30,255,0.5), -0.40218538552878136px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  20% {
    box-shadow: 3.4794037899852017px 0 4px rgba(0,30,255,0.5), -3.4794037899852017px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  25% {
    box-shadow: 1.6125630401149584px 0 4px rgba(0,30,255,0.5), -1.6125630401149584px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  30% {
    box-shadow: 0.7015590085143956px 0 4px rgba(0,30,255,0.5), -0.7015590085143956px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  35% {
    box-shadow: 3.896914047650351px 0 4px rgba(0,30,255,0.5), -3.896914047650351px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  40% {
    box-shadow: 3.870905614848819px 0 4px rgba(0,30,255,0.5), -3.870905614848819px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  45% {
    box-shadow: 2.231056963361899px 0 4px rgba(0,30,255,0.5), -2.231056963361899px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  50% {
    box-shadow: 0.08084290417898504px 0 4px rgba(0,30,255,0.5), -0.08084290417898504px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  55% {
    box-shadow: 2.3758461067427543px 0 4px rgba(0,30,255,0.5), -2.3758461067427543px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  60% {
    box-shadow: 2.202193051050636px 0 4px rgba(0,30,255,0.5), -2.202193051050636px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  65% {
    box-shadow: 2.8638780614874975px 0 4px rgba(0,30,255,0.5), -2.8638780614874975px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  70% {
    box-shadow: 0.48874025155497314px 0 4px rgba(0,30,255,0.5), -0.48874025155497314px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  75% {
    box-shadow: 1.8948491305757957px 0 4px rgba(0,30,255,0.5), -1.8948491305757957px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  80% {
    box-shadow: 0.0833037308038857px 0 4px rgba(0,30,255,0.5), -0.0833037308038857px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  85% {
    box-shadow: 0.09769827255241735px 0 4px rgba(0,30,255,0.5), -0.09769827255241735px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  90% {
    box-shadow: 3.443339761481782px 0 4px rgba(0,30,255,0.5), -3.443339761481782px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  95% {
    box-shadow: 2.1841838852799786px 0 4px rgba(0,30,255,0.5), -2.1841838852799786px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  100% {
    box-shadow: 2.6208764473832513px 0 4px rgba(0,30,255,0.5), -2.6208764473832513px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
}

.scanline {
    width: 100%;
    height: 100px;
    z-index: 8;
    background: linear-gradient(
        0deg,
        rgba(0, 0, 0, 0) 0%,
        rgba(255, 255, 255, 0.2) 10%,
        rgba(0, 0, 0, 0.1) 100%
    );
    opacity: 0.1;
    position: absolute;
    bottom: 100%;
    animation: scanline 3s linear infinite;
    pointer-events: none;
}

@keyframes scanline {
    0% {
        bottom: 100%;
    }
    100% {
        bottom: 0%;
    }
}

CSS CRT/Scanline Demo

dracula pixel artdracula pixel artdracula pixel art
Pixel art example, here dracula from Castlevania: Symphony of the Night
scanline.css
/* CSS courtesy of https://dev.to/ekeijl/retro-crt-terminal-screen-in-css-js-4afh
 * and http://aleclownes.com/2017/02/01/crt-display.html */
.crt::before {
  content: " ";
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.25) 50%),
              linear-gradient(90deg, rgba(255, 0, 0, 0.04) 5%, rgba(255, 0, 0, 0.02) 20%, rgba(0, 255, 0, 0.02) 50%, rgba(255, 0, 0, 0.02) 80%, rgba(0, 0, 255, 0.04) 95%);
  z-index: 7;
  background-size: 100% 4px, 100% 4px;
  pointer-events: none;
}

.crt {
  position: relative;
  width: 100%;
  height: 100%;
  background-color: #161616;
}

.crt-text {
  animation: textShadow 1.6s infinite;
}

.pixel-art {
  image-rendering: pixelated;
}

@keyframes textShadow {
  0% {
    text-shadow: 0.4389924193300864px 0 4px rgba(0,30,255,0.5), -0.4389924193300864px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  5% {
    text-shadow: 2.7928974010788217px 0 4px rgba(0,30,255,0.5), -2.7928974010788217px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  10% {
    text-shadow: 0.02956275843481219px 0 4px rgba(0,30,255,0.5), -0.02956275843481219px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  15% {
    text-shadow: 0.40218538552878136px 0 4px rgba(0,30,255,0.5), -0.40218538552878136px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  20% {
    text-shadow: 3.4794037899852017px 0 4px rgba(0,30,255,0.5), -3.4794037899852017px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  25% {
    text-shadow: 1.6125630401149584px 0 4px rgba(0,30,255,0.5), -1.6125630401149584px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  30% {
    text-shadow: 0.7015590085143956px 0 4px rgba(0,30,255,0.5), -0.7015590085143956px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  35% {
    text-shadow: 3.896914047650351px 0 4px rgba(0,30,255,0.5), -3.896914047650351px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  40% {
    text-shadow: 3.870905614848819px 0 4px rgba(0,30,255,0.5), -3.870905614848819px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  45% {
    text-shadow: 2.231056963361899px 0 4px rgba(0,30,255,0.5), -2.231056963361899px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  50% {
    text-shadow: 0.08084290417898504px 0 4px rgba(0,30,255,0.5), -0.08084290417898504px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  55% {
    text-shadow: 2.3758461067427543px 0 4px rgba(0,30,255,0.5), -2.3758461067427543px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  60% {
    text-shadow: 2.202193051050636px 0 4px rgba(0,30,255,0.5), -2.202193051050636px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  65% {
    text-shadow: 2.8638780614874975px 0 4px rgba(0,30,255,0.5), -2.8638780614874975px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  70% {
    text-shadow: 0.48874025155497314px 0 4px rgba(0,30,255,0.5), -0.48874025155497314px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  75% {
    text-shadow: 1.8948491305757957px 0 4px rgba(0,30,255,0.5), -1.8948491305757957px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  80% {
    text-shadow: 0.0833037308038857px 0 4px rgba(0,30,255,0.5), -0.0833037308038857px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  85% {
    text-shadow: 0.09769827255241735px 0 4px rgba(0,30,255,0.5), -0.09769827255241735px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  90% {
    text-shadow: 3.443339761481782px 0 4px rgba(0,30,255,0.5), -3.443339761481782px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  95% {
    text-shadow: 2.1841838852799786px 0 4px rgba(0,30,255,0.5), -2.1841838852799786px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  100% {
    text-shadow: 2.6208764473832513px 0 4px rgba(0,30,255,0.5), -2.6208764473832513px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
}

@keyframes imageShadow {
  0% {
    box-shadow: 0.4389924193300864px 0 4px rgba(0,30,255,0.5), -0.4389924193300864px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  5% {
    box-shadow: 2.7928974010788217px 0 4px rgba(0,30,255,0.5), -2.7928974010788217px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  10% {
    box-shadow: 0.02956275843481219px 0 4px rgba(0,30,255,0.5), -0.02956275843481219px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  15% {
    box-shadow: 0.40218538552878136px 0 4px rgba(0,30,255,0.5), -0.40218538552878136px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  20% {
    box-shadow: 3.4794037899852017px 0 4px rgba(0,30,255,0.5), -3.4794037899852017px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  25% {
    box-shadow: 1.6125630401149584px 0 4px rgba(0,30,255,0.5), -1.6125630401149584px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  30% {
    box-shadow: 0.7015590085143956px 0 4px rgba(0,30,255,0.5), -0.7015590085143956px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  35% {
    box-shadow: 3.896914047650351px 0 4px rgba(0,30,255,0.5), -3.896914047650351px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  40% {
    box-shadow: 3.870905614848819px 0 4px rgba(0,30,255,0.5), -3.870905614848819px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  45% {
    box-shadow: 2.231056963361899px 0 4px rgba(0,30,255,0.5), -2.231056963361899px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  50% {
    box-shadow: 0.08084290417898504px 0 4px rgba(0,30,255,0.5), -0.08084290417898504px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  55% {
    box-shadow: 2.3758461067427543px 0 4px rgba(0,30,255,0.5), -2.3758461067427543px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  60% {
    box-shadow: 2.202193051050636px 0 4px rgba(0,30,255,0.5), -2.202193051050636px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  65% {
    box-shadow: 2.8638780614874975px 0 4px rgba(0,30,255,0.5), -2.8638780614874975px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  70% {
    box-shadow: 0.48874025155497314px 0 4px rgba(0,30,255,0.5), -0.48874025155497314px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  75% {
    box-shadow: 1.8948491305757957px 0 4px rgba(0,30,255,0.5), -1.8948491305757957px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  80% {
    box-shadow: 0.0833037308038857px 0 4px rgba(0,30,255,0.5), -0.0833037308038857px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  85% {
    box-shadow: 0.09769827255241735px 0 4px rgba(0,30,255,0.5), -0.09769827255241735px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  90% {
    box-shadow: 3.443339761481782px 0 4px rgba(0,30,255,0.5), -3.443339761481782px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  95% {
    box-shadow: 2.1841838852799786px 0 4px rgba(0,30,255,0.5), -2.1841838852799786px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
  100% {
    box-shadow: 2.6208764473832513px 0 4px rgba(0,30,255,0.5), -2.6208764473832513px 0 1px rgba(255,0,80,0.3), 0 0 8px;
  }
}

.scanline {
    width: 100%;
    height: 100px;
    z-index: 8;
    background: linear-gradient(
        0deg,
        rgba(0, 0, 0, 0) 0%,
        rgba(255, 255, 255, 0.2) 10%,
        rgba(0, 0, 0, 0.1) 100%
    );
    opacity: 0.1;
    position: absolute;
    bottom: 100%;
    animation: scanline 3s linear infinite;
    pointer-events: none;
}

@keyframes scanline {
    0% {
        bottom: 100%;
    }
    100% {
        bottom: 0%;
    }
}