<h1>
   Hello, my name is Momchil
</h1>

<h2>
   I build applications on <span id="test"><em class="sr-only">the Web</em></span>.
</h2>
:root {
   --f-bg: #eff1ec;
   --f-text: #16171c;
   --f-ternary: #48bb78;
}

@media (prefers-color-scheme: dark) {
   :root {
      --f-bg: #16171c;
      --f-text: #eff1ec;
      --f-ternary: #276749;
   }
}

html {
   display: flex;
   align-items: center;
   justify-content: center;
   height: 100vh;
   font-size: 16px;
   background: var(--f-bg);
   color: var(--f-text);
}

.sr-only {
   position: absolute;
   width: 1px;
   height: 1px;
   padding: 0;
   margin: -1px;
   overflow: hidden;
   clip: rect(0, 0, 0, 0);
   white-space: nowrap;
   border-width: 0;
}

h1,
h2 {
   -webkit-font-smoothing: antialiased;
   font-weight: 500;
   font-family: IBM Plex Serif, system-ui, -apple-system, BlinkMacSystemFont,
      Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif,
      Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
}

h1 {
   font-size: 1.5rem;
   margin: 0;
   padding: 0;
   color: var(--f-ternary);
}

h2 {
   margin: 0;
   margin-top: 1rem;
   font-size: 3rem;

   span {
      &::after {
         content: "|";
         font-weight: normal;
         animation: cursor 1.25s infinite;
      }
   }
}

@keyframes cursor {
   0% {
      opacity: 0;
   }
   50% {
      opacity: 1;
   }
   100% {
      opacity: 0;
   }
}
View Compiled
function Typewriter(el) {
   const instance = {
      el,
      eventLoop: [],

      wait: (time) => {
         instance.eventLoop.push(
            () => new Promise((resolve) => setTimeout(resolve, time))
         );

         return instance;
      },

      type: (text) => {
         instance.eventLoop.push(
            () =>
               new Promise((resolve) => {
                  let idx = 0;

                  const typeOut = (text) => {
                     window.requestAnimationFrame(() => {
                        if (idx < text.length) {
                           el.innerHTML += text.charAt(idx);
                           idx++;

                           setTimeout(() => typeOut(text), 125);
                        } else {
                           resolve();
                        }
                     });
                  };

                  typeOut(text);
               })
         );

         return instance;
      },

      clear: () => {
         instance.eventLoop.push(
            () =>
               new Promise((resolve) => {
                  const clearText = () => {
                     window.requestAnimationFrame(() => {
                        if (el.innerHTML !== "") {
                           el.innerHTML = el.innerHTML.substr(
                              0,
                              el.innerHTML.length - 1
                           );

                           setTimeout(clearText, 125);
                        } else {
                           resolve();
                        }
                     });
                  };

                  clearText();
               })
         );

         return instance;
      },

      run: (loop) => {
         let i = 0;

         const _run = () =>
            new Promise((resolve) => {
               if (i < instance.eventLoop.length) {
                  return instance.eventLoop[i]().then(() => {
                     i++;
                     return _run();
                  });
               }

               if (loop) {
                  instance.run(loop);
               }

               resolve();
            });

         _run();
      }
   };

   return instance;
}

document.getElementById("test").innerHTML = "";

const writer = Typewriter(document.getElementById("test"))
   .type("the Web")
   .wait(1500)
   .clear()
   .wait(200)
   .type("iOS")
   .wait(1500)
   .clear()
   .wait(200)
   .type("Android")
   .wait(1500)
   .clear()
   .wait(200)
   .run(true);
View Compiled

External CSS

  1. https://fonts.googleapis.com/css2?family=IBM+Plex+Serif:wght@100;500&amp;display=swap

External JavaScript

This Pen doesn't use any external JavaScript resources.