How I Designed and Built This Website

A walkthrough of some of the design and development decisions that went into this blog.

December 26, 2019 | Mike Buss

I started this blog in 2007 during my junior year of High School. My goal was to share tidbits about programming and use it as a portfolio item for future employers. Since then, it’s evolved into a way of sharing my personal interests, including everything from puppies to standing desks.

In this post, I’ll cover the technology I use to design and build this site.


Table of Contents

  1. Context
  2. Design
  3. Code
  4. Deploy
  5. Next Steps
  6. Conclusion

Context

I wanted to keep the website as simple as possible. Maintaining databases, servers, and backups seemed like a heavy solution for a simple blog. For this reason, I didn’t consider tools like Wordpress.

I eventually landed on using a static site generator called Jekyll. Jekyll lets you write blog posts in the Markdown format and converts them into HTML files. These files can then be copied to a server (or, in my case, AWS S3) and served to visitors.


Design

I considered using an off-the-shelf Jekyll theme for the blog but eventually decided to write my own. This site was supposed to be a portfolio item, after all, so I wanted it to reflect my design sense.

I used to use Photoshop for all of my design work but it always felt like an 800 pound gorilla. When Sketch was released in 2010, I made the switch. If you’re interested in quickly mocking up designs, I would highly recommend using Sketch or Figma.

To design the blog, I started with the smallest screen size I wanted to support: 320 pixels wide. I wanted to support small phones (iPhone SE), medium and large phones (iPhone 11 Pro and iPhone 11 Pro Max), tablets (9.7”, 10.2” and 12.9” iPads) and desktop machines.

From there, I sketched up how the blog should look in each size using the Sketch app:

The design for small devices.

I spent a lot of time making sure the site looks presentable in different sizes. Several of the images are different depending on your screen size. Here’s an example:

Full-width truncated images on mobile and a totally different image on desktop-size screens. Note the bottom devices are fully formed in the larger version on the right.

This was accomplished using the picture element in HTML 5 and media queries.

I also mocked up a Dark Mode design for the website. If you have Dark Mode enabled on macOS, iOS, or a supported browser, you should see it now.

To accomplish this, I used the prefers-color-scheme: dark media query in CSS:

@media (prefers-color-scheme: dark) {
    // Your dark style here!
}

Here’s a screenshot:

Link colors were changed to 'pop' a bit more in dark mode, for example.

I’ve cycled through about 20 different fonts for this blog over the years but the one I’m happiest with is called Inter. I used the Inter font and the Dynamic Metrics calculator to find the best letter spacing and line height to use for legibility.


Code

I coded the Jekyll theme in HTML and CSS using Visual Studio Code. At some point, I’d like to switch to Sass.

To make the website feel snappy, I used the jekyll-responsive-images plugin. This allows me to generate one image in Sketch, reference it in a blog post, and have multiple sizes generated automatically. Then, the user’s browser will determine which image to show based on their screen size. This is all done with the srcset feature of HTML. If you’re interested in doing something similar, Mozilla has a great tutorial on responsive images.

I also used the jekyll-compress-images plugin to compress images but I wouldn’t recommend it. As of today, there’s an issue with the plugin that causes an infinite loop when building your site. If you’re running Jekyll with the --watch flag, this means saving any file will ramp your CPU up to 100% indefinitely. None of the suggested fixes have worked for me, so I opted to compress the images once and then remove the plugin.

I absolutely hate using Chrome, but their developer tools are best-in-class. I used Chrome to debug the different screen sizes, starting with the smallest. When Firefox’s version of this tool gets better, I’ll switch to that.


Deploy

When the design was coded and the blog posts were written, the site was ready to deploy. I wound up having two different methods to deploy the site: manually, and through AWS CodeBuild.

Manual Deploys

First, let’s cover the boring deploy method. When I’m writing blog posts on my 2018 Mac Mini, I can build the site in about 2.8 seconds. I’m lucky enough to have a gigabit internet connection, so deploying the site takes a few seconds depending on how many images were added. I sync the contents of my local _site folder to an S3 bucket using the CLI tools for AWS.

This line from my deploy.sh bash script does most of the heavy lifting:

aws s3 sync _site/ s3://mikebuss.com --delete

Then, I invalidate the files in AWS CloudFront, my content delivery network (CDN), so visitors will see the latest changes. This line covers that step:

aws cloudfront create-invalidation \
--distribution-id "$(DISTRIBUTION_ID)" \
--paths "/*"

This is the quickest method to deploying my site, but has some drawbacks. If I’m on-the-go without my laptop and I notice a typo, there’s not much I can do. The next method lets me check out a git repository on my phone, push the changes, and have a remote server deploy the updated site.

Deploying with AWS CodeBuild

I prefer to use AWS CodeBuild to deploy my site when I’m away from my laptop. When I push git commits to AWS CodeCommit the CodeBuild service will start a new deployment. Here is the build script I use:

version: 0.2

phases:
  install:
    runtime-versions:
      ruby: 2.6
  build:
    commands:
      - gem install bundler -v "2.0.2"
      - gem environment
      - bundle --version
      - bundle install
      - bundle exec jekyll build
  post_build:
    commands:
    - aws s3 sync _site/ s3://$S3_BUCKET --delete --debug
    - aws cloudfront create-invalidation --distribution-id "${DISTRIBUTION_ID}" --paths "/*"

I had someone ask why I use CodeBuild instead of CodeDeploy for this. I was originally planning on using CodeDeploy but decided it was an extra step that wasn’t necessary. The CodeBuild service is able to build the site and synchronize it to S3 without much hassle.


Next Steps

I’d like to migrate from Jekyll to something faster like Hugo. I don’t have many posts - only about 20 - but I’m already starting to notice the build time increasing. And, with any Jekyll setup comes the whole Ruby shebang, including RVM, bundler and more compilation errors with nokogiri than you can imagine. Seriously. That gem can burn in a fire.


Conclusion

Hopefully this post is useful for someone looking to create a blog with similar technology. If you have any questions, feel free to shoot me an email.

Notice a goof? Have feedback? I read every email I get!