More from Jim Nielsen’s Blog
I’m currently looking to add a search feature to my blog. It’s a client-side approach, which means I was planning on using my favorite progressive-enhancement technique for client-side only search: you point a search form at Google, scope the results to your site, then use JavaScript to intercept the form submission and customize the experience on your site to your heart’s content. <form action="https://www.google.com/search"> <input type="text" name="q" placeholder="Search" /> <input type="hidden" name="as_sitesearch" value="blog.jim-nielsen.com" /> <button type="submit">Search</button> </form> <script> document.querySelector("form").addEventListener("submit", (e) => { e.preventDefault(); // Do my client-side search stuff here // and stay on the current page }); </script> However, then I remembered that Google Search no longer works without JavaScript which means this trick is no longer a trick. [1] But have no fear, other search engines to the rescue! DuckDuckGo, for example, supports this trick. Tweak some of the HTML from the Google example and it’ll work: <form action="https://duckduckgo.com"> <input type="text" name="q" placeholder="Search" /> <input type="hidden" name="sites" value="blog.jim-nielsen.com" /> <button type="submit">Search</button> </form> <script> document.querySelector("form").addEventListener("submit", (e) => { e.preventDefault(); // Do my client-side search stuff here // and stay on the current page }); </script> Yahoo also supports this trick, but not Bing. You can point people at Bing, but you can’t scope a query to your site only with an HTML form submission alone. Why? Because you need two search params: 1) a “query” param representing what the user typed into the search box, and 2) a “site search” param to denote which site you want to limit your results to (otherwise it’ll search the whole web). From a UI perspective, if a search box is on your site, user intent is to search the content on your site. You don’t want to require people to type “my keywords site:blog.jim-nielsen.com” when they’re using a search box on your site — that’s just silly! That’s why you need a second search parameter you can set yourself (a hidden input). You can’t concatenate something onto the end of a user’s HTML form submission. (What they type in the input box is what gets sent to the search engine as the ?q=... param.) To add to the q param, you would need JavaScript — but then that defeats the whole purpose of this exercise in the first place! Anyhow, here are the search parameters I found useful for search engines that will support this trick: DuckDuckGo: Query: q Site search param: sites Yahoo Query: p Site search param: vs I made myself a little test page for trying all these things. Check it out (and disable JS) if you want to try yourself! Not only that, but the as_sitesearch search param doesn’t seem to work anymore either. I can’t find any good documentation on what happened to as_sitesearch, but it seems like you’re supposed to use the “programmable search” now instead? Honestly I don’t know. And I don’t care enough to find out. ⏎ Email :: Mastodon :: Bluesky #progressiveEnhancement
Hidde de Vries gave a great talked titled “Creativity cannot be computed” (you can checkout the slides or watch the video). In his slides he has lots of bullet points that attempt to define what art is, and then in the talk he spends time covering each one. Here’s a sampling of the bullet points: Art isn't always easy to recognize Art has critics Art is fuzzy Art can make us think Art can make the artist think Art can make the audience think Art can show us a mirror to reflect Art can move us Art can take a stance Art can be used to show solidarity Art can help us capture what it's like to be another person I love all his bullet points. In fact, they got me thinking about websites. I think you could substitute “website” for “art” in many of his slides. For example: Art is repeated So are websites. Think of all those websites that follow the same template. Art may contain intentions Like the intent to purposely break best practices. Art can show us futures we should not want Or the present we currently have. Art doesn’t have to fit in You can make any kind of website. It gives you agency to respond to the world the way you want, not just by “liking” something on social media. Me personally, I’ve made little websites meant to convey my opinion on social share imagery or reinforce the opinion I share with others on the danger of normalizing breakage on the web. Each of those could’ve been me merely “liking” someone else’s opinion. Or I could’ve written a blog post. Or, as in those cases, I instead made a website. Art can insult the audience It doesn’t have to make you happy. Its purpose can be to offend you, or make you outraged and provoke a response. It can be a mother fucking website. Of course, as Hidde points out, a website doesn’t have to be all of these. It also doesn’t have to be any of these. Art — and a website — is as much about the artist and the audience as it is about the artifact. It’s a reflection of the person/people making it. Their intentions. Their purpose. How’d you make it? Why’d you make it? When’d you make it? Each of these threads run through your art (website). So when AI lets you make a website with the click of a button, it’s automating away a lot of the fun art stuff that goes into a website. The part where you have to wrestle with research, with your own intentions and motivations, with defining purpose, with (re)evaluating your world view. Ultimately, a website isn’t just what you ship. It’s about who you are — and who you become — on the way to shipping. So go explore who you are. Plumb the bottomless depths of self. Make art, a.k.a make a website. Email :: Mastodon :: Bluesky
Quoting myself from former days on Twitter: Businesses have a mental model of what they do. Businesses build software to help them do it—a concrete manifestation of their mental model. A gap always exists between these two. What makes a great software business is their ability to keep that gap very small. I think this holds up. And I still think about this idea (hence this post). Software is an implementation of human understanding — people need X, so we made Y. But people change. Businesses change. So software must also change. One of your greatest strengths will be your ability to adapt and evolve your understanding of people’s needs and implement it in your software. In a sense, technical debt is the other side of this coin of change: an inability to keep up with your own metamorphosis and understanding. In a way, you could analogize this to the conundrum of rocket science: you need fuel to get to space, but the more fuel you add, the more weight you add, and the more weight you add, the more fuel you need. Ad nauseam. It’s akin to making software. You want to make great software for people’s needs today. It takes people, processes, and tools to make software, but the more people, processes, and tools you add to the machine of making software, the less agile you become. So to gain velocity you add more people, processes, and tools, which…you get the idea. Being able to build and maintain pliable software that can change and evolve at the same speed as your mental model is a superpower. Quality in code means the flexibility to change. Email :: Mastodon :: Bluesky
A friend gave me a copy of the book “Perfect Wave” by Dave Hickey. I’ve been slowly reading through each essay and highlighting parts with my red pencil. When I got to the chapter “Cool on Cool”, this passage stood out. I want to write it down and share it: there was this perfect, luminous pop single by the Carpenters that just blew me away. And, believe me, the Carpenters were the farthest thing from my kind of thing. But when something that is not your thing blows you away, that’s one of the best things that can happen. It means you are something more and something other than you thought you were. I find this beautiful. I should take more time to wonder at moments of surprise I did not expect. What a beautiful thing that I can be plowing through my existence and suddenly be surprised by something outside my taste, my beliefs, even my identity, that reaches in past all those things and rearranges me. Perhaps my boundaries are more porous than I assume. In an instant, I can become something different, something more that I ever believed was possible. Just think, that ability is lying there inside all of us. I don’t have to think of myself as a walled garden but an open field. Who knows where my boundaries will expand to next. All it takes is someone walking by and tossing out a seed I would’ve never chosen to plant myself. (Tangential: I love this interaction between Jerry Seinfeld and Brian Regan talking about being “blown away”.) Email :: Mastodon :: Bluesky
Jeremy Keith, Chris Coyier, and others (see Jeremy’s post) have written about the idea of “pace layers” and now I’m going to take a stab at applying it to user interface primitives. First, let’s start with a line of reasoning: Common user interface controls — such as checkboxes or radios — should be visually and functionally consistent. This provides users a uniform, predictable interface for common interactions across various applications (turning things on/off, selecting an option from a pre-defined list, etc.). Designers and developers should use the primitives afforded by the lower-levels they’re building on. This gives application and web site users a consistent, predictable interface within their context and environment. For web designers, every person accessing your site has a particular piece of hardware with a particular operating system and design language to boot. You can build on top of those primitives, rather than re-create them yourself, which gives end users consistency within their chosen environment. For example, a radio button on one website or in one native app is the same radio button on another website or in another app. (Rather than every single website and application rolling their own radios that might be identical, similar, or drastically different.) To achieve this, user interfaces can be built in “layers” where each layer builds on top of the layer below it, providing a level of integration and consistency within its environment. And, where lower levels don’t provide primitives necessary for a user interface, designers and developers can create their own. In this world, individual websites are free to explore patterns and interactions which don’t yet exist (or are only half-implemented by lower layers). However, where a lower-level dependency exists, they can leverage it which gives end users a more consistent experience in their chosen environment while also giving designers and developers more time to focus on building UI controls and patterns that don’t yet exist. UI Primitives We Build Ourselves Are a Liability Every UI control you roll yourself is a liability. You have to design it, test it, ship it, document it, debug it, maintain it — the list goes on. It makes you wonder why we insist on rolling (or styling) our own common UI controls so often. Perhaps we’d be better off asking: What are the fewest amount of components we have to build to deliver value to our users? When creating user interfaces, you can leverage the existing controls and patterns of the layers you’re building on top of. This helps you build, maintain, and debug less because you’re using primitives built and maintained by the makers of levels below you (which are generally more stable and change less). And it helps your users because the experience of your app or website is more consistent and predictable within whatever particular hardware and operating system they’re using. Adopting UI Primitives: Addition or Subtraction When designers and developers set out to create a user interface, they have to ask themselves: Are we going to use something that already exists, or create our own? When you use a checkbox or radio control, are you adopting those controls by 1) leveraging existing APIs of lower-level layers, or 2) re-implementing them yourself? Approach (1) makes it easier for you to maintain and easier for your users to use, as it’s a pattern consistent with the shared language and functionality of their bespoke computing experience. Approach (2) does neither of these. It’s more work for you to build and maintain, and it’s more cognitive work for your users to learn yet another visual and functional variant of an otherwise standard UI primitive. An Example: The Switch Control For a long time, a checkbox was all you had on the web. So people built their own “switch” controls. Eventually, browsers got around to providing an API to the existing switch control of lower-level systems. So the question for many websites and design systems became: Do we adopt the switch control that the browser (and lower-level layers) now provide us? Or do we keep our hand-rolled switch? In this sense, there are two approaches to building a design system: Build everything that’s needed. Build only what is not already provided by lower layers (and trade variance in your system for consistency in your users’ systems). In approach (1) you build and maintain everything yourself. In approach (2) you build what isn’t provided and you maintain by deleting previous implementations now provided by lower layers. Priority Says: Brands > People In a world of layers built on top of each other, you would see updates to UI primitives change in lower levels and “bubble up” to websites. OS -> Native -> Browser -> Website -> Form control However, the world we’ve constructed with many of our websites and design systems is outside of this flow of updates. There’s the OS-level stuff: OS -> Native -> Browser And then tangential to that stream of updates is this flow, which requires manual intervention and updates: Design system -> Website -> Form control For example, if the OS changes its radios, websites only get those updates if individual design system and website owners decide to pick up those changes, leaving users’ experiences inconsistent in their chosen computing environment. In other words, the UI layering of operating systems and websites diverge from each other. We opt to make the experience of our brands primary over the users’. Whereas we could be choosing to make our brands fit into users' choices. But then we’d have to value honoring user choice over brand consistency, and I just don’t know if the world is ready for that because brands pay the bills. Email :: Mastodon :: Bluesky
More in design
We will never agree about AI until we agree about what it means to live a good life. Current debates* about artificial intelligence circle endlessly around questions of capability, economic impact, and resource allocation – not to mention language. Is AI truly useful? What will it do to jobs? How much should we invest in its development? And what do we mean by AI? What’s the difference between machine learning and large language modeling? What can one do that the other cannot? What happens when we mix them up? These discussions are necessary, but will continue to be maddening without backing up some and widening the scope. Meanwhile, it often feels like we’re arguing about the objective merit of a right-hand turn over a left without first agreeing where we’re trying to go. The real questions about AI are actually questions about human flourishing. How much of a person’s life should be determined by work? What level of labor should be necessary to meet basic needs? Where do we draw the line between necessity and luxury? How should people derive contentment and meaning? Without wrestling with these fundamental questions, our AI debates are just technical discussions floating free of human context. Consider how differently we might approach AI development if we had clear answers about what constitutes a good human life. If we believed that meaningful work is essential to human flourishing, we’d focus the development of AI on human augmentation while being vigilant of how it might replace human function. We’d carefully choose how it is applied, leveraging machine-learning systems to analyze datasets beyond our comprehension and move scientific investigations forward, but withhold its use in areas that derive value from human creativity. If we thought that freedom from labor was the path to human fulfillment, we’d push AI toward maximum automation and do the work of transitioning from a labor and resource-driven capitalist system to a completely different structure. We would completely remake the world, starting with the lives of those who inhabit it. But without this philosophical foundation, we’re left with market forces, technological momentum, and environmental pressures shaping our future by default. The details of human life become outputs of these systems rather than conscious choices guided by shared values. As abstract as this may sound, it is as essential as any technical detail that differentiates one model from another. Every investment in AI derives from a worldview which, at best, prefers maintaining the structural status quo, or at worst, desires a further widening of the gap between economic power and poverty. Every adoption layer of large language models reinforces the picture of society drawn by just one piece of it — the internet — and as dependence upon these systems increases, so does the reality distortion. The transition from index-driven search engines to AI-driven research engines reaches a nearly gaslight level of affirming a certain kind of truth; a referral, after all, is a different kind of truth-builder than an answer. And though both systems draw from exactly the same information, one will persuade its users more directly. Its perception will be reality. Unless, of course, we say otherwise. We’re building the infrastructure of future human experience without explicitly discussing what that experience should be. To be sure, many humans have shared worldviews. Some are metaphysical in nature, if not explicitly religious. Some are maintained independent of economic and technological forces, if not in direct rejection of them. Among the many pockets of human civilization rooted in pre-digital traditions, the inexorable supremacy of AI likely looks like an apocalypse they’d prefer to avoid. I am not saying we all must live and believe as others do. A shared picture of human flourishing does not require a totalitarian trickle-down demand on every detail of day-to-day life. But it must be defined enough to help answer questions, particularly about technology, that are relevant to anyone alive. The most urgent conversation about AI isn’t about its capabilities or risks, but about the kind of life we want it to help us create. Until we grapple with these deeper questions about human flourishing, our technical debates will continue to miss the point and further alienate us from one another. This from Robin Sloan vs. this from Baldur Bjarnason vs. this from Michelle Barker, for example. All thoughtful, offering nuance and good points, but also missing one another.
Stoked Associates redefines workplace design with a human-centric approach, blending local graphics, biophilic elements, and smart solutions to create a...
I’m currently looking to add a search feature to my blog. It’s a client-side approach, which means I was planning on using my favorite progressive-enhancement technique for client-side only search: you point a search form at Google, scope the results to your site, then use JavaScript to intercept the form submission and customize the experience on your site to your heart’s content. <form action="https://www.google.com/search"> <input type="text" name="q" placeholder="Search" /> <input type="hidden" name="as_sitesearch" value="blog.jim-nielsen.com" /> <button type="submit">Search</button> </form> <script> document.querySelector("form").addEventListener("submit", (e) => { e.preventDefault(); // Do my client-side search stuff here // and stay on the current page }); </script> However, then I remembered that Google Search no longer works without JavaScript which means this trick is no longer a trick. [1] But have no fear, other search engines to the rescue! DuckDuckGo, for example, supports this trick. Tweak some of the HTML from the Google example and it’ll work: <form action="https://duckduckgo.com"> <input type="text" name="q" placeholder="Search" /> <input type="hidden" name="sites" value="blog.jim-nielsen.com" /> <button type="submit">Search</button> </form> <script> document.querySelector("form").addEventListener("submit", (e) => { e.preventDefault(); // Do my client-side search stuff here // and stay on the current page }); </script> Yahoo also supports this trick, but not Bing. You can point people at Bing, but you can’t scope a query to your site only with an HTML form submission alone. Why? Because you need two search params: 1) a “query” param representing what the user typed into the search box, and 2) a “site search” param to denote which site you want to limit your results to (otherwise it’ll search the whole web). From a UI perspective, if a search box is on your site, user intent is to search the content on your site. You don’t want to require people to type “my keywords site:blog.jim-nielsen.com” when they’re using a search box on your site — that’s just silly! That’s why you need a second search parameter you can set yourself (a hidden input). You can’t concatenate something onto the end of a user’s HTML form submission. (What they type in the input box is what gets sent to the search engine as the ?q=... param.) To add to the q param, you would need JavaScript — but then that defeats the whole purpose of this exercise in the first place! Anyhow, here are the search parameters I found useful for search engines that will support this trick: DuckDuckGo: Query: q Site search param: sites Yahoo Query: p Site search param: vs I made myself a little test page for trying all these things. Check it out (and disable JS) if you want to try yourself! Not only that, but the as_sitesearch search param doesn’t seem to work anymore either. I can’t find any good documentation on what happened to as_sitesearch, but it seems like you’re supposed to use the “programmable search” now instead? Honestly I don’t know. And I don’t care enough to find out. ⏎ Email :: Mastodon :: Bluesky #progressiveEnhancement
The packaging design for Vita-Care vitamin tablets was developed with the aim of attracting more attention from the target audience....
This is the second part of a series on the identity of social networks: