Terminal Website Using Typewriter.js and CSS

Terminal Website Using Typewriter.js and CSS

Just recently, I was searching for how to create a terminal-esque website, much like Jeremy Wagner’s old site where you could run commands to open different links and places on his site.

Side Note : To get the Dev related News & Articles Check my Telegram Channel

It was really cool, and interesting idea: a command line interface to navigate a website.

I went in search of doing something similar however couldn’t find any articles or tutorials on how to do it.

Hacker Noon

I found an interesting article on how to make a terminal landing page. It was kind of what I was looking for, but still had some flaws:

  • The UI of the site was decent but still not what I would want
  • I dug into the code on GitHub and decided that piping in a text file to do the typewriter effect was a hack I wasn’t willing to put up with

The interesting bits, like the typing and the introduction to what the site is about, was something I could take with me.

GitHub diving

I came across this site, 0x44 and instantly knew I wanted my landing page to look like this.

I copied the CSS when I inspected the site, added a bit of my own, and went to work.

The HTML

It’s just plain old HTML; a header and nav, footer, like so:

<header>
    <nav>
      <a href="/" class="underline">/about</a>
      <a href="your email here" class="underline">/contact</a>
    </nav>
  </header>
  <div class="site-title">
    <h1>
      <a href="/">IcedMonk:$</a><span class="cursor"></span>
    </h1>
  </div>
  <div id="app" class="container">

  </div>
  <footer>

    <a href="https://github.com/icedmonk/" class="svglink">
      //GitHub svg here
    </a>
    <br><br>
    © Copyright 2019 - incedmonk.
  </footer>
</body>
</html>

Here we have a nav that will have the core links underlined. Then, we give the main part of the terminal header the class, site-title where we will give it its 1980s terminal vibe. You can find the block cursor with an online search.

The second div is where the cool stuff happens.

I am using a library for the typewriter effect called, obviously, typerwriterjs . In order to type everything we need out to the “console”, we need an empty div we can target with enough space to type what we need. We can do that with an id of app. Then I added a class of container to center the content and then make it responsive once we add content to the div. Then the footer is just an svg of the GitHub logo and a copyright.

The CSS

This is the look that Ian Pringle created with his site. The main pieces are:

a {
  color: rgb(0, 170, 0);
  text-decoration: none;
}

.underline:hover {
  color: rgb(0, 170, 0);
}

.underline {
  position: relative;
}

.underline::before {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 2px;
  background-color: rgb(0, 170, 0);
  transform-origin: bottom right;
  transform: scaleX(0);
  transition: transform 0.5s ease;
}

.underline:hover::before {
  transform-origin: bottom left;
  transform: scaleX(1);
}

.cursor {
  animation: cursor 2s infinite;
  color: rgb(0, 170, 0);
  display: inline-block;
  width: 10px;
  margin-left: 5px;
  border-radius: 1px;
}

.centered {
  margin: 0px auto 40px;
  display: block;
}

@keyframes cursor {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

.container {
  display: flex;
  align-content: center;
}

We want to give the links that 1980s terminal green. We also want to give the body a black-ish background, and use CSS transitions and transforms so that when you hover the links in the nav, you get the ease-in-out effect:

Codesnatchers_website_like_console.gif

Using the transform-origin property allows us to specify where to start and end the transition, in this case, the bottom right of the link in the nav.

We give the cursor some love with the animation property and keyframes to give it a fade in and out look as it is blinking.

Finally, we make the text container, where our links will be displayed, a display of flex so it can shrink and expand as needed, and then we can align our links within that container center.

The problem I had was keeping the footer flush to the bottom, regardless of where the content was initiated.

I added this to the footer:

footer {
  text-align: center;
  position: fixed;
  bottom: 0;
}

positioning the footer at the bottom with the fixed property making it static, and giving the bottom of the footer a length of 0.

The JavaScript

Okay this isn’t really all that difficult. Just following the docs allows you to get something up and running relatively quickly.

Insert the unpkg link in the area above the closing body tag, along with the file you’re going to initialize the typing effect in:

<body>
  // Some code
  <script src="https://unpkg.com/typewriter-effect@latest/dist/core.js"></script>
  <script src="app.js"></script>
</body>

You initialize the Typewriter object like so:

var app = document.getElementById('app');

var typewriter = new Typewriter(app, {
  loop: false,
  delay: 75,
  autoStart: true,
  cursor: '█',
  strings: ['My name is Samyek, and I am a Web developer and wannabe entrepreneur.']
});

We target the DOM node we want the typing to occur, this being the div with the id of app. Then we create a new Typewriter object, pass in our app variable, and add a few properties on the Typewriter object:

  • loop: do you want the typing to start over when it is finished?: Boolean

  • How long to delay the start of the typing: Number, in ms

  • Whether or not to start when a user initially loads the site: Boolean

  • Type of cursor you want, the default being the pipe: String

  • And the initial string you want to type out when the user first visits: Array of strings

This is simple enough.

To get the typing started, we can do something like this:

typewriter
  .deleteAll(1)
  .pauseFor(50)
  .deleteAll(1)
  .typeString('I work for <strong>[ENTERTEN]</strong> as a frontend dev, and I code, write, and shoot and edit videos on weekends.')
  .pauseFor(300)
  .deleteAll(1)
  .typeString('Find me online: <br />')
  .pauseFor(300)
  .typeString('<a href="https://codesnatchers.com">Blog</a> <br />')
  .typeString('<a href="https://loving-gates-05283f.netlify.com/">Portfolio</a> <br />')

We delete all the initial strings using the deleteAll method which takes a number in ms for how long the delete animation should last. Then we can use the pauseFor method to pause for a specified time in ms.

The typeString method allows us to type whatever we want. Each method takes one string that can also contain HTML. This means in order to do what I wanted, I needed to create several typeString methods to create a list of links I wanted to show on different lines. It’s an unfortunate limitation but with everything else you get in the library, it is not a deal breaker.

Check out all the methods that come with the library to see what you can do with it.

Wrap-up

It’s a simple thing that looks cool and is easy enough to build. Let me know your Ideas & what you think in the comments below.

Do Check my Telegram Channel