It took me way too long, but now I’m happy to announce to my imaginary audience that I’ve finally launched my new website. Let me walk you through the details I’m disproportionately proud of.
Animated Underlines
You may have encountered animated underlines on menus before. But have you ever seen them follow the cursor? I haven’t, so I had to build it myself.
If you’re using a desktop browser, you can try the effect yourself on the main menu. For everyone else, here is a video:
A cursor moves over a menu item to show off an animated underline.
Draggable Cards
These cards remember their position (try reloading the page) and tilt to the left or right when you drag them. If you drop a card outside its bounding area, it will smoothly transition back.
Drag the cards around.
Pinhole Transition
This component can hold two or more slides to cycle through with a keyhole-transition. Click on the colored area below to watch the effect.
Click or tap anywhere on the colored area above.
Showing Random Slides
This component also cycles through a set of slides but lands on a random one, similar to rolling a dice. I added an easing effect that slows down the action towards the end.
Click or tap anywhere on the area above.
Auto-Scrolling Slides
This custom scroller has an option to automatically scroll back and forth. Like back in the 90ies when we had the glorious <marquee> tag. You can also scroll it using mouse or touch gestures or by clicking on the arrows (which appear on hover if you are using a desktop browser).
When you cannot scroll further in a given direction, the corresponding arrow will change into a circle. Clicking or tapping it will cause the scroll position indicator to shake.
Auto scrolling container, pauses on pointerenter and can be navigated by buttons as well.
Custom Scroll Areas
For elements that deal with overflowing content — eg. a menu on a small screen — I created the component <ScrollClip>. It can show buttons on the overflowing edges. Together with shadows, they act as signifiers (you can scroll in this direction) but you can also click them to scroll a certain distance.
Scroll around with a scroll wheel, trackpad or touch gesture or use the arrow buttons.
All these examples work with keyboard navigation
Try navigating this page with your keyboard: press the tab key to jump between interactive elements and the enter key to trigger them. This requires a small amount of extra work — but I think it’s absolutely worth it.
The tech behind this website
In case you are curious, this website runs on Jigsaw , a refreshingly minimal and robust static site generator. It’s written in PHP and built on top of Laravel’s Blade templating engine (which I am a big fan of).
It allows me to use custom component-tags with parameters for both purely markup partials, and fully interactive elements:
<x-box filled>
<!--
A Blade component to simply include
some HTML and CSS
-->
</x-box>
<x-scroller controls-overlay controls-autohide>
<!--
A Blade component to include an
interactive web component
(HTML + CSS + JS)
-->
</x-scroller>
For websites like this I prefer native Web Components to progressively enhance the experience. Everything works fine with JavaScript disabled.
To enhance my own developer experience, I hacked together a semi-elegant solution for single-file Blade components, where Vite processes the CSS and JS while the Blade template engine processes the markup:
{{--
An example file (myComponent.blade.php) which
I can use in any other Blade file simply by
writing <x-myComponent />.
--}}
@props([
$someAttribute => false,
])
<x-vite component="myComponent">
<style>
.myComponent {
/* ... */
}
</style>
<script>
customElements.define(
'my-component',
class extends HTMLElement {
// ...
}
)
</script>
</x-vite>
<my-component {{ $attributes->merge(['someAttribute' => $someAttribute]) }}>
<!-- ... -->
</my-component>
This is how my homebrew single-file Blade components look like.
I have used 11ty + WebC , Astro and other tools before which offer similar solutions but I prefer the simplicity and robustness of Jigsaw. No need for explicit imports (Blade associates component-tags with corresponding files automatically), no need for constant updates and fixing breaking changes, no syntactic overhead — it’s just very much how I like it.
Some other stuff I used
- Tailwind for Design Tokes and Utility Classes
- Lucide and Tabler icon sets
- Lineto Akkurat for gorgeous looking text
That’s it. I hope you’ll have fun exploring my website.