This Website
My personal website/project portfolio.
What/why?
During my PhD, I had a personal website, hosted by Yale, that was mostly just a publications list. After I defended in mid-2022, I decided I wanted a new one that I had more access to, looked nicer, and where I could showcase some of my other interests. I had the idea to make it look sort of console-y, wrote some HTML and CSS, threw it on GitHub Pages, and lo, a website was born.
How?
The "wrote some HTML and CSS" part is actually a significant
oversimplification; this thing is an overengineered monster.
After using React and drowning in node_modules
for the
last site, my main goals for this one were to use only plain,
semantic HTML and CSS, nary a drop of JavaScript, while still being
reactive and having some fun visual elements, and to automate as
many tedious processes as possible.
This led to lots of time browsing
CSS-Tricks and the
development of a suite of home-grown build infrastructure tools.
Some of the interesting bits are highlighted below.
Build Pipeline
- For the music, photos, and publications pages, I wanted to use
the same block of HTML for a bunch of items, but with different
details like titles, captions, and links.
Enter THTML, my custom HTML
template format.
It understands JSON, so the following will read
music.json
and generate a<section>
for each object in the songs array using the title and audio fields.<%%j music.json.songs %> <section> <h3><%ji .title %></h3> <audio> <source src="/assets/music/<%ji .audio %>" /> </audio> </section> <%%e %>
- The world map on the photos page is automatically generated by reading the coordinates from some shape files downloaded from Natural Earth Data and creating SVG polygons. The shape files also include metadata like the country/state name, so the conversion script checks if there's a corresponding subdirectory in the photos directory and adds a link if so.
- In order to keep my CV up to date, rather than include a static PDF in the website source, the LaTeX files are kept in their own repo with a GitHub Action set up to compile it and save the PDF as a release artifact.
- The entire site is "built" from a Makefile. This includes running the THTML and world map generator scripts, copying and optimizing assets like photos and audio, minifying HTML and CSS, and generating favicons of various sizes. The result is a directory with everything needed to serve the site.
- To test the site locally I wrote a small Python web server that's just SimpleHTTPRequestHandler with some extra HTTP headers to prevent caching. It also runs a file watcher to handle automatic rebuilding whenever the source files change. It's a bit overkill for a static site, but it makes it easier to test on other devices, like my phone.
- Finally, the site is deployed by a GitHub Action that builds the site using a Nix Flake and puts it where GitHub Pages expects.
Fun CSS Trickery
- The thing in the header that types out wolf.html when the page
loads (unless prefers-reduced-motion is set) uses
CSS animations.
The typing effect works by using
clip-path
to reveal one character at a time (every character is exactly1ch
wide since I'm using a monospace font). The cursor is a1ch
-wide empty::after
pseudo-element that blinks by alternating between 0% and 100%opacity
. - The zoom in/out feature of the world map on the
photos page uses the
checkbox hack.
Using the
~
selector and the:checked
pseudo-class, a CSS rule can detect when the box is checked and adjust the map's width. - The little arrow on the top right corner of links uses
::after
with a border on the top and right sides. To make it grow on hover, the whole thing is scaled withtransform
while the thickness of the border is reduced to keep it the same size. There's also some positioning trickery to get it to work with links with line breaks that doesn't work perfectly in all browsers, but it's good enough for me.