More from Ryan Mulligan
Hey there. It has been a minute since my last post. I was semi-recently tagged by Zach Leatherman to (optionally) participate in this year's Blog Questions Challenge. I had planned on doing it then. But life really hit hard as we entered this year and it has not let up. Energy dedicated to my personal webspace has been non-existent. I am tired. Hopefully this post can help shake off some of the rust, bring me back to writing and sharing with you lovely folks. I won't be tagging anyone to do this challenge. However, if you're inspired to write your own after reading mine, I'd love for you to share it with me. Why did you start blogging in the first place? Blogging has always been a part of my web experience. Earliest I can remember is building my band a GeoCities website back in high school. I'd share short passages about new song ideas, how last night's show went, stuff like that. I also briefly had a Xanga blog running. My memory is totally faded on what exactly I wrote in there—I'm not eager to dig up high school feelings either—but fairly certain all of those entries are just lost digital history. Having an "online journal" was such a fresh idea at the time. Sharing felt more natural and real before the social media platforms took over. [blows raspberry] I've completely dated myself and probably sound like "old man yells at cloud" right now. Anyway, I pretty much stopped blogging for a while after high school. I turned my efforts back to pen on paper, keeping journals of lyrics, thoughts, and feelings mostly to myself. My dev-focused blogging that you may be familiar with really only spans the last decade, give or take a couple years. What platform are you using to manage your blog and why? At the moment and the forseeable future, I'm using 11ty. I published a short post about migrating to 11ty back in 2021. I still feel the same sentiments and still admire those same people. And many new community friends as well! Have you blogged on other platforms before? I've definitely used WordPress but I can't remember what the heck I was even blogging about during that time. Then I switched to just writing posts directly in HTML files and FTP'ing them up to some server somewhere. Pretty silly in retrospect, but boy did I feel alive. How do you write your posts? Always via laptop, never on my phone. I manage posts in markdown files, push them up to a GitHub repo and let that automatically redeploy my site on Netlify. Editing content is done in VSCode. I've debated switching to some lightweight CMS, connecting to Notion or Obsidian, but why introduce any more complexity and mess with what works fine for me? When do you feel most inspired to write? Typically I'll write up a post about something new I discovered while on my wild coding escapades, whether at work or in my free time. If I have trouble finding solutions to my particular problem on the world wide webs, I'm even more inclined to post about it. Most of my ideas are pursued on weekends, but I've had some early morning or late night weekday sessions. What I'm trying to say is that anytime is a good time for blogging. It's like pizza when it's on a bagel. Do you publish immediately after writing, or do you let it simmer a bit as a draft? It depends. If I had been writing for a long period of time, I find it best to take a breather before publishing. When I feel ready, I'll post and share with a small group for feedback, find grammatical errors. Then I eventually add it to whatever social channels feel right. Used to be Twitter, but straight up screw that garbage temple. I'll likely post on Bluesky, toot on Mastodon. Other times I'll slap a new post on this site and not share it on any socials. Let the RSS feeds do their magic. What's your favorite post on your blog? I don't know if I have a favorite. Can I love them all equally? Well, besides that CSS Marquee one. Damn that blog post for becoming so popular. Any future plans for your blog? Once things settle down in life, I think I'll be ready for a redesign. I had a blast building the current version inspired by Super Mario Wonder. Until then? More blogging. It won't be super soon, but I do have a few zesty article ideas percolating in this old, tired brain.
Once again, here I am, hackin' away on horizontal scroll ideas. This iteration starts with a custom HTML tag. All the necessities for scroll overflow, scroll snapping, and row layout are handled with CSS. Then, as a little progressive enhancement treat, button elements are connected that scroll the previous or next set of items into view when clicked. Behold! The holy grail of scrolling rails... the scrolly-rail! CodePen demo GitHub repo Open CodePen demo I'm being quite facetious about the "holy grail" part, if that's not clear. 😅 This is an initial try on an idea I'll likely experiment more with. I've shared some thoughts on potential future improvements at the end of the post. With that out of the way, let's explore! The HTML Wrap any collection of items with the custom tag: <scrolly-rail> <ul> <li>1</li> <li>2</li> <li>3</li> <!-- and so on--> </ul> </scrolly-rail> The custom element script checks if the direct child within scrolly-rail is a wrapper element, which is true for the above HTML. While it is possible to have items without a wrapper element, if the custom element script runs and button controls are connected, sentinel elements are inserted at the start and end bounds of the scroll container. Wrapping the items makes controlling spacing between them much easier, avoiding any undesired gaps appearing due to these sentinels. We'll discover what the sentinels are for later in the post. The CSS Here are the main styles for the component: scrolly-rail { display: flex; overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; @media (prefers-reduced-motion: no-preference) { scroll-behavior: smooth; } } When JavaScript is enabled, sentinel elements are inserted before and after the unordered list (<ul>) element in the HTML example above. Flexbox ensures that the sentinels are positioned on either side of the element. We'll find out why later in this post. Containing the overscroll behavior will prevent us accidentally triggering browser navigation when scrolling beyond either edge of the scrolly-rail container. scroll-snap-type enforces mandatory scroll snapping. Smooth scrolling behavior applies when items scroll into view on button click, or if interactive elements (links, buttons, etc.) inside items overflowing the visible scroll area are focused. Finally, scroll-snap-align: start should be set on the elements that will snap into place. This snap position aligns an item to the beginning of the scroll snap container. In the above HTML, this would apply to the <li> elements. scrolly-rail li { scroll-snap-align: start; } As mentioned earlier, this is everything our component needs for layout, inline scrolling, and scroll snapping. Note that the CodePen demo takes it a step further with some additional padding and margin styles (check out the demo CSS panel). However, if we'd like to wire up controls, we'll need to include the custom element script in our HTML. The custom element script Include the script file on the page. <script type="module" src="scrolly-rail.js"></script> To connect the previous/next button elements, give each an id value and add these values to the data-control-* attributes on the custom tag. <scrolly-rail data-control-previous="btn-previous" data-control-next="btn-next" > <!-- ... --> </scrolly-rail> <button id="btn-previous" class="btn-scrolly-rail">Previous</button> <button id="btn-next" class="btn-scrolly-rail">Next</button> Now clicking these buttons will pull the previous or next set of items into view. The amount of items to scroll by is based on how many are fully visible in the scroll container. For example, if we see three visible items, clicking the "next" button will scroll the subsequent three items into view. Observing inline scroll bounds Notice that the "previous" button element in the demo's top component. As we begin to scroll to the right, the button appears. Scrolling to the end causes the "next" button to disappear. Similarly, for the bottom component we can see either button fade when their respective scroll bound is reached. Recall the sentinels discussed earlier in this post? With a little help from the Intersection Observer API, the component watches for either sentinel intersecting the visible scroll area, indicating that we've reached a boundary. When this happens, a data-bound attribute is toggled on the respective button. This presents the opportunity to alter styles and provide additional visual feedback. .btn-scrolly-rail { /** default styles */ } .btn-scrolly-rail[data-bound] { /* styles to apply to button at boundary */ } Future improvements I'd love to hear from the community most specifically on improving the accessibility story here. Here are some general notes: I debated if button clicks should pass feedback to screen readers such as "Scrolled next three items into view" or "Reached scroll boundary" but felt unsure if that created unforeseen confusion. For items that contain interactive elements: If a new set of items scroll into view and a user tabs into the item list, should the initial focusable element start at the snap target? This could pair well with navigating the list using keyboard arrow keys. Is it worth authoring intersecting sentinel "enter/leave" events that we can listen for? Something like: Scroll bound reached? Do a thing. Leaving scroll bound? Revert the thing we just did or do another thing. Side note: prevent these events from firing when the component script initializes. How might this code get refactored once scroll snap events are widely available? I imagine we could check for when the first or last element becomes the snap target to handle toggling data-bound attributes. Then we can remove Intersection Observer functionality. And if any folks have other scroll component solutions to share, please reach out or open an issue on the repo.
Over the last few months or so, I have been fairly consistent with getting outside for Sunday morning runs. A series of lower body issues had prevented me from doing so for many years, but it was an exercise I had enjoyed back then. It took time to rebuild that habit and muscle but I finally bested the behavior of doing so begrudgingly. Back in the day (what a weird phrase to say, how old am I?) I would purchase digital copies of full albums. I'd use my run time to digest the songs in the order the artist intended. Admittedly, I've become a lazy listener now, relying on streaming services to surface playlists that I mindlessly select to get going. I want to be better than that, but that's a story for another time. These days, my mood for music on runs can vary: Some sessions I'll pop in headphones and throw on some tunes, other times I head out free of devices (besides a watch to track all those sweet, sweaty workout stats) and simply take in the city noise. Before I headed out for my journey this morning, a friend shared a track from an album of song covers in tribute to The Refused's The Shape Of Punk To Come. The original is a treasured classic, a staple LP from my younger years, and I can still remember the feeling of the first time it struck my ears. Its magic is reconjured every time I hear it. When that reverb-soaked feedback starts on Worms of the Senses / Faculties of the Skull, my heart rate begins to ascend. The anticipation builds, my entire body well aware of the explosion of sound imminent. As my run began, I wasn't sure if I had goosebumps from the morning chill or the wall of noise about to ensue. My legs were already pumping. I was fully present, listening intently, ready for the blast. The sound abruptly detonated sending me rocketing down the street towards the rising sun. My current running goal is 4-in-40, traversing four miles under forty minutes. I'm certainly no Prefontaine, but it's a fair enough objective for my age and ability. I'll typically finish my journey in that duration or slightly spill over the forty-minute mark. Today was different. Listening to The Shape Of Punk To Come sent me cruising an extra quarter mile beyond the four before my workout ended. The unstoppable energy from that album is truly pure runner's fuel. There's certainly some layer of nostalgia, my younger spirit awakened and reignited by thrashing guitars and frantic rhythms, but many elements and themes on this record were so innovative at the time it was released. New Noise is a prime example that executes the following feeling flawlessly: Build anticipation, increase the energy level, and then right as the song seems prepped to blast off, switch to something unexpected. In this case, the guitars drop out to make way for some syncopated celestial synths layered over a soft drum rhythm. The energy sits in a holding pattern, unsure whether it should burst or cool down, when suddenly— Can I scream?! Oh my goodness, yes. Yes you can. I quickly morphed into a runner decades younger. I had erupted, my entire being barreling full speed ahead. The midpoint of this track pulls out the same sequence of build up, drop off, and teasing just long enough before unleashing another loud burst of noise, driving to its explosive outro. As the song wraps up, "The New Beat!" is howled repeatedly to a cheering crowd that, I would imagine, had not been standing still. I definitely needed a long stretch after this run.
I recently stumbled on a super cool, well-executed hover effect from the clerk.com website where a bloom of tiny pixels light up, their glow staggering from the center to the edges of its container. With some available free time over this Thanksgiving break, I hacked together my own version of a pixel canvas background shimmer. It quickly evolved into a pixel-canvas Web Component that can be enjoyed in the demo below. The component script and demo code have also been pushed up to a GitHub repo. Open CodePen demo Usage Include the component script and then insert a pixel-canvas custom element inside the container it should fill. <script type="module" src="pixel-canvas.js"></script> <div class="container"> <pixel-canvas></pixel-canvas> <!-- other elements --> </div> The pixel-canvas stretches to the edges of the parent container. When the parent is hovered, glimmering pixel fun ensues. Options The custom element has a few optional attributes available to customize the effect. Check out the CodePen demo's html panel to see how each variation is made. data-colors takes a comma separated list of color values. data-gap sets the amount of space between each pixel. data-speed controls the general duration of the shimmer. This value is slightly randomized on each pixel that, in my opinion, adds a little more character. data-no-focus is a boolean attribute that tells the Web Component to not run its animation whenever sibling elements are focused. The animation runs on sibling focus by default. There's likely more testing and tweaking necessary before I'd consider using this anywhere, but my goal was to run with this inspiration simply for the joy of coding. What a mesmerizing concept. I tip my hat to the creative engineers over at Clerk.
More in design
The next evolution of personal computing won’t replace your phone — it will free computing from any single device. Like most technologists of a certain age, many of my expectations for the future of computing were set by Star Trek production designers. It’s quite easy to connect many of the devices we have today to props designed 30-50 years ago: The citizens of the Federation had communicators before we had cellphones, tricorders before we had smartphones, PADDs before we had tablets, wearables before the Humane AI pin, and voice interfaces before we had Siri. You could easily make a case that Silicon Valley owes everything to Star Trek. But now, there seems to be a shared notion that the computing paradigm established over the last half-century has run its course. The devices all work well, of course, but they all come with costs to culture that are worth correcting. We want to be more mobile, less distracted, less encumbered by particular modes of use in certain contexts. And, it’s also worth pointing out that the creation of generative AI has made the corporate shareholders ravenous for new products and new revenue streams. So whether we want them or not, we’re going to get new devices. The question is, will they be as revolutionary as they’re already hyped up to be? I’m old enough to remember the gasping “city-changing” hype of the Segway before everyone realized it was just a scooter with a gyroscope. But in fairness, there was equal hype to the iPhone and it isn’t overreaching to say that it remade culture even more extensively than a vehicle ever could have. So time will tell. I do think there is room for a new approach to computing, but I don’t expect it to be a new device that renders all others obsolete. The smartphone didn’t do that to desktop or laptop computers, nor did the tablet. We shouldn’t expect a screenless, sensor-ridden device to replace anyone’s phone entirely, either. But done well, such a thing could be a welcome addition to a person’s kit. The question is whether that means just making a new thing or rethinking how the various computers in our life work together. As I’ve been pondering that idea, I keep thinking back to Star Trek, and how the device that probably inspired the least wonder in me as a child is the one that seems most relevant now: the Federation’s wearables. Every officer wore a communicator pin — a kind of Humane Pin light — but they also all wore smaller pins at their collars signifying rank. In hindsight, it seems like those collar pins, which were discs the size of a watch battery, could have formed some kind of wearable, personal mesh network. And that idea got me going… The future isn’t a zero-sum game between old and new interaction modes. Rather than being defined by a single new computing paradigm, the future will be characterized by an increase in computing: more devices doing more things. I’ve been thinking of this as a PAC — Personal Ambient Computing. Personal Ambient Computing At its core is a modular component I’ve been envisioning as a small, disc-shaped computing unit roughly the diameter of a silver dollar but considerably thicker. This disc would contain processing power, storage, connectivity, sensors, and microphones. The disc could be worn as jewelry, embedded in a wristwatch with its own display, housed in a handheld device like a phone or reader, integrated into a desktop or portable (laptop or tablet) display, or even embedded in household appliances. This approach would create a personal mesh network of PAC modules, each optimized for its context, rather than forcing every function in our lives through a smartphone. The key innovation lies in the standardized form factor. I imagine a magnetic edge system that allows the disc to snap into various enclosures — wristwatches, handhelds, desktop displays, wearable bands, necklaces, clips, and chargers. By getting the physical interface right from the start, the PAC hardware wouldn’t need significant redesign over time, but an entirely new ecosystem of enclosures could evolve more gradually and be created by anyone. A worthy paradigm shift in computing is one that makes the most use of modularity, open-source software and hardware, and context. Open-sourcing hardware enclosures, especially, would offer a massive leap forward for repairability and sustainability. In my illustration above, I even went as far as sketching a smaller handheld — exactly the sort of device I’d prefer over the typical smartphone. Mine would be proudly boxy with a larger top bezel to enable greater repair access to core components, like the camera, sensors, microphone, speakers, and a smaller, low-power screen I’d depend upon heavily for info throughout the day. Hey, a man can dream. The point is, a PAC approach would make niche devices much more likely. Power The disc itself could operate at lower power than a smartphone, while device pairings would benefit from additional power housed in larger enclosures, especially those with screens. This creates an elegant hierarchy where the disc provides your personal computing core and network connectivity, while housings add context-specific capabilities like high-resolution displays, enhanced processing, or extended battery life. Simple housings like jewelry would provide form factor and maybe extend battery life. More complex housings would add significant power and specialized components. People wouldn’t pay for screen-driving power in every disc they own, just in the housings that need it. This modularity solves the chicken-and-egg problem that kills many new computing platforms. Instead of convincing people to buy an entirely new device that comes with an established software ecosystem, PAC could give us familiar form factors — watches, phones, desktop accessories — powered by a new paradigm. Third-party manufacturers could create housings without rebuilding core computing components. Privacy This vision of personal ambient computing aligns with what major corporations already want to achieve, but with a crucial difference: privacy. The current trajectory toward ambient computing comes at the cost of unprecedented surveillance. Apple, Google, Meta, OpenAI, and all the others envision futures where computing is everywhere, but where they monitor, control and monetize the flow of information. PAC demands a different future — one that leaves these corporate gatekeepers behind. A personal mesh should be just that: personal. Each disc should be configurable to sense or not sense based on user preferences, allowing contextual control over privacy settings. Users could choose which sensors are active in which contexts, which data stays local versus shared across their mesh, and which capabilities are enabled in different environments. A PAC unit should be as personal as your crypto vault. Obviously, this is an idea with a lot of technical and practical hand-waving at work. And at this vantage point, it isn’t really about technical capability — I’m making a lot of assumptions about continued miniaturization. It is about computing power returning to individuals rather than being concentrated in corporate silos. PAC represents ambient computing without ambient surveillance. And it is about computing graduating its current form and becoming more humanely and elegantly integrated into our day to day lives. Next The smartphone isn’t going anywhere. And we’re going to get re-dos of the AI devices that have already spectacularly failed. But we won’t get anywhere especially exciting until we look at the personal computing ecosystem holistically. PAC offers a more distributed, contextual approach that enhances rather than replaces effective interaction modes. It’s additive rather than replacement-based, which historically tends to drive successful technology adoption. I know I’m not alone in imagining something like this. I’d just like to feel more confident that people with the right kind of resources would be willing to invest in it. By distributing computing across multiple form factors while maintaining continuity of experience, PAC could deliver on the promise of ubiquitous computing without sacrificing the privacy, control, and interaction diversity that make technology truly personal. The future of computing shouldn’t be about choosing between old and new paradigms. It should be about computing that adapts to us, not the other way around.
Unlocking the Code of Eastern Beauty in National Tea Where Mountains and Waters Sing in Harmony Nature holds the secrets...
For the past twenty to thirty years, the creative services industry has pursued a strategy of elevating the perceived value of knowledge work over production work. Strategic thinking became the premium offering, while actual making was reframed as “tactical” and “commoditized.” Creative professionals steered their careers toward decision-making roles rather than making roles. Firms adjusted their positioning to sell ideas, not assets — strategy became the product, while labor became nearly anonymous. After twenty years in my own career, I believe this has been a fundamental mistake, especially for those who have so distanced themselves from craft that they can no longer make things. The Unintended Consequences The strategic pivot created two critical vulnerabilities that are now being exposed by AI: For individuals: AI is already perceived as delivering ideas faster and with greater accuracy than traditional strategic processes, repositioning much of what passed for strategy as little better than educated guesswork. The consultant who built their career on frameworks and insights suddenly finds themselves competing with a tool that can generate similar outputs in seconds. For firms: Those who focused staff on strategy and account management while “offshoring” production cannot easily pivot to new means of production, AI-assisted or otherwise. They’ve created organizations optimized for talking about work rather than doing it. The Canary in the Coal Mine In hindsight, the homogeneity of interaction design systems should have been our warning. We became so eager to accept tools that reduced labor — style guides that eliminated design decisions, component libraries that standardized interfaces, templates that streamlined production — that we literally cleared the decks for AI replacement. Many creative services firms now accept AI in the same way an army-less nation might surrender to an invader: they have no other choice. They’ve systematically dismantled their capacity to make things in favor of their capacity to think about things. Now they’re hoping they can just re-boot production with bots. I don’t think that will work. AI, impressive as it is, still cannot make anything and everything. More importantly, it cannot produce things for existing systems as efficiently and effectively as a properly equipped person who understands both the tools and the context. The real world still requires: Understanding client systems and constraints Navigating technical limitations and possibilities Iterating based on real feedback from real users Adapting to changing requirements mid-project Solving the thousand small problems that emerge during implementation These aren’t strategic challenges — they’re craft challenges. They require the kind of deep, hands-on knowledge that comes only from actually making things, repeatedly, over time. The New Premium I see the evidence everywhere in my firm’s client accounts: there’s a desperate need to move as quickly as ever, motivated by the perception that AI has created about the overall pace of the market. But there’s also an acknowledgment that meaningful progress doesn’t come at the push of a button. The value of simply doing something — competently, efficiently, and with an understanding of how it fits into larger systems — has never been higher. This is why I still invest energy in my own craft and in communicating design fundamentals to anyone who will listen. Not because I’m nostalgic for pre-digital methods, but because I believe craft represents a sustainable competitive advantage in an AI-augmented world. Action vs. Advice The fundamental issue is that we confused talking about work with doing work. We elevated advice-giving over action-taking. We prioritized the ability to diagnose problems over the ability to solve them. But clients don’t ultimately pay for insights — they pay for outcomes. And outcomes require action. They require the messy, iterative, problem-solving work of actually building something that works in the real world. The firms and individuals who will thrive in the coming years won’t be those with the best strategic frameworks or the most sophisticated AI prompts. They’ll be those who can take an idea — whether it comes from a human strategist or an AI system — and turn it into something real, functional, and valuable. In my work, I regularly review design output from teams across the industry. I encounter both good ideas and bad ones, skillful craft and poor execution. Here’s what I’ve learned: it’s better to have a mediocre idea executed with strong craft than a brilliant idea executed poorly. When craft is solid, you know the idea can be refined — the execution capability exists, so iteration is possible. But when a promising idea is rendered poorly, it will miss its mark entirely, not because the thinking was wrong, but because no one possessed the skills to bring it to life effectively. The pendulum that swung so far toward strategy needs to swing back toward craft. Not because technology is going away, but because technology makes the ability to actually build things more valuable, not less. In a world where everyone can generate ideas, the people who can execute those ideas become invaluable.
Noise Beer is a collection of craft and dark beers whose visual identity is inspired by the noise music genre...
Many Grids I’ve been making very small collages, trying to challenge myself to create new patterns and new ways of connecting form and creating space. Well, are we? The last page in a book I started last year.