Articles on Smashing Magazine — For Web Designers And Developers

A Practical Guide To Design Principles

<p>We often see design principles as rigid guidelines that dictate design decisions. But actually, they are an incredible tool to <strong>rally the team around a shared purpose</strong> and document the values and beliefs that an organization embodies.</p> <p>They align teams and inform decision-making. They also keep us afloat amidst all the hype, big assumptions, desire for faster delivery, and AI workslop. But how do we choose the right ones, and how do we get started? Let’s find out.</p> Real-World Design Principles <p>In times when we can generate any passable design and code within minutes, we need to decide better <strong>what’s worth designing and building</strong> — and what values we want our products to embody.</p> <p>It’s similar to voice and tone. You might not design it intentionally, but then end users will define it for you. And so, without principles, many company initiatives are <strong>random, sporadic, ad-hoc</strong> — and feel vague, inconsistent, or simply dull to the outside world.</p> <p><strong>Design principles</strong> are guidelines and design considerations that <a href="https://ixdf.org/literature/topics/design-principles">designers apply with discretion</a> — by default, without debating or discussing what has already been agreed upon.</p> <p>One fantastic resource that I keep coming back to after all these years is Ben Brignell’s <a href="https://principles.design/">Principles.design</a>. It has <strong>230 pointers for design principles and methods</strong>, searchable and tagged, covering everything from language and infrastructure to hardware and organizations.</p> 10 Principles Of Good Design <p>There is no shortage of principles out there. But the good ones are more than just being <em>visionary</em> — they <strong>have a point of view</strong>, and they explain what we <em>don’t do</em> as much as what we do. They also explain what <strong>we stand for</strong> in the world — beyond profits, stock prices, and all the hype and noise around us.</p> <p><img src="https://files.smashing.media/articles/stop-endless-debates-design-principles/1-principles-good-design.jpg"></p> <p>Many years ago, I encountered <a href="https://www.vitsoe.com/gb/about/good-design#good-design-is-innovative">Dieter Rams’ 10 principles of good design</a> (see above), a very <strong>humble, practical and tangible</strong> overview of principles that were informing, shaping, and guarding his design work at Braun.</p> <p>There are <strong>no visionary claims</strong>, and no big bold statements: just a clear overview of what we do, and where our ambition and care lie for the products we are designing. It’s honest, sincere, and in many ways beautifully <strong>humane</strong>.</p> <h3>Examples Of Design Principles</h3> <p>There are plenty of <strong>wonderful examples</strong> that I keep close:</p> <ul> <li><a href="https://www.anthropic.com/constitution">Anthropic’s Constitution</a></li> <li> <a href="https://principles.design/examples/principles-of-product-design">Principles of Product Design</a>, by Joshua Porter</li> <li> <a href="https://principles.design/examples/20-guiding-principles-for-experience-design">Guiding Principles for Experience Design</a>, by Whitney Hess, PCC</li> <li> <a href="https://github.com/Heydon/principles-of-web-accessibility">Principles of Web Accessibility</a>, by Heydon Pickering</li> <li> <a href="https://humanebydesign.com/">Humane by Design</a>, by Jon Yablonski</li> <li> <a href="https://principles.design/examples/designing-for-voice-interfaces">Designing Voice UX Principles</a>, by Brian Colcord</li> <li> <a href="https://linear.app/developers/aig">Agentic Design Principles</a>, by Linear</li> <li> <a href="https://www.intercom.com/blog/principles-bot-design/">AI Chatbot Design Principles</a>, by Emmet Connolly</li> <li> <a href="https://voiceprinciples.com/">Voice UX Principles</a>, by Ben Sauer</li> </ul> <h3>Design Principles In Design Systems</h3> <ul> <li><a href="https://guides.18f.org/">18F</a></li> <li><a href="https://styleguide.audi.com/document/2440#/-/experience-principles">Audi</a></li> <li><a href="https://www.ibm.com/design/language/philosophy/principles/">Carbon (IBM)</a></li> <li><a href="https://acorn.firefox.com/latest/get-started/firefox-design-principles-5ezPvNdo">Firefox</a></li> <li><a href="https://www.gov.uk/guidance/government-design-principles">Gov.uk</a></li> <li><a href="https://contentdesign.intuit.com/style-and-usage/our-principles/">Intuit</a></li> <li><a href="https://service-manual.nhs.uk/design-system/design-principles">NHS</a></li> <li><a href="https://nordhealth.design/principles/">Nordhealth</a></li> <li><a href="https://base.uber.com/6d2425e9f/p/434f39-principles">Uber</a></li> </ul> How To Establish Design Principles <p>Design principles can be personal, but usually they are committed to and shaped by the <strong>entire product team</strong>. Design principles <strong>aren’t just for designers</strong>. User’s experience is <em>everything</em> from performance to support to customer service, and ideally, participants would cover these areas as well.</p> <p>In practice, though, establishing principles might feel incredibly challenging. They are abstract and fluffy and often ambiguous, and often very difficult to agree upon.</p> <p><img src="https://files.smashing.media/articles/stop-endless-debates-design-principles/2-design-principles-workshop.png"></p> <p>You can get started with a <strong>simple 8-step workshop</strong> (inspired by <a href="https://medium.com/@marcintreder/design-system-sprint-4-design-principles-8efb22d8a208">Marcin Treder</a>, <a href="https://medium.com/design-bootcamp/design-principles-workshop-a-template-15c7c90458f2">Maria Meireles</a> and <a href="https://www.better.care/blog-en/establishing-design-principles-for-a-design-system-and-what-it-taught-us/">Better</a>):</p> <ol> <li> <strong>Pre-session Research</strong><br>Study how users speak about the products, what they appreciate, and the words they use.</li> <li> <strong>Get Into Principles Mode</strong><br>Invite 6–8 participants, ask them to choose their favorite object, and describe it in 3 words.</li> <li> <strong>Product Analogies</strong><br>Compare product to tangible items (e.g., ‘A Porsche 911’ or ‘a Braun audio system’).</li> <li> <strong>Extract Attributes</strong><br>Individually, in silence, everyone writes 3–5 initial principles, which are then grouped by theme for review.</li> <li> <strong>Link Attributes To Research</strong><br>Link attributes to actual user pain points or desires, to make sure they are grounded in reality.</li> <li> <strong>Value Statements</strong><br>We write <em>‘We want X because of Y’</em> sentences that express the rationale behind our thinking.</li> <li> <strong>Move to Principles</strong><br>Remove analogies to create enduring rules that will guide our design process.</li> <li> <strong>Reality Check</strong><br>Search for both positive and negative examples in our products to see where principles are being met or ignored.</li> </ol> <p><img src="https://files.smashing.media/articles/stop-endless-debates-design-principles/3-design-principles.jpg"></p> <h3>Useful Starter Kits For Principles Workshops</h3> <ul> <li> <a href="https://medium.com/design-bootcamp/design-principles-workshop-a-template-15c7c90458f2">Design Principles Workshop (Figma Template)</a>, by Maria Meireles</li> <li> <a href="https://www.figma.com/community/file/1051212964426062558">Design Principles Workshop (FigJam Template)</a>, by Richard Picot</li> <li> <a href="https://miro.com/templates/design-principles-workshop/">How to Create Design Principles (Miro Workshop Template)</a>, by NanoGiants</li> </ul> Wrapping Up <p>Creating principles is only a small portion of the work; most work is about <strong>effectively sharing and embedding them</strong>. It’s difficult to get anywhere without finding ways to <strong>make design principles a default</strong> — by revisiting settings, templates, naming conventions, and output.</p> <p>Principles help <strong>avoid endless discussions</strong> that often stem from personal preferences or taste. But design should not be a matter of taste; it must be guided by our goals and values. Design principles can help with just that.</p> Meet “Design Patterns For AI Interfaces” <p>Meet <a href="https://ai-design-patterns.com/"><strong>Design Patterns For AI Interfaces</strong></a>, Vitaly’s new <strong>video course</strong> with 100s of real-life examples and UX guidelines to design AI features that people actually use — with a <a href="https://smashingconf.com/online-workshops/workshops/ai-interfaces-vitaly-friedman/">live UX training</a> later this year. <a href="https://www.youtube.com/watch?v=jhZ3el3n-u0">Jump to a free preview</a>.</p> <p></p> <a href="https://ai-design-patterns.com/"><img src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/product-designer-career-paths/design-patterns-ai-interfaces.png"></a>Meet <a href="https://ai-design-patterns.com/">Design Patterns For AI Interfaces</a>, Vitaly’s video course on interface design &amp; UX.<p></p> <div><div> <ul> <li><a href="https://www.smashingmagazine.com/#"> Video + UX Training</a></li> <li><a href="https://www.smashingmagazine.com/#">Video only</a></li> </ul> <div> <h3>Video + UX Training</h3>$ 450.00 $ 799.00 <a href="https://smart-interface-design-patterns.thinkific.com/enroll/3476562?price_id=4401578"> Get Video + UX Training<div></div></a><p>30 video lessons (10h) + <a href="https://smashingconf.com/online-workshops/workshops/ai-interfaces-vitaly-friedman/">Live UX Training</a>.<br>100 days money-back-guarantee.</p> </div> <div> <h3>Video only</h3> <div>$ 275.00$ 395.00</div> <a href="https://smart-interface-design-patterns.thinkific.com/enroll/3476562?price_id=4397456"> Get the video course<div></div></a><p>30 video lessons (10h). Updated yearly.<br>Also available as a <a href="https://smart-interface-design-patterns.thinkific.com/enroll/3570306?price_id=4503439">UX Bundle with 3 video courses.</a></p> </div> </div></div> Useful Resources <ul> <li> <a href="https://principles.design/">Design Principles Collection</a>, by Ben Brignell</li> <li>“<a href="https://medium.com/@marcintreder/design-system-sprint-4-design-principles-8efb22d8a208">How To Establish Design Principles</a>”, by Marcin Treder</li> <li>“<a href="https://www.better.care/blog-en/establishing-design-principles-for-a-design-system-and-what-it-taught-us/">Establishing Design Principles for a Design System and What It Taught Us</a>”, by Better Design Team</li> <li> <a href="https://principles.adactio.com/">Design Principles</a>, by Jeremy Keith</li> <li> <a href="https://www.designprinciplesftw.com/">Design Principles Collection</a>, by Gabriel Svennerberg</li> <li> <a href="https://medium.com/design-bootcamp/design-principles-workshop-a-template-15c7c90458f2">Design Principles Workshop (Figma Template)</a>, by Maria Meireles</li> <li> <a href="https://www.figma.com/community/file/1051212964426062558">Design Principles Workshop (FigJam Template)</a>, by Richard Picot</li> <li> <a href="https://miro.com/templates/design-principles-workshop/">How to Create Design Principles (Miro Workshop Template)</a>, by NanoGiants</li> <li><a href="https://designsystems.surf/components/modal">Modals in Design Systems</a></li> </ul>

The Joy Of A Fresh Beginning (April 2026 Wallpapers Edition)

<p>Starting the new month with a little inspiration boost — that’s the idea behind our <a href="https://www.smashingmagazine.com/category/wallpapers">monthly wallpapers series</a> which has been going on for more than 15 years already. Each month, the wallpapers are <strong>created by the community for the community</strong>, and everyone who has an idea for a design is welcome to <a href="https://www.smashingmagazine.com/desktop-wallpaper-calendars-join-in/">join in</a> — experienced designers just like aspiring artists.</p> <p>For this edition, creative folks from across the globe once again got their ideas flowing and designed desktop wallpapers that are sure to <strong>bring some good vibes to your screens</strong>. You’ll find them compiled below, ready to be downloaded in a variety of screen resolutions. A huge thank-you to everyone who shared their designs with us — you’re truly <em>smashing</em>!</p> <p>If <em>you</em> too would like to <strong>get featured</strong> in one of our upcoming posts, please don’t hesitate to <a href="https://www.smashingmagazine.com/desktop-wallpaper-calendars-join-in/">submit your wallpaper</a>. We can’t wait to see what you’ll come up with! Happy April!</p> <ul> <li>You can <strong>click on every image to see a larger preview</strong>.</li> <li>We respect and carefully consider the ideas and motivation behind each and every artist’s work. This is why we give all artists the <strong>full freedom to explore their creativity</strong> and express emotions and experience through their works. This is also why the themes of the wallpapers weren’t anyhow influenced by us but rather designed from scratch by the artists themselves.</li> </ul> April Blooms <p>“The search for colorful Easter eggs comes at just the right time. After long winter months of searching for sunlight and meaning, April blooms have never been more welcome.” — Designed by <a href="https://www.gingeritsolutions.com/">Ginger It Solutions</a> from Serbia.</p> <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/apr-26-april-blooms-full.png"><img src="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2026/apr-26-april-blooms-preview-opt.png"></a> <ul> <li><a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/apr-26-april-blooms-preview.png">preview</a></li> <li>with calendar: <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-320x480.png">320x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-640x480.png">640x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-800x480.png">800x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-800x600.png">800x600</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-1024x768.png">1024x768</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-1024x1024.png">1024x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-1152x864.png">1152x864</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-1280x720.png">1280x720</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-1280x800.png">1280x800</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-1280x960.png">1280x960</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-1280x1024.png">1280x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-1400x1050.png">1400x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-1440x900.png">1440x900</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-1600x1200.png">1600x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-1680x1050.png">1680x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-1680x1200.png">1680x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-1920x1080.png">1920x1080</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-1920x1200.png">1920x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-1920x1440.png">1920x1440</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/cal/apr-26-april-blooms-cal-2560x1440.png">2560x1440</a> </li> <li>without calendar: <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-320x480.png">320x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-640x480.png">640x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-800x480.png">800x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-800x600.png">800x600</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-1024x768.png">1024x768</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-1024x1024.png">1024x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-1152x864.png">1152x864</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-1280x720.png">1280x720</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-1280x800.png">1280x800</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-1280x960.png">1280x960</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-1280x1024.png">1280x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-1400x1050.png">1400x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-1440x900.png">1440x900</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-1600x1200.png">1600x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-1680x1050.png">1680x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-1680x1200.png">1680x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-1920x1080.png">1920x1080</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-1920x1200.png">1920x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-1920x1440.png">1920x1440</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/april-blooms/nocal/apr-26-april-blooms-nocal-2560x1440.png">2560x1440</a> </li> </ul> Happiness In Full Bloom <p>Designed by <a href="https://www.ricardogimenes.com/">Ricardo Gimenes</a> from Spain.</p> <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/apr-26-happiness-in-full-bloom-full.png"><img src="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2026/apr-26-happiness-in-full-bloom-preview-opt.png"></a> <ul> <li><a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/apr-26-happiness-in-full-bloom-preview.png">preview</a></li> <li>with calendar: <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-640x480.png">640x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-800x480.png">800x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-800x600.png">800x600</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-1024x768.png">1024x768</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-1024x1024.png">1024x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-1152x864.png">1152x864</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-1280x720.png">1280x720</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-1280x800.png">1280x800</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-1280x960.png">1280x960</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-1280x1024.png">1280x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-1366x768.png">1366x768</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-1400x1050.png">1400x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-1440x900.png">1440x900</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-1600x1200.png">1600x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-1680x1050.png">1680x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-1680x1200.png">1680x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-1920x1080.png">1920x1080</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-1920x1200.png">1920x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-1920x1440.png">1920x1440</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-2560x1440.png">2560x1440</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/cal/apr-26-happiness-in-full-bloom-cal-3840x2160.png">3840x2160</a> </li> <li>without calendar: <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-640x480.png">640x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-800x480.png">800x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-800x600.png">800x600</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-1024x768.png">1024x768</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-1024x1024.png">1024x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-1152x864.png">1152x864</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-1280x720.png">1280x720</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-1280x800.png">1280x800</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-1280x960.png">1280x960</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-1280x1024.png">1280x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-1366x768.png">1366x768</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-1400x1050.png">1400x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-1440x900.png">1440x900</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-1600x1200.png">1600x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-1680x1050.png">1680x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-1680x1200.png">1680x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-1920x1080.png">1920x1080</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-1920x1200.png">1920x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-1920x1440.png">1920x1440</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-2560x1440.png">2560x1440</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/happiness-in-full-bloom/nocal/apr-26-happiness-in-full-bloom-nocal-3840x2160.png">3840x2160</a> </li> </ul> Blade Dance <p>Designed by <a href="https://www.ricardogimenes.com/">Ricardo Gimenes</a> from Spain.</p> <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/apr-26-blade-dance-full.png"><img src="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2026/apr-26-blade-dance-preview-opt.png"></a> <ul> <li><a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/apr-26-blade-dance-preview.png">preview</a></li> <li>with calendar: <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-640x480.png">640x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-800x480.png">800x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-800x600.png">800x600</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-1024x768.png">1024x768</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-1024x1024.png">1024x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-1152x864.png">1152x864</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-1280x720.png">1280x720</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-1280x800.png">1280x800</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-1280x960.png">1280x960</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-1280x1024.png">1280x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-1366x768.png">1366x768</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-1400x1050.png">1400x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-1440x900.png">1440x900</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-1600x1200.png">1600x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-1680x1050.png">1680x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-1680x1200.png">1680x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-1920x1080.png">1920x1080</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-1920x1200.png">1920x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-1920x1440.png">1920x1440</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-2560x1440.png">2560x1440</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/cal/apr-26-blade-dance-cal-3840x2160.png">3840x2160</a> </li> <li>without calendar: <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-640x480.png">640x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-800x480.png">800x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-800x600.png">800x600</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-1024x768.png">1024x768</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-1024x1024.png">1024x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-1152x864.png">1152x864</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-1280x720.png">1280x720</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-1280x800.png">1280x800</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-1280x960.png">1280x960</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-1280x1024.png">1280x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-1366x768.png">1366x768</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-1400x1050.png">1400x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-1440x900.png">1440x900</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-1600x1200.png">1600x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-1680x1050.png">1680x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-1680x1200.png">1680x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-1920x1080.png">1920x1080</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-1920x1200.png">1920x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-1920x1440.png">1920x1440</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-2560x1440.png">2560x1440</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-26/blade-dance/nocal/apr-26-blade-dance-nocal-3840x2160.png">3840x2160</a> </li> </ul> Swing Into Spring <p>“Our April calendar doesn’t need to mark any special occasion — April itself is a reason to celebrate. It was a breeze creating this minimal, pastel-colored calendar design with a custom lettering font and plant pattern for the ultimate spring feel.” — Designed by <a href="https://www.popwebdesign.net/illustrations.html">PopArt Studio</a> from Serbia.</p> <a href="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2023/apr-22-swing-into-spring-full-opt.png"><img src="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2023/apr-22-swing-into-spring-preview-opt.png"></a> <ul> <li><a href="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2023/apr-22-swing-into-spring-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-320x480.png">320x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-640x480.png">640x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-800x480.png">800x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-800x600.png">800x600</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-1024x768.png">1024x768</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-1024x1024.png">1024x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-1152x864.png">1152x864</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-1280x720.png">1280x720</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-1280x800.png">1280x800</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-1280x960.png">1280x960</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-1280x1024.png">1280x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-1400x1050.png">1400x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-1440x900.png">1440x900</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-1600x1200.png">1600x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-1680x1050.png">1680x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-1680x1200.png">1680x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-1920x1080.png">1920x1080</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-1920x1200.png">1920x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-1920x1440.png">1920x1440</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/swing-into-spring/nocal/apr-22-swing-into-spring-nocal-2560x1440.png">2560x1440</a> </li> </ul> Dreaming <p>“The moment when you just walk and your imagination fills up your mind with thoughts.” — Designed by <a href="https://galshir.com/">Gal Shir</a> from Israel.</p> <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/7f6fd0f6-4c2e-4e8f-999c-e0ba5ad27a55/apr-19-dreaming-full-opt.png"><img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/8258c4b2-ea98-45d8-9727-8bba2812646d/apr-19-dreaming-preview-opt.png"></a> <ul> <li><a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/8258c4b2-ea98-45d8-9727-8bba2812646d/apr-19-dreaming-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-340x480.png">340x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-640x480.png">640x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-800x480.png">800x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-800x600.png">800x600</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-1024x768.png">1024x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-1024x1024.png">1024x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-1152x864.png">1152x864</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-1280x720.png">1280x720</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-1280x800.png">1280x800</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-1280x960.png">1280x960</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-1280x1024.png">1280x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-1366x768.png">1366x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-1400x1050.png">1400x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-1440x900.png">1440x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-1600x1200.png">1600x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-1680x1050.png">1680x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-1680x1200.png">1680x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-1920x1080.png">1920x1080</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-1920x1200.png">1920x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-1920x1440.png">1920x1440</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/dreaming/nocal/apr-19-dreaming-nocal-2560x1440.png">2560x1440</a> </li> </ul> Clover Field <p>Designed by Nathalie Ouederni from France.</p> <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/39bc6bc9-47f0-431e-b7fb-882ca4a846df/apr-17-clover-field-full-opt.png"><img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/47694eea-aa70-4e2c-a1ac-04d66d9b1360/apr-17-clover-field-preview-opt.png"></a> <ul> <li><a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/47694eea-aa70-4e2c-a1ac-04d66d9b1360/apr-17-clover-field-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/apr-17/clover-field/nocal/apr-17-clover-field-nocal-1024x768.jpg">1024x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/clover-field/nocal/apr-17-clover-field-nocal-1280x1024.jpg">1280x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/clover-field/nocal/apr-17-clover-field-nocal-1440x900.jpg">1440x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/clover-field/nocal/apr-17-clover-field-nocal-1680x1200.jpg">1680x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/clover-field/nocal/apr-17-clover-field-nocal-1920x1200.jpg">1920x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/clover-field/nocal/apr-17-clover-field-nocal-2560x1440.jpg">2560x1440</a> </li> </ul> Spring Awakens <p>“We all look forward to the awakening of a life that spreads its wings after a dormant winter and opens its petals to greet us. Long live spring, long live life.” — Designed by <a href="https://www.librafire.com/">LibraFire</a> from Serbia.</p> <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/4859e888-38f2-44a7-b993-04cb88cf9418/apr-20-spring-awakens-full-opt.png"><img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/0e46f3a5-f552-494c-a790-2ea6e0fefa97/apr-20-spring-awakens-preview-opt.png"></a> <ul> <li><a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/0e46f3a5-f552-494c-a790-2ea6e0fefa97/apr-20-spring-awakens-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-320x480.png">320x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-640x480.png">640x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-800x480.png">800x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-800x600.png">800x600</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-1024x768.png">1024x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-1024x1024.png">1024x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-1152x864.png">1152x864</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-1280x720.png">1280x720</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-1280x800.png">1280x800</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-1280x960.png">1280x960</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-1280x1024.png">1280x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-1366x768.png">1366x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-1400x1050.png">1400x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-1440x900.png">1440x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-1600x1200.png">1600x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-1680x1050.png">1680x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-1680x1200.png">1680x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-1920x1080.png">1920x1080</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-1920x1200.png">1920x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-1920x1440.png">1920x1440</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-20/spring-awakens/nocal/apr-20-spring-awakens-nocal-2560x1440.png">2560x1440</a> </li> </ul> Inspiring Blossom <p>“‘Sweet spring is your time is my time is our time for springtime is lovetime and viva sweet love,’ wrote E. E. Cummings. And we have a question for you: Is there anything more refreshing, reviving, and recharging than nature in blossom? Let it inspire us all to rise up, hold our heads high, and show the world what we are made of.” — Designed by <a href="https://www.popwebdesign.net/index_eng.html">PopArt Studio</a> from Serbia.</p> <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/b4d1bcbc-24de-458f-b5fd-4bc311346294/apr-19-inspiring-blossom-full-opt.png"><img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/58e505d3-2a5f-40ce-8be0-f284bacd9016/apr-19-inspiring-blossom-preview-opt.png"></a> <ul> <li><a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/58e505d3-2a5f-40ce-8be0-f284bacd9016/apr-19-inspiring-blossom-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-320x480.jpg">320x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-640x480.jpg">640x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-800x480.jpg">800x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-800x600.jpg">800x600</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-1024x768.jpg">1024x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-1024x1024.jpg">1024x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-1152x864.jpg">1152x864</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-1280x720.jpg">1280x720</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-1280x800.jpg">1280x800</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-1280x960.jpg">1280x960</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-1280x1024.jpg">1280x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-1366x768.jpg">1366x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-1400x1050.jpg">1400x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-1440x900.jpg">1440x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-1600x1200.jpg">1600x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-1680x1050.jpg">1680x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-1680x1200.jpg">1680x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-1920x1080.jpg">1920x1080</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-1920x1200.jpg">1920x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-1920x1440.jpg">1920x1440</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/inspiring-blossom/nocal/apr-19-inspiring-blossom-nocal-2560x1440.jpg">2560x1440</a> </li> </ul> Rainy Day <p>Designed by <a href="https://www.behance.net/xenialatii">Xenia Latii</a> from Berlin, Germany.</p> <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/6718210c-8101-4da8-8b28-21fe81961719/apr-16-rainy-day-full-opt.png"><img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/9fb9c64b-f5d1-41fe-be48-11a7e77ccaa5/apr-16-rainy-day-preview-opt.png"></a> <ul> <li><a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/9fb9c64b-f5d1-41fe-be48-11a7e77ccaa5/apr-16-rainy-day-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-320x480.jpg">320x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-640x480.jpg">640x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-800x480.jpg">800x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-800x600.jpg">800x600</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-1024x768.jpg">1024x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-1152x864.jpg">1152x864</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-1280x720.jpg">1280x720</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-1280x800.jpg">1280x800</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-1280x960.jpg">1280x960</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-1280x1024.jpg">1280x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-1366x768.jpg">1366x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-1400x1050.jpg">1400x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-1440x900.jpg">1440x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-1600x1200.jpg">1600x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-1680x1050.jpg">1680x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-1680x1200.jpg">1680x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-1920x1080.jpg">1920x1080</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-1920x1200.jpg">1920x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-1920x1440.jpg">1920x1440</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/rainy-day/nocal/apr-16-rainy-day-nocal-2560x1440.jpg">2560x1440</a> </li> </ul> A Time For Reflection <p>“‘We’re all equal before a wave.’ (Laird Hamilton)” — Designed by Shawna Armstrong from the United States.</p> <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/47348c03-f515-4be8-9883-3ebb01ae754b/apr-15-a-time-for-reflection-full-opt.png"><img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/45e0f0ee-e850-46d9-af29-662819ebf30e/apr-15-a-time-for-reflection-preview-opt.png"></a> <ul> <li><a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/45e0f0ee-e850-46d9-af29-662819ebf30e/apr-15-a-time-for-reflection-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/april-15/a-time-for-reflection/nocal/apr-15-a-time-for-reflection-nocal-1440x900.jpg">1440x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/a-time-for-reflection/nocal/apr-15-a-time-for-reflection-nocal-1600x1200.jpg">1600x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/a-time-for-reflection/nocal/apr-15-a-time-for-reflection-nocal-1680x1050.jpg">1680x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/a-time-for-reflection/nocal/apr-15-a-time-for-reflection-nocal-1920x1080.jpg">1920x1080</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/a-time-for-reflection/nocal/apr-15-a-time-for-reflection-nocal-1920x1200.jpg">1920x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/a-time-for-reflection/nocal/apr-15-a-time-for-reflection-nocal-1920x1440.jpg">1920x1440</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/a-time-for-reflection/nocal/apr-15-a-time-for-reflection-nocal-2560x1440.jpg">2560x1440</a> </li> </ul> Wildest Dreams <p>“We love the art direction, story, and overall cinematography of the ‘Wildest Dreams’ music video by Taylor Swift. It inspired us to create this illustration. Hope it will look good on your desktops.” — Designed by <a href="https://www.kasradesign.com/">Kasra Design</a> from Malaysia.</p> <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/82a6be20-e659-4898-852e-53421e7ce7d2/apr-18-wildest-dreams-full-opt.png"><img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/5e6958ee-8d8a-45e2-8789-f83e72eeb153/apr-18-wildest-dreams-preview-opt.png"></a> <ul> <li><a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/5e6958ee-8d8a-45e2-8789-f83e72eeb153/apr-18-wildest-dreams-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-320x480.jpg">320x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-640x480.jpg">640x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-800x480.jpg">800x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-800x600.jpg">800x600</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-1024x768.jpg">1024x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-1024x1024.jpg">1024x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-1152x864.jpg">1152x864</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-1280x720.jpg">1280x720</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-1280x800.jpg">1280x800</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-1280x960.jpg">1280x960</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-1280x1024.jpg">1280x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-1366x768.jpg">1366x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-1400x1050.jpg">1400x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-1440x900.jpg">1440x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-1600x1200.jpg">1600x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-1680x1050.jpg">1680x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-1680x1200.jpg">1680x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-1920x1080.jpg">1920x1080</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-1920x1200.jpg">1920x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-1920x1440.jpg">1920x1440</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/wildest-dreams/nocal/apr-18-wildest-dreams-nocal-2560x1440.jpg">2560x1440</a> </li> </ul> Coffee Morning <p>Designed by <a href="https://www.ricardogimenes.com/">Ricardo Gimenes</a> from Spain.</p> <a href="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2023/apr-22-coffee-morning-full-opt.png"><img src="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2023/apr-22-coffee-morning-preview-opt.png"></a> <ul> <li><a href="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2023/apr-22-coffee-morning-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-640x480.png">640x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-800x480.png">800x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-800x600.png">800x600</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-1024x768.png">1024x768</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-1024x1024.png">1024x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-1152x864.png">1152x864</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-1280x720.png">1280x720</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-1280x800.png">1280x800</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-1280x960.png">1280x960</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-1280x1024.png">1280x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-1366x768.png">1366x768</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-1400x1050.png">1400x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-1440x900.png">1440x900</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-1600x1200.png">1600x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-1680x1050.png">1680x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-1680x1200.png">1680x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-1920x1080.png">1920x1080</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-1920x1200.png">1920x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-1920x1440.png">1920x1440</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-2560x1440.png">2560x1440</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-22/coffee-morning/nocal/apr-22-coffee-morning-nocal-3840x2160.png">3840x2160</a> </li> </ul> Sakura <p>“Spring is finally here with its sweet Sakura flowers, which remind me of my trip to Japan.” — Designed by <a href="https://weblog.redisdead.net/">Laurence Vagner</a> from France.</p> <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/421692a9-f6b0-4ba2-a962-764add28a469/april-11-prunus-48-full-opt.png"><img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/9f501224-75ff-4f61-84dc-700a6362185a/april-11-prunus-48-preview-opt.png"></a> <ul> <li><a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/9f501224-75ff-4f61-84dc-700a6362185a/april-11-prunus-48-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/efc7788a-1f99-45b6-af8a-910f91ee6940/april-11-prunus-48-nocal-1280x800.jpg">1280x800</a>, <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/4872efae-6211-4d98-ba0d-4903f2e0ce75/april-11-prunus-48-nocal-1280x1024.jpg">1280x1024</a>, <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/9621e961-d3ff-4fd8-8935-a513ee50bb12/april-11-prunus-48-nocal-1680x1050.jpg">1680x1050</a>, <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/6e59e3ac-2d15-4e11-a85f-757deefc31f7/april-11-prunus-48-nocal-1920x1080.jpg">1920x1080</a>, <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/5221f66a-5437-413e-ab1d-02b90c0b2a00/april-11-prunus-48-nocal-1920x1200.jpg">1920x1200</a>, <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/ebb40a83-424a-46ba-b1c6-111adbdeb267/april-11-prunus-48-nocal-2560x1440.jpg">2560x1440</a> </li> </ul> The Perpetual Circle <p>“Inspired by the Black Forest, which is beginning right behind our office windows, so we can watch the perpetual circle of nature when we take a look outside.” — Designed by <a href="https://www.netzbewegung.com/">Nils Kunath</a> from Germany.</p> <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/02959355-754b-4bd7-baf8-a50e3c304882/apr-15-the-perpetual-circle-full-opt.png"><img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/f852d5ba-45e9-450a-a18e-61789bcda9df/apr-15-the-perpetual-circle-preview-opt.png"></a> <ul> <li><a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/f852d5ba-45e9-450a-a18e-61789bcda9df/apr-15-the-perpetual-circle-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/april-15/the-perpetual-circle/nocal/apr-15-the-perpetual-circle-nocal-320x480.jpg">320x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/the-perpetual-circle/nocal/apr-15-the-perpetual-circle-nocal-640x480.jpg">640x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/the-perpetual-circle/nocal/apr-15-the-perpetual-circle-nocal-1024x768.jpg">1024x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/the-perpetual-circle/nocal/apr-15-the-perpetual-circle-nocal-1152x864.jpg">1152x864</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/the-perpetual-circle/nocal/apr-15-the-perpetual-circle-nocal-1280x720.jpg">1280x720</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/the-perpetual-circle/nocal/apr-15-the-perpetual-circle-nocal-1280x800.jpg">1280x800</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/the-perpetual-circle/nocal/apr-15-the-perpetual-circle-nocal-1280x960.jpg">1280x960</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/the-perpetual-circle/nocal/apr-15-the-perpetual-circle-nocal-1280x1024.jpg">1280x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/the-perpetual-circle/nocal/apr-15-the-perpetual-circle-nocal-1400x1050.jpg">1400x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/the-perpetual-circle/nocal/apr-15-the-perpetual-circle-nocal-1440x900.jpg">1440x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/the-perpetual-circle/nocal/apr-15-the-perpetual-circle-nocal-1600x1200.jpg">1600x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/the-perpetual-circle/nocal/apr-15-the-perpetual-circle-nocal-1680x1200.jpg">1680x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/the-perpetual-circle/nocal/apr-15-the-perpetual-circle-nocal-1920x1080.jpg">1920x1080</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/the-perpetual-circle/nocal/apr-15-the-perpetual-circle-nocal-1920x1200.jpg">1920x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/the-perpetual-circle/nocal/apr-15-the-perpetual-circle-nocal-1920x1440.jpg">1920x1440</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/the-perpetual-circle/nocal/apr-15-the-perpetual-circle-nocal-2560x1440.jpg">2560x1440</a> </li> </ul> The Loneliest House In The World <p>“March 26 was Solitude Day. To celebrate it, here is the picture about the loneliest house in the world. It is a real house, I found it <a href="https://www.youtube.com/watch?v=dTqVocrDoy0">on Youtube</a>.” — Designed by <a href="https://vlad.studio/">Vlad Gerasimov</a> from Georgia.</p> <a href="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2024/apr-23-the-lonliest-house-in-the-world-full-opt.png"><img src="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2024/apr-23-the-lonliest-house-in-the-world-preview-opt.png"></a> <ul> <li><a href="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2024/apr-23-the-lonliest-house-in-the-world-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-800x480.jpg">800x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-800x600.jpg">800x600</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-1024x600.jpg">1024x600</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-1024x768.jpg">1024x768</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-1152x864.jpg">1152x864</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-1280x720.jpg">1280x720</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-1280x800.jpg">1280x800</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-1280x960.jpg">1280x960</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-1280x1024.jpg">1280x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-1366x768.jpg">1366x768</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-1400x1050.jpg">1400x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-1440x900.jpg">1440x900</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-1440x960.jpg">1440x960</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-1600x900.jpg">1600x900</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-1600x1200.jpg">1600x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-1680x1050.jpg">1680x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-1680x1200.jpg">1680x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-1920x1080.jpg">1920x1080</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-1920x1200.jpg">1920x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-1920x1440.jpg">1920x1440</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-2560x1440.jpg">2560x1440</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-2560x1600.jpg">2560x1600</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-2880x1800.jpg">2880x1800</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-3072x1920.jpg">3072x1920</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-3840x2160.jpg">3840x2160</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/the-lonliest-house-in-the-world/nocal/apr-23-the-lonliest-house-in-the-world-nocal-5120x2880.jpg">5120x2880</a> </li> </ul> Happy Easter <p>Designed by <a href="https://www.tazi.com.au/">Tazi Design</a> from Australia.</p> <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/104f13a8-8317-4bf1-87bf-19abbaf4adc8/apr-17-happy-easter-full-opt.png"><img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/ef95403f-b12f-43a4-ace6-2a5e0efc6146/apr-17-happy-easter-preview-opt.png"></a> <ul> <li><a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/ef95403f-b12f-43a4-ace6-2a5e0efc6146/apr-17-happy-easter-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/apr-17/happy-easter/nocal/apr-17-happy-easter-nocal-320x480.png">320x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/happy-easter/nocal/apr-17-happy-easter-nocal-640x480.png">640x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/happy-easter/nocal/apr-17-happy-easter-nocal-800x600.png">800x600</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/happy-easter/nocal/apr-17-happy-easter-nocal-1024x768.png">1024x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/happy-easter/nocal/apr-17-happy-easter-nocal-1152x864.png">1152x864</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/happy-easter/nocal/apr-17-happy-easter-nocal-1280x720.png">1280x720</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/happy-easter/nocal/apr-17-happy-easter-nocal-1280x960.png">1280x960</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/happy-easter/nocal/apr-17-happy-easter-nocal-1600x1200.png">1600x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/happy-easter/nocal/apr-17-happy-easter-nocal-1920x1080.png">1920x1080</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/happy-easter/nocal/apr-17-happy-easter-nocal-1920x1440.png">1920x1440</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/happy-easter/nocal/apr-17-happy-easter-nocal-2560x1440.png">2560x1440</a> </li> </ul> Playful Alien <p>“Everything would be more fun if a little alien had the controllers.” — Designed by <a href="https://www.mariakellerac.com/">Maria Keller</a> from Mexico.</p> <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/0eb88cb3-bdfb-4e8d-a319-2b0a825057b5/apr-16-playful-alien-full-opt.png"><img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/644b4916-4c76-45f5-bb00-f272b5a886a7/apr-16-playful-alien-preview-opt.png"></a><ul> <li><a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/644b4916-4c76-45f5-bb00-f272b5a886a7/apr-16-playful-alien-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-320x480.png">320x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-640x480.png">640x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-640x1136.png">640x1136</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-750x1334.png">750x1334</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-800x600.png">800x600</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-1024x768.png">1024x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-1024x1024.png">1024x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-1152x864.png">1152x864</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-1242x2208.png">1242x2208</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-1280x720.png">1280x720</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-1280x800.png">1280x800</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-1280x960.png">1280x960</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-1280x1024.png">1280x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-1366x768.png">1366x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-1400x1050.png">1400x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-1440x900.png">1440x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-1600x1200.png">1600x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-1680x1050.png">1680x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-1680x1200.png">1680x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-1920x1080.png">1920x1080</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-1920x1200.png">1920x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-1920x1440.png">1920x1440</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-2560x1440.png">2560x1440</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/playful-alien/nocal/apr-16-playful-alien-nocal-2880x1800.png">2880x1800</a> </li> </ul> Springtime Sage <p>“Spring and fresh herbs always feel like they compliment each other. Keeping it light and fresh with this wallpaper welcomes a new season!” — Designed by <a href="https://www.susanchiang.com/">Susan Chiang</a> from the United States.</p> <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/64e51685-dfa7-4508-94bb-58ee6f241340/apr-17-springtime-sage-full-opt.png"><img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/f65379f3-d09d-4218-9921-513057977894/apr-17-springtime-sage-preview-opt.png"></a> <ul> <li><a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/f65379f3-d09d-4218-9921-513057977894/apr-17-springtime-sage-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/apr-17/springtime-sage/nocal/apr-17-springtime-sage-nocal-320x480.png">320x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/springtime-sage/nocal/apr-17-springtime-sage-nocal-1024x768.png">1024x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/springtime-sage/nocal/apr-17-springtime-sage-nocal-1280x800.png">1280x800</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/springtime-sage/nocal/apr-17-springtime-sage-nocal-1280x1024.png">1280x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/springtime-sage/nocal/apr-17-springtime-sage-nocal-1400x900.png">1400x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/springtime-sage/nocal/apr-17-springtime-sage-nocal-1680x1200.png">1680x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/springtime-sage/nocal/apr-17-springtime-sage-nocal-1920x1200.png">1920x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/springtime-sage/nocal/apr-17-springtime-sage-nocal-1920x1440.png">1920x1440</a> </li> </ul> April Showers <p>Designed by <a href="https://www.ricardogimenes.com/">Ricardo Gimenes</a> from Spain.</p> <a href="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2025/apr-19-april-showers-full-opt.png"><img src="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2025/apr-19-april-showers-preview-opt.png"></a> <ul> <li><a href="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2025/apr-19-april-showers-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-320x480.png">320x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-640x480.png">640x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-800x480.png">800x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-800x600.png">800x600</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-1024x768.png">1024x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-1024x1024.png">1024x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-1152x864.png">1152x864</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-1280x720.png">1280x720</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-1280x800.png">1280x800</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-1280x960.png">1280x960</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-1280x1024.png">1280x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-1366x768.png">1366x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-1400x1050.png">1400x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-1440x900.png">1440x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-1600x1200.png">1600x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-1680x1050.png">1680x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-1680x1200.png">1680x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-1920x1080.png">1920x1080</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-1920x1200.png">1920x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-1920x1440.png">1920x1440</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/april-showers/nocal/apr-19-april-showers-nocal-2560x1440.png">2560x1440</a> </li> </ul> Fairy Tale <p>“A tribute to Hans Christian Andersen. Happy Birthday!” — Designed by <a href="https://www.behance.net/roxana-nastase">Roxi Nastase</a> from Romania.</p> <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/c9a294b3-d423-4b0b-8bb8-12ec019260d8/apr-17-fairytale-full-opt.png"><img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/ee587665-f8be-49e3-b526-5b4b6778d668/apr-17-fairytale-preview-opt.png"></a> <ul> <li><a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/ee587665-f8be-49e3-b526-5b4b6778d668/apr-17-fairytale-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/apr-17/fairytale/nocal/apr-17-fairytale-nocal-1152x864.jpg">1152x864</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/fairytale/nocal/apr-17-fairytale-nocal-1280x720.jpg">1280x720</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/fairytale/nocal/apr-17-fairytale-nocal-1280x800.jpg">1280x800</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/fairytale/nocal/apr-17-fairytale-nocal-1280x960.jpg">1280x960</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/fairytale/nocal/apr-17-fairytale-nocal-1280x1024.jpg">1280x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/fairytale/nocal/apr-17-fairytale-nocal-1400x1050.jpg">1400x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/fairytale/nocal/apr-17-fairytale-nocal-1440x900.jpg">1440x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/fairytale/nocal/apr-17-fairytale-nocal-1600x1200.jpg">1600x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/fairytale/nocal/apr-17-fairytale-nocal-1680x1050.jpg">1680x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/fairytale/nocal/apr-17-fairytale-nocal-1680x1200.jpg">1680x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/fairytale/nocal/apr-17-fairytale-nocal-1920x1080.jpg">1920x1080</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/fairytale/nocal/apr-17-fairytale-nocal-1920x1200.jpg">1920x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/fairytale/nocal/apr-17-fairytale-nocal-1920x1440.jpg">1920x1440</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/fairytale/nocal/apr-17-fairytale-nocal-2560x1440.jpg">2560x1440</a> </li> </ul> First Day Of Spring <p>“April is my birthday month! Creating this wallpaper was a reminder of the new beginnings spring brings!” — Designed by Marykate Boyle from the United States.</p> <a href="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2026/apr-23-first-day-of-spring-full-opt.png"><img src="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2026/apr-23-first-day-of-spring-preview-opt.png"></a> <ul> <li><a href="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2026/apr-23-first-day-of-spring-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-320x480.png">320x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-640x480.png">640x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-800x480.png">800x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-800x600.png">800x600</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-1024x768.png">1024x768</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-1024x1024.png">1024x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-1152x864.png">1152x864</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-1280x720.png">1280x720</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-1280x800.png">1280x800</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-1280x960.png">1280x960</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-1280x1024.png">1280x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-1400x1050.png">1400x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-1440x900.png">1440x900</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-1600x1200.png">1600x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-1680x1050.png">1680x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-1680x1200.png">1680x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-1920x1080.png">1920x1080</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-1920x1200.png">1920x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-1920x1440.png">1920x1440</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/first-day-of-spring/nocal/apr-23-first-day-of-spring-nocal-2560x1440.png">2560x1440</a> </li> </ul> Citrus Passion <p>Designed by Nathalie Ouederni from France.</p> <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/caa53bc8-6a29-4e62-bdd7-9cde2389d0c6/apr-15-citrus-passion-full-opt.png"><img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/e9230d56-af8c-47a3-ae80-cf712b815ec9/apr-15-citrus-passion-preview-opt.png"></a> <ul> <li><a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/e9230d56-af8c-47a3-ae80-cf712b815ec9/apr-15-citrus-passion-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/april-15/citrus-passion/nocal/apr-15-citrus-passion-nocal-320x480.jpg">320x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/citrus-passion/nocal/apr-15-citrus-passion-nocal-1024x768.jpg">1024x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/citrus-passion/nocal/apr-15-citrus-passion-nocal-1200x1024.jpg">1200x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/citrus-passion/nocal/apr-15-citrus-passion-nocal-1440x900.jpg">1440x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/citrus-passion/nocal/apr-15-citrus-passion-nocal-1600x1200.jpg">1600x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/citrus-passion/nocal/apr-15-citrus-passion-nocal-1680x1200.jpg">1680x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/citrus-passion/nocal/apr-15-citrus-passion-nocal-1920x1200.jpg">1920x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/citrus-passion/nocal/apr-15-citrus-passion-nocal-2560x1440.jpg">2560x1440</a> </li> </ul> I “Love” My Dog <p>Designed by <a href="https://www.ricardogimenes.com/">Ricardo Gimenes</a> from Spain.</p> <a href="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2024/apr-23-i-love-my-dog-full-opt.png"><img src="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2024/apr-23-i-love-my-dog-preview-opt.png"></a> <ul> <li><a href="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2024/apr-23-i-love-my-dog-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-640x480.png">640x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-800x480.png">800x480</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-800x600.png">800x600</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-1024x768.png">1024x768</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-1024x1024.png">1024x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-1152x864.png">1152x864</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-1280x720.png">1280x720</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-1280x800.png">1280x800</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-1280x960.png">1280x960</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-1280x1024.png">1280x1024</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-1366x768.png">1366x768</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-1400x1050.png">1400x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-1440x900.png">1440x900</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-1600x1200.png">1600x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-1680x1050.png">1680x1050</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-1680x1200.png">1680x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-1920x1080.png">1920x1080</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-1920x1200.png">1920x1200</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-1920x1440.png">1920x1440</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-2560x1440.png">2560x1440</a>, <a href="https://www.smashingmagazine.com/files/wallpapers/apr-23/i-love-my-dog/nocal/apr-23-i-love-my-dog-nocal-3840x2160.png">3840x2160</a> </li> </ul> Ready For April <p>“It is very common that it rains in April. This year, I am not sure… But whatever… we are just prepared!” — Designed by <a href="https://www.silocreativo.com/en/">Verónica Valenzuela</a> from Spain.</p> <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/e722b322-43d2-4878-9019-324c82f2ec71/apr-16-ready-for-april-full-opt.png"><img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/e3f77535-471b-4c15-b34b-aa549c370d67/apr-16-ready-for-april-preview-opt.png"></a><ul> <li><a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/e3f77535-471b-4c15-b34b-aa549c370d67/apr-16-ready-for-april-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/april-16/ready-for-april/nocal/apr-16-ready-for-april-nocal-800x480.png">800x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/ready-for-april/nocal/apr-16-ready-for-april-nocal-1024x768.png">1024x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/ready-for-april/nocal/apr-16-ready-for-april-nocal-1152x864.png">1152x864</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/ready-for-april/nocal/apr-16-ready-for-april-nocal-1280x800.png">1280x800</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/ready-for-april/nocal/apr-16-ready-for-april-nocal-1280x960.png">1280x960</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/ready-for-april/nocal/apr-16-ready-for-april-nocal-1440x900.png">1440x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/ready-for-april/nocal/apr-16-ready-for-april-nocal-1680x1200.png">1680x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/ready-for-april/nocal/apr-16-ready-for-april-nocal-1920x1080.png">1920x1080</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-16/ready-for-april/nocal/apr-16-ready-for-april-nocal-2560x1440.png">2560x1440</a> </li> </ul> Good Day <p>“Some pretty flowers and spring time always make for a good day.” — Designed by <a href="https://www.corporate3design.com/">Amalia Van Bloom</a> from the United States.</p> <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/b39d9dc1-f5b7-4838-a3d4-8f581d42347d/apr-14-good-day-full-opt.png"><img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/424e321b-e0e7-451d-afb7-8a67e917f7bc/apr-14-good-day-preview-opt.png"></a> <ul> <li><a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/424e321b-e0e7-451d-afb7-8a67e917f7bc/apr-14-good-day-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/april-14/good-day/nocal/apr-14-good-day-nocal-640x1136.jpg">640x1136</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-14/good-day/nocal/apr-14-good-day-nocal-1024x768.jpg">1024x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-14/good-day/nocal/apr-14-good-day-nocal-1280x800.jpg">1280x800</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-14/good-day/nocal/apr-14-good-day-nocal-1280x1024.jpg">1280x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-14/good-day/nocal/apr-14-good-day-nocal-1440x900.jpg">1440x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-14/good-day/nocal/apr-14-good-day-nocal-1920x1200.jpg">1920x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-14/good-day/nocal/apr-14-good-day-nocal-2560x1440.jpg">2560x1440</a> </li> </ul> Yellow Submarine <p>“The Beatles — ‘Yellow Submarine’: This song is fun and at the same time there is a lot of interesting text that changes your thinking. Like everything that makes The Beatles.” — Designed by <a href="https://www.webtoffee.com/">WebToffee</a> from India.</p> <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/12572c89-8dd9-45b5-abef-2e7d8e22a962/apr-18-yellow-submarine-full-opt.png"><img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/6b27b8a6-2b8c-4a06-a8d6-0d4a1774db18/apr-18-yellow-submarine-preview-opt.png"></a> <ul> <li><a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/6b27b8a6-2b8c-4a06-a8d6-0d4a1774db18/apr-18-yellow-submarine-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/apr-18/yellow-submarine/nocal/apr-18-yellow-submarine-nocal-360x640.png">360x640</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/yellow-submarine/nocal/apr-18-yellow-submarine-nocal-1024x768.png">1024x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/yellow-submarine/nocal/apr-18-yellow-submarine-nocal-1280x720.png">1280x720</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/yellow-submarine/nocal/apr-18-yellow-submarine-nocal-1280x800.png">1280x800</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/yellow-submarine/nocal/apr-18-yellow-submarine-nocal-1280x960.png">1280x960</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/yellow-submarine/nocal/apr-18-yellow-submarine-nocal-1280x1024.png">1280x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/yellow-submarine/nocal/apr-18-yellow-submarine-nocal-1366x768.png">1366x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/yellow-submarine/nocal/apr-18-yellow-submarine-nocal-1400x1050.png">1400x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/yellow-submarine/nocal/apr-18-yellow-submarine-nocal-1440x900.png">1440x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/yellow-submarine/nocal/apr-18-yellow-submarine-nocal-1600x900.png">1600x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/yellow-submarine/nocal/apr-18-yellow-submarine-nocal-1680x1200.png">1680x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-18/yellow-submarine/nocal/apr-18-yellow-submarine-nocal-1920x1080.png">1920x1080</a> </li> </ul> Spring Fever <p>“I created that mouse character for a series of illustrations about a poem my mom often told me when I was a child. In that poem the mouse goes on an adventure. Here it is after the adventure, ready for new ones.” — Designed by <a href="https://www.anja-sturm.com/">Anja Sturm</a> from Germany.</p> <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/dbda6734-afb0-445d-ae8d-c7b065588454/apr-15-spring-fever-full-opt.png"><img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/95eec686-6be9-41f4-9250-bd78c01d34cc/apr-15-spring-fever-preview-opt.png"></a> <ul> <li><a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/95eec686-6be9-41f4-9250-bd78c01d34cc/apr-15-spring-fever-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/april-15/spring-fever/nocal/apr-15-spring-fever-nocal-320x480.png">320x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/spring-fever/nocal/apr-15-spring-fever-nocal-800x600.png">800x600</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/spring-fever/nocal/apr-15-spring-fever-nocal-1024x768.png">1024x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/spring-fever/nocal/apr-15-spring-fever-nocal-1280x720.png">1280x720</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/spring-fever/nocal/apr-15-spring-fever-nocal-1440x900.png">1440x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/spring-fever/nocal/apr-15-spring-fever-nocal-1620x1050.png">1620x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/april-15/spring-fever/nocal/apr-15-spring-fever-nocal-1920x1080.png">1920x1080</a> </li> </ul> In The River <p>“Spring is here! Crocodiles search the hot and stay in the river.” — Designed by <a href="https://www.silocreativo.com/en">Veronica Valenzuela</a> from Spain.</p> <a href="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2023/apr-19-in-the-river-full-opt.png"><img src="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2023/apr-19-in-the-river-preview-opt.png"></a> <ul> <li><a href="https://files.smashing.media/articles/desktop-wallpaper-calendars-april-2023/apr-19-in-the-river-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/apr-19/in-the-river/nocal/apr-19-in-the-river-nocal-640x480.png">640x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/in-the-river/nocal/apr-19-in-the-river-nocal-800x480.png">800x480</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/in-the-river/nocal/apr-19-in-the-river-nocal-1024x768.png">1024x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/in-the-river/nocal/apr-19-in-the-river-nocal-1280x720.png">1280x720</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/in-the-river/nocal/apr-19-in-the-river-nocal-1280x800.png">1280x800</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/in-the-river/nocal/apr-19-in-the-river-nocal-1440x900.png">1440x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/in-the-river/nocal/apr-19-in-the-river-nocal-1600x1200.png">1600x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/in-the-river/nocal/apr-19-in-the-river-nocal-1920x1080.png">1920x1080</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/in-the-river/nocal/apr-19-in-the-river-nocal-1920x1440.png">1920x1440</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-19/in-the-river/nocal/apr-19-in-the-river-nocal-2560x1440.png">2560x1440</a> </li> </ul> Purple Rain <p>“This month is International Guitar Month! Time to get out your guitar and play. As a graphic designer/illustrator seeing all the variations of guitar shapes begs to be used for a fun design. Search the guitar shapes represented and see if you see one similar to yours, or see if you can identify some of the different styles that some famous guitarists have played (BTW, Prince’s guitar is in there and purple is just a cool color).” — Designed by <a href="https://www.codesign.cc/">Karen Frolo</a> from the United States.</p> <a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/4974612c-d128-47cd-bc5b-88fe614c8060/apr-17-purple-rain-full-opt.png"><img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/a3044f60-78ac-448a-9603-45c926378aeb/apr-17-purple-rain-preview-opt.png"></a> <ul> <li><a href="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/a3044f60-78ac-448a-9603-45c926378aeb/apr-17-purple-rain-preview-opt.png">preview</a></li> <li>without calendar: <a href="https://smashingmagazine.com/files/wallpapers/apr-17/purple-rain/nocal/apr-17-purple-rain-nocal-1024x768.jpg">1024x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/purple-rain/nocal/apr-17-purple-rain-nocal-1024x1024.jpg">1024x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/purple-rain/nocal/apr-17-purple-rain-nocal-1280x800.jpg">1280x800</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/purple-rain/nocal/apr-17-purple-rain-nocal-1280x960.jpg">1280x960</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/purple-rain/nocal/apr-17-purple-rain-nocal-1280x1024.jpg">1280x1024</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/purple-rain/nocal/apr-17-purple-rain-nocal-1366x768.jpg">1366x768</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/purple-rain/nocal/apr-17-purple-rain-nocal-1440x900.jpg">1440x900</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/purple-rain/nocal/apr-17-purple-rain-nocal-1600x1200.jpg">1600x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/purple-rain/nocal/apr-17-purple-rain-nocal-1680x1050.jpg">1680x1050</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/purple-rain/nocal/apr-17-purple-rain-nocal-1680x1200.jpg">1680x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/purple-rain/nocal/apr-17-purple-rain-nocal-1920x1080.jpg">1920x1080</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/purple-rain/nocal/apr-17-purple-rain-nocal-1920x1200.jpg">1920x1200</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/purple-rain/nocal/apr-17-purple-rain-nocal-1920x1440.jpg">1920x1440</a>, <a href="https://smashingmagazine.com/files/wallpapers/apr-17/purple-rain/nocal/apr-17-purple-rain-nocal-2560x1440.jpg">2560x1440</a> </li> </ul> Get Featured Next Month <p>Feeling inspired? We’ll publish the <strong>May wallpapers</strong> on April 30, so if you’d like to be a part of the collection, please don’t hesitate to <a href="https://www.smashingmagazine.com/desktop-wallpaper-calendars-join-in/"><strong>submit your design</strong></a>. We are already looking forward to it!</p>

The Site-Search Paradox: Why The Big Box Always Wins

<p>In the early days of the web, the search bar was a luxury, added to a site once it became “too big” to navigate by clicking. We treated it like an index at the back of a book: a literal, alphabetical list of words that pointed to specific pages. If you typed the exact word the author used, you found what you needed. If you didn’t, you were met with a “0 Results Found” screen that felt like a digital dead end.</p> <p>Twenty-five years later, we are still building search bars that act like 1990s index cards, even though the humans using them have been fundamentally rewired. Today, when a user lands on your site and can’t find what they need in the global navigation within seconds, they don’t try to learn your taxonomy. They head for the search box. But if that box fails them, and demands they use <em>your</em> specific brand vocabulary, or punishes them for a typo, they do something that should keep every UX designer awake at night. They leave your site, go to Google, and type <strong>site:yourwebsite.com [query]</strong>. Or, worse still, they just type in their query and end up on a competitor’s website. I personally use Google over a site’s search nearly every time.</p> <p>This is the <strong>Site-Search Paradox</strong>. In an era where we have more data and better tools than ever, our internal search experiences are often so poor that users prefer to use a trillion-dollar global search engine to find a single page on a local site. As Information Architects and UX designers, we have to ask, why does the “Big Box” win, and how can we take our users back?</p> The “Syntax Tax” And The Death Of Exact Match <p>The primary reason site search fails is what I call the <strong>Syntax Tax</strong>. This is the cognitive load we place on users when we require them to guess the exact string of characters we’ve used in our database.</p> <p>Research by <strong>Origin Growth</strong> on <a href="https://www.origingrowth.co.uk/blog/search-vs-navigate-how-people-behave-on-websites-do-they-search-or-do-they-navigate/"><strong>Search vs Navigate</strong></a> shows that roughly <strong>50% of users</strong> go straight to the search bar upon landing on a site. For example, when a user types “sofa” into a furniture site that has categorised everything under “couches,” and the site returns nothing, the user doesn’t think, <em>“Ah, I should try a synonym.”</em> They think, <em>“This site doesn’t have what I want.”</em></p> <p>This is a failure of <strong>Information Architecture (IA)</strong>. We’ve built our systems to match <em>strings</em> (literal sequences of letters) rather than <em>things</em> (the concepts behind the words). When we force users to match our internal vocabulary, we are taxing their brainpower.</p> <p><img src="https://files.smashing.media/articles/site-search-paradox-why-big-box-always-wins/1-keyword-semantic-search.jpg"></p> Why Google Wins: It’s Not Power, It’s Context <p>It is easy to throw our hands up and say, “We can’t compete with Google’s engineering.” But Google’s success isn’t just about raw power; it’s about <strong>contextual understanding</strong>. While we often treat search as a technical utility, Google treats it as an IA challenge.</p> <p>Data from the <strong>Baymard Institute</strong> reveals that <a href="https://baymard.com/blog/ecommerce-search-query-types"><strong>41% of e-commerce sites</strong></a> fail to support even basic symbols or abbreviations, and this often leads to <strong>users</strong> abandoning a site after a single failed search attempt. Google wins because it uses <a href="https://www.ibm.com/think/topics/stemming-lemmatization#:~:text=How%20lemmatization%20works,syntactic%20function%20in%20the%20sentence."><strong>stemming and lemmatization</strong></a> — IA techniques that recognize “running” and “ran” are the same intent. Most internal searches are “blind” to this context, treating “Running Shoe” and “Running Shoes” as entirely different entities.</p> <p>If your site search can’t handle a simple plural or a common misspelling, you are effectively charging your users a tax for being human.</p> <p><img src="https://files.smashing.media/articles/site-search-paradox-why-big-box-always-wins/2-user-query-friction-user-flow.jpg"></p> The UX Of “Maybe”: Designing For Probabilistic Results <p>In traditional IA, we think in binaries: A page is either in a category, or it isn’t. A search result is either a match or it isn’t. Modern search, which users now expect, is <strong>probabilistic</strong>. It deals in “confidence levels.”</p> <p>According to <strong>Forresters</strong>, users who use search are <a href="https://www.nosto.com/blog/ecommerce-site-search-statistics/#:~:text=Everyone%E2%80%99s%20searching%20for%20something%2C%20but,to%20convert%20and%20come%20back"><strong>2–3 times more likely to convert</strong></a> than those who don’t, <em>if</em> the search works. And <a href="https://www.nosto.com/blog/ecommerce-site-search-statistics/#:~:text=Everyone%E2%80%99s%20searching%20for%20something%2C%20but,to%20convert%20and%20come%20back"><strong>80% of users</strong></a> on e-commerce sites exit a site due to poor search results. </p> <p>As designers, we rarely design for the middle ground. We design a “<strong>Results Found</strong>” page and a “<strong>No Results</strong>” page. We miss the most important state: <strong>The “Did You Mean?” State.</strong> A well-designed search interface should provide “Fuzzy” matches. Instead of a cold “0 Results Found” screen, we should be using our metadata to say, <em>“We didn’t find that in ‘Electronics,’ but we found 3 matches in ‘Accessories’.”</em> By designing for “Maybe,” we can keep the user in the flow.</p> Case Study: The Cost Of “Invisible” Content <p>To understand why IA is the fuel for the search engine, we must look at how data is structured behind the scenes. In my 25 years of practice, I’ve seen that the “findability” of a page is directly tied to its structured metadata.</p> <p>Consider a large-scale enterprise I worked with that had over 5,000 technical documents. Their internal search was returning irrelevant results because the “Title” tag of every document was the internal SKU number (e.g., “DOC-9928-X”) rather than the human-readable name.</p> <p>By reviewing the search logs, we discovered that users were searching for “installation guide.” Because that phrase didn’t appear in the SKU-based title, the engine ignored the most relevant files. We implemented a <strong>Controlled Vocabulary</strong>, which was a set of standardised terms that mapped SKUs to human language. Within three months, the “Exit Rate” from the search page dropped by 40%. This wasn’t an algorithmic fix; it was an IA fix. It proves that a search engine is only as good as the map we give it.</p> The Internal Language Gap <p>Throughout my two decades in UX, I’ve noticed a recurring theme: internal teams often suffer from “The curse of knowledge.” We become so immersed in our own corporate vocabulary, or sometimes referred to as business jargon, that we forget the user doesn’t speak our language.</p> <p>I once worked with a financial institution that was frustrated by high call volumes to their support centre. Users were complaining they couldn’t find “loan payoff” information on the site. When we looked at the search logs, “loan payoff” was the #1 searched term that resulted in zero hits.</p> <p>Why? Because the institution’s IA team had labelled every relevant page under the formal term “Loan Release.” To the bank, a “payoff” was a process, but a “Loan Release” was the legal document that was the “thing” in the database. Because the search engine was looking for literal character strings, it refused to connect the user’s desperate need with the company’s official solution.</p> <p>This is where the IA professional must act as a translator. By simply adding “loan payoff” as a hidden metadata keyword to the Loan Release pages, we solved a multi-million dollar support problem. We didn’t need a faster server; we needed <strong>a more empathetic taxonomy</strong>.</p> The 4-step Site-search Audit Framework <p>If you want to reclaim your search box from Google, you cannot simply “set it and forget it.” You must treat search as a living product. Here is the framework I use to audit and optimise search experiences:</p> <h3>Phase 1: The “Zero-result” Audit</h3> <p>Pull your search logs from the last 90 days. Filter for all queries that returned zero results. Group these into three buckets:</p> <ul> <li> <strong>True gaps</strong><br>Content the user wants that you simply don’t have (a signal for your content strategy team).</li> <li> <strong>Synonym gaps</strong><br>Content you have, but described in words the user doesn’t use (e.g., “Sofa” vs “Couch”).</li> <li> <strong>Format gaps</strong><br>The user is looking for a “video” or “PDF,” but your search only indexes HTML text.</li> </ul> <h3>Phase 2: Query Intent Mapping</h3> <p>Analyse the <em>top 50</em> most common queries. Are they <strong>Navigational</strong> (looking for a specific page), <strong>Informational</strong> (looking for “how to”), or <strong>Transactional</strong> (looking for a specific product)? Your search UI should look different for each. A navigational search should “Quick-Link” the user directly to the destination, bypassing the results page entirely.</p> <h3>Phase 3: The “Fuzzy” Matching Test</h3> <p>Intentionally mistype your top 10 products. Use plurals, common typos, and American vs. British English spellings (e.g., “Color” vs. “Colour”). If your search fails these tests, your engine lacks “stemming” support. This is a technical requirement you must advocate for to your engineering team.</p> <h3>Phase 4: Scoping And Filtering UX</h3> <p>Look at your results page. Does it offer filters that actually make sense? If a user searches for “shoes," they should see filters for <em>Size</em> and <em>Colour</em>. Generic filters can be as bad as no filters.</p> Reclaiming The Search Box: A Strategy For IA Professionals <p>To stop the exodus to Google, we must move beyond the “Box” and look at the <strong>scaffolding</strong>.</p> <p><strong>Step A: Implement semantic scaffolding.</strong><br>Don’t just return a list of links. Use your IA to provide context. If a user searches for a product, show them the product, but also show them the <em>manual</em>, the <em>FAQs</em>, and the <em>related parts</em>. This “associative” search mimics how the human brain works and how Google operates.</p> <p><strong>Step B: Stop being a librarian, start being a concierge.</strong><br>A librarian tells you exactly where the book is on the shelf. A concierge listens to what you want to achieve and gives you a recommendation. Your search bar should use predictive text not just to complete words, but to <strong>suggest intentions</strong>.</p> Using A Google-powered Search Bar <p>Using a “Google-powered” search bar, as seen on the <strong>University of Chicago</strong> website, is essentially an admission that a site’s internal organisation has become too complex for its own navigation to handle. While it is a quick “fix” for massive institutions to ensure users find <em>something</em>, it is generally a poor choice for businesses with deep content. </p> <p><img src="https://files.smashing.media/articles/site-search-paradox-why-big-box-always-wins/3-university-chicago-website.png"></p> <p>By delegating the search to Google, you surrender the user experience to an outside algorithm. You lose the ability to promote specific products, you expose your users to third-party ads, and you train your customers to leave your ecosystem the moment they need help. For a business, search should be a curated conversation that guides a customer toward a goal, not a generic list of links that pushes them back to the open web.</p> <p><img src="https://files.smashing.media/articles/site-search-paradox-why-big-box-always-wins/4-search-results.jpg"></p> The Simple Search UX Checklist <p>Here is a final checklist for reference when you are building the search experience for your users. Work with your product team to ensure you are engaging with the right team members.</p> <ul> <li> <strong>Kill the dead-end.</strong><br>Never just say “<strong>No results found</strong>.” If an exact match isn’t there, suggest a similar category, a popular product, or a way to contact support.</li> <li> <strong>Fix “almost” matches.</strong><br>Make sure the search can handle plurals (like “plant” vs. “plants”) and common typos. Users shouldn’t be punished for a slip of the thumb.</li> <li> <strong>Predict the user’s goal.</strong><br>Use an “auto-suggest” menu to show helpful actions (like “Track my order”) or categories, not just a list of words.</li> <li> <strong>Talk like a human.</strong><br>Look at your search logs to see the words people actually use. If they type “couch” and you call it “sofa,” create a bridge in the background so they find what they need anyway.</li> <li> <strong>Smart filtering.</strong><br>Only show filters that matter. If someone searches for “shoes,” show them size and color filters, not a generic list that applies to the whole site.</li> <li> <strong>Show, don’t just list.</strong><br>Use small thumbnails and clear labels in the search results so users can see the difference between a product, a blog post, and a help article at a glance.</li> <li> <strong>Speed is trust.</strong><br>If the search takes more than a second, use a loading animation. If it’s too slow, people will immediately go back to Google.</li> <li> <strong>Check the “failure” logs.</strong><br>Once a month, look at what people searched for that returned zero results. This is your “to-do list” for fixing your site’s navigation.</li> </ul> Conclusion: The Search Bar Is A Conversation <p>The search box is the only place on your site where the user tells us exactly, in their own words, what they want. When we fail to understand those words, when we let the “Big Box” of Google do the work for us, we aren’t just losing a page view. We are losing the opportunity to prove that we <strong>understand</strong> our customers.</p> <p>Success in modern UX isn’t about having the most content; it’s about having the most findable content. It’s time to stop taxing users for their syntax and start designing for their intent.</p> <p>By moving from literal string matching to semantic understanding, and by supporting our search engines with robust, human-centered Information Architecture, we can finally close the gap.</p>

Testing Font Scaling For Accessibility With Figma Variables

<p>Building a true culture of digital accessibility in a company is a mission of resilience and perseverance. It’s not difficult for the discourse on accessibility to fall into the usual clichés. Accessibility is very important for people. The accessibility of digital products and services promotes inclusion. Or even, all professionals on the teams should be involved in accessibility work. Of course. No one in their right mind will dispute any of these statements (I hope).</p> <p>However, the second part of this conversation, which very few companies reach, is <em>“how?”</em> How do we make this happen in the midst of the day-to-day work of digital transformation teams, which, as we all know, are immersed in demanding scripts, often with a very limited number of people available? Most of the time, the choice ends up being between <em>“we do this”</em> and <em>“that.”</em> And it shouldn’t, because, in these cases, I never saw accessibility winning in this equation.</p> <p>It shouldn’t be this way. You don’t need to be this way. First of all, because choosing between accessibility and anything else isn’t the right choice. Accessibility is no longer just another feature to be added to the others. It’s an added value for the business and, currently, a legal obligation that can have serious consequences for companies. On the other hand, there are intelligent, optimized, and impactful ways to incorporate accessibility principles into the natural dynamics of teams. It’s possible to work on accessibility without turning team operations upside down. In essence, that’s what AccessibilityOps does. <strong>Empowering people</strong> and <strong>providing teams with simple processes</strong> so they can <strong>integrate accessibility work into their daily routines</strong> without disproportionate effort.</p> Accessibility And Design <p>Working on digital accessibility in design can involve several actions. It’s clear that we need to pay particular attention to color and how it’s used to convey meaning. Of course, the interaction sizes of elements must be comfortable. But, most importantly, we must <strong>think about design from a versatile perspective</strong>. An interface isn’t a poster. We can control many aspects of that design, but how users interact with the interface is subject to an endless number of variables. The type of device, context, purpose, network quality, etc. All of this greatly affects each person’s experience and interaction. Along with all this, when digital accessibility concerns are brought into the design process, it adds even more variables.</p> <p><img src="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/01-assistive-technologies.png"></p> <p>People often use what are called <strong>assistive technologies and strategies</strong>. Basically, these are technological tools or, at the very least, “tricks” that people resort to in order to find more comfortable usage models. The famous screen readers, commonly associated with the use of blind people (but which are not only useful to them), for example, are an assistive technology. Changing colors or color contrasts between different elements is also an assistive technology. Increasing the font size (which we discussed in this text) is another example. There are countless assistive technologies and strategies. Almost as many as the different contexts of use for each person.</p> We Don’t Control Everything <p>In other words (and this is the “bad news” for us designers), “our design” is subject, from the users’ perspective, to transformations that we don’t control. It will be “transformed” by the user, ensuring that they can interact with the application and everything it offers in the most comfortable way possible. And that’s a good thing. If this happens and everything goes well, we will have surely done our accessibility work very well, and we all deserve congratulations. If the user applies any of these support technologies and strategies and still cannot use the digital application, it’s a sign that something is not working as it should.</p> <p>Oh, and speaking of which. Don’t even think about blocking the use of these technologies or support strategies. They may be “destroying” your beautiful design, but they are allowing more and more people to actually use the app. In the end, wasn’t that exactly what we promised we wanted to do? Design for (all) people. Without exception?</p> Increase Font Size <p>How many times have we heard someone — friends, family, or even colleagues — complaining that this or that text is too small? Text plays a very important role in the digital experience. Much information is conveyed through text: instructions for use, button captions, or interactive elements. All of this uses text as a communication tool. If reading all these elements is difficult, naturally, the experience is severely impaired.</p> <p>Comfortable text reading, regardless of its function, is a non-negotiable principle. This reading can be facilitated by using comfortable sizes in the design. However, supporting technologies and strategies, through the functionality of increasing font size, can also help improve readability. According to <a href="https://appt.org/en/stats/font-size">APPT</a> data, <strong>26% of Android and iOS mobile device users</strong> increase the default font size (data from February 2026). One in four users increases the font size on their smartphone. This is a very significant sample of people, making this functionality unavoidable in design processes.</p> <p><img src="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/02-chart.png"></p> Compliance With Guidelines <p>Increasing font size in interfaces can represent a huge design challenge. It’s important to understand that, suddenly, some text elements, due to user actions, can double in size from their initial size.</p> <blockquote>“With the exception of captions and text images, text can be resized without assistive technology up to 200% without loss of content or functionality.”<br><br>— <a href="https://acessibilidade.gov.pt/wcag/#resize-text">Success criterion 1.4.4, “Resizing Text”</a> of the Web Content Accessibility Guidelines (WCAG), version 2.2</blockquote> <p>This success criterion is at the AA compliance level, meaning this is an absolutely mandatory feature according to any legal framework.</p> <p>It’s easy to understand the 200% in this success criterion. If we assume we design the interfaces at a 100% scale, meaning the element size is the initial size, then increasing the text by up to 200% will correspond to doubling the initial size. Other enlargement scales can also be used, such as 120%, 140%, and so on. In other words, we have to ensure that users can increase the text to double its initial size through supporting technologies or strategies (and this is not a minor detail).</p> <p>To comply with this standard, we don’t need to provide text size increase tools in the interfaces. In practice, these features are nothing more than redundancy. Devices already allow this to be done in a standardized way. Users who really need this setting know it (because, without it, their lives would be much more difficult). Well, they already have this setting applied across their device. And that means we can eliminate these additional interface elements, simplifying the experience.</p> <p><img src="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/03-feature.png"></p> Standardized Access <p>An important concept to remember about assistive technologies, particularly in this case regarding increasing font size, is that most devices already have many of these tools installed by default. In other words, in many cases, users don’t need to purchase their own software or buy a specific type of device just to have this functionality.</p> <p>Whether on mobile devices or even in web browsers, in the vast majority of cases, it’s easy to find installed features that allow you to increase the default font size we’re using throughout the interface. This principle of increasing font size can be applied to digital products, such as apps, or even to any type of website running on the standard web browsers used today.</p> <h3>iPhones</h3> <p>On iPhone devices, the font size increase feature is integrated by default. To use this feature, simply access the “Settings” panel, select “Accessibility,” and within the “Vision” options group, access the “Text Size and Display” feature and configure the desired font size increase on that screen.</p> <p><img src="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/04-iphones.png"></p> <h3>Google Chrome</h3> <p>Web browsers also offer, by default, the functionality to increase font size. For example, in Google Chrome, this feature is available in the “Options” panel, specifically in the “Appearance” area. In the list of options that appear in this group, simply select the “Font size” option. Normally, the “Medium — Recommended” option will be selected. You can change this setting to any other available font size. Try, for example, the “Very large” option.</p> <p><img src="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/05-google-chrome.png"></p> Test In Figma <p>To ensure that digital accessibility work becomes effective in the daily lives of teams, it is essential to find <strong>simple work processes</strong>. Actions or initiatives that can be integrated into the team’s routine, that address accessibility in an integrated way, and do not require a dramatic transformation of the current reality. If that were necessary, he believes, it wouldn’t happen most of the time. Therefore, designing simple work processes is half the battle for accessibility to truly happen, in this case, also within a design team.</p> <p>Regarding testing font size increases in design, we have extraordinary tools at our disposal today. Those who remember the days of designing complex interfaces in <a href="https://www.adobe.com/pt/products/photoshop.html">Adobe Photoshop</a> will recognize the differences in the tools we have today (and thankfully so). It’s now possible, through tools like <a href="https://www.figma.com/design/">Figma</a>, to create such dynamism in design that testing font size increases for accessibility becomes almost unavoidable for the team.</p> <p><img src="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/06-hands-on.png"></p> <p><strong>Note</strong>: To take this test, you need to have a strong grasp of Figma’s <a href="https://help.figma.com/hc/en-us/articles/360039957034-Create-and-apply-text-styles">text styles</a>, <a href="https://help.figma.com/hc/en-us/articles/360040451373-Guide-to-auto-layout">auto layouts</a>, and <a href="https://help.figma.com/hc/en-us/articles/15339657135383-Guide-to-variables-in-Figma">variables</a>. These three are fundamental tools for success without much extra effort. If you haven’t yet mastered these features, it’s highly recommended that you start there. Don’t skip steps. Learning is a gradual process that must be followed in a structured, step-by-step manner.</p> <h3>Where Do We Want To Go?</h3> <p>The font size increase test in Figma that we want to perform is simple. We want to have a set of variables available for all the text styles we use in the interface, allowing us to choose whether we want to see the interface with the text at a scale of 100%, 120%, 140%, 160%, 180%, or 200%. As we apply this set of variables (much like applying variables for light and dark mode), we observe the transformations of the text in the interface and understand to what extent adaptations are needed in each version of the interface with different typographic scales.</p> <p><img src="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/07-font-scaling.png"></p> <h3>How Do We Make This Happen?</h3> <p>For this test to go so smoothly, you need to do some groundwork. <a href="https://dxd.pt/design-systems/">Design systems</a> can greatly help optimize much of this initial work. But I won’t lie to you. For the test to work well, your design needs to have a very serious level of organization and systematization.</p> <p>This isn’t really a guide, because each team will have its own work model, and these recommendations can be applied in different ways (and that’s okay). However, for this test to work, it’s important to ensure certain assumptions in the design. To help you phase the implementation of this test model, here are some steps to follow. Step-by-step instructions to guide you in organizing your files and ensuring you can fully execute this test in the simplest and most practical way possible.</p> <h3>1. Designing The Interfaces</h3> <p>It all starts with the design. Before any testing, the focus should, as it should, be on the design of each interface that we will want to test later. At this stage, there is still no specific concern with the font size increase test that we will perform later. Naturally, all interface design should, from the outset, follow the most basic <a href="https://www.a11yproject.com/checklist/">accessibility recommendations</a> applied to design.</p> <p><img src="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/08-design-screens.png"></p> <h3>2. Apply Auto Layouts To All Elements</h3> <p>In every screen design you create, you’ll need to ensure you apply auto layouts perfectly. This is a very important step. It’s this consistent application of auto layouts to the entire structure and design elements that will later guarantee the scalability of the interface when we start testing font size increases. You really can’t underestimate this step. If you don’t pay it the attention it deserves, you’ll see when we test typographic scaling in the interfaces, everything breaking down like an elephant in a china shop.</p> <p><img src="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/09-auto-layout.png"></p> <h3>3. Structuring And Applying Text Styles</h3> <p>To perform our font size increase test, we’ll also need you to have applied text styles to each interface design. You probably even started creating them as you were drawing. Great. If you haven’t done so, it’s important that you do it now. For the test to work perfectly, we really need this. Don’t leave any text element in the design without a text style applied.</p> <p><img src="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/10-text-styles.png"></p> <h3>4. Define The Set Of Variables 100%</h3> <p>This test forces a fairly high degree of optimization. In practice, this means we will have to use Figma variables for all the characteristics of the text styles we have in the interface. At this stage, you must define Figma “number” variables for at least the font-size and line-height of the text styles you applied to the drawing. With this step, you are defining the font size increase scale values for a 100% visualization model, that is, the initial and reference version of the drawing. It is important that you structure these variables for each text style in the drawing because, subsequently, we will have to consider the enlargement scale of each of these text elements.</p> <p><img src="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/11-variables-100-percent.png"></p> <h3>5. Apply The Variables To The Text Styles</h3> <p>Having defined the variables for the 100% scale text styles, you must now apply them to the elements of the text styles already created. Don’t forget to apply variables at least to the font-size and line-height characteristics. If you have more typographical variables, that’s fine. But you should at least have variables applied to font-size and line-height. This is really very important.</p> <p><img src="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/12-text-styles-variables.png"></p> <h3>6. Define The Variables For Increasing The Text Size</h3> <p>Now that you have the variables applied to the 100% scale text styles, the next step is to create the variables for the other font size increase scales. In practice, you have to create the variables that will tell the system what font size each text style will grow to when the increase scale is 120%, 140%, 160%, etc.</p> <p>To define the font-size and line-height values, simply multiply the initial value by the scale percentage. For example, if a text style has a font-size of 16px, the size for the 120% scale will be 16 multiplied by 1.2, which gives a result of 19.2. Repeat this calculation for all font-size and line-height values of the font size increase scale percentages you choose.</p> <p>You can also choose whether or not to apply rounding to the final values. This is an approximate test, and therefore any differences that may arise from rounding will not affect the final perception of the test result.</p> <p><img src="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/13-font-scaling-variables.png"></p> <h3>7. Apply Variables To Different Scale Versions</h3> <p>The moment of truth has arrived. The next step is to understand if we have everything working so that the test runs perfectly. Therefore, you should copy the original interface and apply the set of variables for each of the font size increase rates that make sense to you. Repeat this process for all the font size increase percentages you have defined.</p> <p>As a suggestion, you can use the 120%, 140%, 160%, 180%, and 200% increase percentages as a reference. If you want to simplify, you can reduce the number of scaling percentages you are working with. Regardless of the number of percentages you are working with, you should always work with the minimum of 100% and 200% scales.</p> <p><img src="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/14-apply-different-scales.png"></p> <h3>8. Identify Areas For Improvement</h3> <p>By applying different font size increase scales to the same screen, it’s easy to understand where improvements might be needed. This is where the real test of increasing font size in interface design and the most interesting accessibility work begins.</p> <p>In your analysis of the various screens, keep some important aspects in mind:</p> <ul> <li>The fact that the text appears gigantic isn’t a problem and doesn’t “ruin” the design. Remember that this can mean the difference between someone being able to use a particular product or service or not.</li> <li>An accessibility problem exists when increasing the font size makes it impossible for the user to read certain texts or to activate certain controls.</li> <li>For text elements that are already very large, increasing the font size might not make sense. Doing so could make those elements disproportionate, which wouldn’t improve readability (since they are already a good size) and would occupy completely unnecessary space.</li> <li>If there are elements that appear to be popping out of the screen, the first step is to confirm how you are applying <strong>auto layout</strong>. Many design aspects can be easily resolved with the proper use of auto layout.</li> <li>Regardless of the scale of font size increase, it is essential to maintain the <strong>visual hierarchy of the typography</strong>, as this readability is important for perceiving the different levels of information present on the screen.</li> <li>This test can help identify elements that may need adjustments directly in the code to function well at a given scale of increase. Not everything can be solved through design alone, and that’s perfectly fine. Accessibility is essentially a team effort.</li> </ul> <p><img src="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/15-critical-points.png"></p> <h3>9. Make Corrections And Adjustments To The Design</h3> <p>Finally, based on the various screens with different text enlargement scales applied, you can make the design changes that make sense. Some of these adjustments may only be necessary in code. In these cases, you document all these suggestions and pass them on to the development team. It is also crucial to reinforce (again) that some of the problems you may encounter in the design can be quickly resolved in the design process, with the simple and correct application of auto-layout properties.</p> <p><img src="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/16-make-changes.png"></p> <h3>10. Go Back To The Beginning And Repeat The Process</h3> <p>This is a cyclical approach. This means you should repeat these steps, or variations thereof, as many times as necessary throughout the project. It’s natural that, over time and with process optimization, some of these steps will cease to make sense. That’s absolutely not a problem. But the most important thing to realize here is that accessibility and this process of testing font size increases shouldn’t be done just once, and that’s it. It’s a test to be done many, many times throughout the day-to-day work of each project and team.</p> <p><img src="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/17-staring-point.png"></p> The Role Of Design Systems <p>At first glance, this list of steps might seem like a complex exercise. But it’s not. This is because the vast majority, if not all, of these steps are easy to execute in any context where a design system exists. In fact, design systems have become an <strong>unavoidable standard</strong> in the Product Design industry. We can discuss what each team calls a design system, but the truth is that it’s very difficult today to find a Product Design team that doesn’t have, at the very least, a minimally structured library of components and styles.</p> <p><img src="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/18-design-systems.png"></p> <p>With this foundation, whether more or less documented, it’s very easy to apply this type of font size increase test using Figma variables. Furthermore, if your design system already has, for example, structured variables for light and dark mode, it means you’re already applying the exact same principles we used to perform this test. So, nothing new.</p> <p>Working with design systems involves a level of <strong>structuring and organization</strong> that is also very useful for creating this type of test. There’s a myth that design systems limit creativity. This is not true. Design systems help solve the “bureaucratic” part of design, so we can actually have more time for what matters: in this case, testing accessibility and building more and more products and services that are truly accessible to the greatest number of people.</p> Example File <p>It’s always easier to see an example than just read a description of a process. If this is true in many disciplines of knowledge, in design, this premise makes even more sense. Therefore, in this <a href="https://www.figma.com/community/file/1600134823556764105">Figma file</a>, freely published and openly available to the community, you’ll find a <strong>practical example of the entire testing process</strong> described here. Remember that this is just an example. There may be countless ways to perform this type of test within the context of a Figma file.</p> <p><img src="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/19-community.png"></p> <p>Be sure to look at this approach with a critical eye. It’s a suggestion for testing font size increases that follows a specific process. Despite this, the approach should be adapted to your team’s specific reality, processes, and level of maturity. Simply copying formulas from other teams without understanding if they make sense in our own context is a sure way to make accessibility efforts disproportionate. Every situation is unique. This approach attempts to simplify accessibility work as much as possible in this specific context. And remember: if something happens, however small, it’s a step forward, not a step backward. And that should be celebrated by everyone on the team.</p>

Dropdowns Inside Scrollable Containers: Why They Break And How To Fix Them Properly

<p>The scenario is almost always the same, which is a data table inside a scrollable container. Every row has an action menu, a small dropdown with some options, like <strong>Edit</strong>, <strong>Duplicate</strong>, and <strong>Delete</strong>. You build it, it seems to work perfectly in isolation, and then someone puts it inside that scrollable <code>div</code> and things fall apart. I’ve seen this exact bug in three different codebases: the container, the stack, and the framework, all different. The bug, though, is totally identical.</p> <p>The dropdown gets clipped at the container’s edge. Or it shows up behind content that should logically be below it. Or it works fine until the user scrolls, and then it drifts. You reach for <code>z-index: 9999</code>. Sometimes it helps, but other times it does absolutely nothing. That inconsistency is the first clue that something deeper is happening.</p> <p>The reason it keeps coming back is that three separate browser systems are involved, and most developers understand each one on its own but never think about what happens when all three collide: <strong>overflow</strong>, <strong>stacking contexts</strong>, and <strong>containing blocks</strong>.</p> <p><img src="https://files.smashing.media/articles/dropdowns-scrollable-containers-why-break-how-fix/1-three-browser-systems-large.png"></p> <p>Once you understand how all three interact, the failure modes stop feeling random. In fact, they become predictable.</p> The Three Things Actually Causing This <p>Let’s look at each of those items in detail.</p> <h3>The Overflow Problem</h3> <p>When you set <code>overflow: hidden</code>, <code>overflow: scroll</code>, or <code>overflow: auto</code> on an element, the browser will clip anything that extends beyond its bounds, including absolutely positioned descendants.</p> <pre><code>.scroll-container { overflow: auto; height: 300px; /* This will clip the dropdown, full stop */ } .dropdown { position: absolute; /* Doesn't matter -- still clipped by .scroll-container */ } </code></pre> <p>That surprised me the first time I ran into it. I’d assumed <code>position: absolute</code> would let an element escape a container’s clipping. It doesn’t.</p> <p>In practice, that means an absolutely positioned menu can be cut off by any ancestor that has a non-visible overflow value, even if that ancestor isn’t the menu’s containing block. Clipping and positioning are separate systems. They just happen to collide in ways that look completely random until you understand both.</p> <p><img src="https://files.smashing.media/articles/dropdowns-scrollable-containers-why-break-how-fix/2-why-z-index-fails-large.png"></p> <p><img src="https://files.smashing.media/articles/dropdowns-scrollable-containers-why-break-how-fix/3-portal-pattern-dropdown-large.png"></p> <p>Here’s a React example using <code>createPortal</code>:</p> <div> <pre><code>import { createPortal } from 'react-dom'; import { useState, useEffect, useRef } from 'react'; function Dropdown({ anchorRef, isOpen, children }) { const [position, setPosition] = useState({ top: 0, left: 0 }); useEffect(() =&gt; { if (isOpen &amp;&amp; anchorRef.current) { const rect = anchorRef.current.getBoundingClientRect(); setPosition({ top: rect.bottom + window.scrollY, left: rect.left + window.scrollX, }); } }, [isOpen, anchorRef]); if (!isOpen) return null; return createPortal( &lt;div id="dropdown-demo" role="menu" className="dropdown-menu" style={{ position: 'absolute', top: position.top, left: position.left }} &gt; {children} &lt;/div&gt;, document.body ); } </code></pre> </div> <p><img src="https://files.smashing.media/articles/dropdowns-scrollable-containers-why-break-how-fix/4-fixed-positioning-large.png"></p> <p>And, of course, we can’t ignore accessibility. Fixed elements that appear over content must still be keyboard-reachable. If the focus order doesn’t naturally move into the fixed dropdown, you’ll need to manage it using code. It’s also worth checking that it doesn’t sit over other interactive content with no way to dismiss it. That one bites you in keyboard testing.</p> <h3>CSS Anchor Positioning: Where I Think This Is Heading</h3> <p><a href="https://css-tricks.com/css-anchor-positioning-guide/">CSS Anchor Positioning</a> is the direction I’m most interested in right now. I wasn’t sure how much of the spec was actually usable when I first looked at it. It lets you declare the relationship between a dropdown and its trigger directly in CSS, and the browser handles the coordinates.</p> <pre><code>.trigger { anchor-name: --my-trigger; } .dropdown-menu { position: absolute; position-anchor: --my-trigger; top: anchor(bottom); left: anchor(left); position-try-fallbacks: flip-block, flip-inline; } </code></pre> <p>The <code>position-try-fallbacks</code> property is what makes this worth using over a manual calculation. The browser tries alternative placements before giving up, so a dropdown at the bottom of the viewport automatically flips upward instead of getting cut off.</p> <p>Browser support is solid in Chromium-based browsers and growing in Safari. Firefox needs a <code>polyfill</code>. The <a href="https://github.com/oddbird/css-anchor-positioning"><code>@oddbird/css-anchor-positioning</code></a> package covers the core spec. I’ve hit layout edge cases with it that required fallbacks I didn’t anticipate, so treat it as a progressive enhancement or pair it with a JavaScript fallback for Firefox.</p> <p>In short, promising but not universal yet. Test in your target browsers.</p> <p>And as far as accessibility is concerned, declaring a visual relationship in CSS doesn’t tell the accessibility tree anything. <code>aria-controls</code>, <code>aria-expanded</code>, <code>aria-haspopup</code> — that part is still on you.</p> <h3>Sometimes The Fix Is Just Moving The Element</h3> <p>Before reaching for a portal or making coordinate calculations, I always ask one question first: Does this dropdown actually need to live inside the scroll container?</p> <p>If it doesn’t, moving the markup to a higher-level wrapper eliminates the problem entirely, with no JavaScript and no coordinate calculations.</p> <p>This isn’t always possible. If the button and dropdown are encapsulated in the same component, moving one without the other means rethinking the whole API. But when you can do it, there’s nothing to debug. The problem just doesn’t exist.</p> What Modern CSS Still Doesn’t Solve <p>CSS has come a long way here, but there are still places it lets you down.</p> <p>The <code>position: fixed</code> and <code>transform</code> issues are still there. It’s in the spec intentionally, which means no CSS workaround exists. If you’re using an animation library that wraps your layout in a transformed element, you’re back to needing portals or anchor positioning.</p> <p>CSS Anchor Positioning is promising, but new. As mentioned earlier, Firefox still needs a <code>polyfill</code> at the time I’m writing this. I’ve hit layout edge cases with it that required fallbacks I didn’t anticipate. If you need consistent behavior across all browsers today, you’re still reaching for JavaScript for the tricky parts.</p> <p>The addition I’ve actually changed my workflow for is the <a href="https://www.smashingmagazine.com/2026/03/getting-started-popover-api/">HTML Popover API</a>, now available in all modern browsers. Elements with the popover attribute render in the browser’s top layer, above everything, with no JavaScript positioning needed.</p> <div> <pre><code>&lt;button popovertarget="dropdown-demo"&gt;Open&lt;/button&gt; &lt;div id="dropdown-demo" popover="manual" role="menu"&gt;Popover content&lt;/div&gt; </code></pre> </div> <p>Escape handling, dismiss-on-click-outside, and solid accessibility semantics come free for things like tooltips, disclosure widgets, and simple overlays. It’s the first tool I reach for now.</p> <p>That said, it doesn’t solve positioning. It solves layering. You still need anchor positioning or JavaScript to align a popover to its trigger. The Popover API handles the layering. Anchor positioning handles the placement. Used together, they cover most of what you’d previously reach for a library to do.</p> A Decision Guide For Your Situation <p>After going through all of this the hard way, here’s how I actually think about the choice now.</p> <p><img src="https://files.smashing.media/articles/dropdowns-scrollable-containers-why-break-how-fix/5-dropdown-decision-guide-large.png"></p> <ul> <li> <strong>Use a portal.</strong><br>I’d use this when the trigger lives deep in nested scroll containers. I used this pattern for table action menus and paired it with focus restoration and accessibility checks. It’s the most reliable option, but budget time for the extra wiring.</li> <li> <strong>Use fixed positioning.</strong><br>This is for when you’re in vanilla JavaScript or a lightweight framework and can verify no ancestor applies transforms or filters. It’s simple to set up and simple to debug, as long as that one constraint holds.</li> <li> <strong>Use CSS Anchor Positioning.</strong><br>Reach for this when your browser support allows it. If Firefox support is required, pair it with the <code>@oddbird</code> polyfill. This is where the platform is ultimately heading and will eventually become your go-to approach.</li> <li> <strong>Restructure the DOM.</strong><br>Use this when the architecture permits it, and you want zero runtime complexity. I believe it’s likely the most underrated option.</li> <li> <strong>Combine patterns.</strong><br>Do this when you want anchor positioning as your primary approach, paired with a JavaScript fallback for unsupported browsers. Or a portal for DOM placement paired with <code>getBoundingClientRect()</code> for coordinate accuracy.</li> </ul> Conclusion <p>I used to treat this bug as a one-off issue — something to patch and move on from. But once I sat with it long enough to understand all three systems involved — <strong>overflow clipping</strong>, <strong>stacking contexts</strong>, and <strong>containing blocks</strong> — it stopped feeling random. I could look at a broken dropdown and immediately trace which ancestor was responsible. That shift in how I read the DOM was the real takeaway.</p> <p>There’s no single right answer. What I reached for depended on what I could control in the codebase: portals when the ancestor tree was unpredictable; fixed positioning when it was clean and simple; moving the element when nothing was stopping me; and anchor positioning now, where I can.</p> <p>Whatever you end up choosing, <strong>don’t treat accessibility as the last step</strong>. In my experience, that’s exactly when it gets skipped. The ARIA relationships, the focus management, the keyboard behavior — those aren’t polish. They’re part of what makes the thing actually work.</p> <p>Check out the full source code in <a href="https://github.com/BboyGT/DropDowns">my GitHub repo</a>.</p> <h3>Further Reading</h3> <p>These are the references I kept coming back to while working through this:</p> <ul> <li> <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Positioned_layout/Stacking_context">The Stacking Context</a> (MDN) </li> <li>“<a href="https://css-tricks.com/css-anchor-positioning-guide/">CSS Anchor Positioning Guide</a>”, Juan Diego Rodriguez</li> <li>“<a href="https://www.smashingmagazine.com/2026/03/getting-started-popover-api/">Getting Started With The Popover API</a>”, Godstime Aburu</li> <li> <a href="https://floating-ui.com/">Floating UI</a> (floating-ui.com)</li> <li> <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/overflow">CSS Overflow</a> (MDN)</li> </ul>

Modal vs. Separate Page: UX Decision Tree

<p>You probably have been there before. How do we choose between <strong>showing a modal</strong> to users, and when do we navigate them to a separate, new page? And does it matter at all?</p> <p>Actually, it does. The decision influences users’ flow, their context, their ability to look up details, and with it <strong>error frequency and task completion</strong>. Both options can be disruptive and frustrating — at the wrong time, and at the wrong place.</p> <p>So we’d better get it right. Well, let’s see how to do just that.</p> Modals vs. Dialogs vs. Overlays vs. Lightboxes <p>While we often speak about a single modal UI component, we often ignore fine, intricate nuances between all the different types of modals. In fact, <strong>not every modal is the same</strong>. Modals, dialogs, overlays, and lightboxes — all sound similar, but they are actually quite different:</p> <p><img src="https://files.smashing.media/articles/modal-separate-page-ux-decision-tree/2-modal-nonmodal-lightbox-nonlightbox-dialog-boxes.jpg"></p> <ul> <li> <strong>Dialog</strong><br>A generic term for “conversation” (user ↔ system).</li> <li> <strong>Overlay</strong><br>A small content panel displayed on top of a page.</li> <li> <strong>Modal</strong><br>User must interact with overlay + background <strong>disabled</strong>.</li> <li> <strong>Nonmodal</strong><br>User must interact with overlay + background <strong>enabled</strong>.</li> <li> <strong>Lightbox</strong><br>Dimmed background to focus attention on the modal.</li> </ul> <p>As Anna Kaley <a href="https://www.nngroup.com/articles/popups/">highlights</a>, most overlays appear at the wrong time, interrupt users during critical tasks, use poor language, and break users’ flow. They are <strong>interruptive by nature</strong>, and typically with a high level of severity without a strong need for that.</p> <p><img src="https://files.smashing.media/articles/modal-separate-page-ux-decision-tree/3-overlay-types-modal-non-modal-components.jpg"></p> <p>Surely users <em>must</em> be slowed down and interrupted if the consequences of their action have a high impact, but for most scenarios <strong>non-modals are much more subtle</strong> and a more friendly option to bring something to the user’s attention. If anything, I always suggest it to be a <strong>default</strong>.</p> Modals → For Single, Self-Contained Tasks <p>As designers, we often dismiss modals as irrelevant and annoying — <em>and often they are!</em> — yet they have their value as well. They can be very helpful to <strong>warn users about potential mistakes</strong> or help them avoid data loss. They can also help perform related actions or drill down into details without interrupting the current state of the page.</p> <p>But the biggest advantage of modals is that they help users <strong>keep the context</strong> of the current screen. It doesn’t mean just the UI, but also edited input, scrolling position, state of accordions, selection of filters, sorting, and so on.</p> <p><img src="https://files.smashing.media/articles/modal-separate-page-ux-decision-tree/4-nonmodal.png"></p> <p>At times, users need to <strong>confirm a selection quickly</strong> (e.g., filters as shown above) and then proceed immediately from there. Auto-save can achieve the same, of course, but it’s not always needed or desired. And blocking the UI is often not a good idea.</p> <p>However, modals aren’t used for any tasks. Typically, we use them for <strong>single, self-contained tasks</strong> where users should jump in, complete a task, and then return to where they were. Unsurprisingly, they do work well for high-priority, short interactions (e.g., alerts, destructive actions, quick confirmations).</p> <p><strong>When modals help</strong>:</p> <p>🚫 Modals are often disruptive, invasive, and confusing.<br>🚫 They make it difficult to compare and copy-paste.<br>✅ Yet modals allow users to maintain multiple contexts.<br>✅ Useful to prevent irreversible errors and data loss.<br>✅ Useful if sending users to a new page would be disruptive. </p> <p>✅ Show a modal only if users will value the disruption.<br>✅ By default, prefer non-blocking dialogs (“nonmodals”).<br>✅ Allow users to minimize, hide, or restore the dialog later.<br>✅ Use a modal to slow users down, e.g., verify complex input.<br>✅ Give a way out with “Close”, ESC key, or click outside the box.</p> Pages → For Complex, Multi-Step Workflows <p>Wizards or <strong>tabbed navigation within modals</strong> doesn’t work too well, even in complex enterprise products — there, side panels or drawers typically work better. Troubles start when users need to compare or reference data points — yet modals block this behavior, so they re-open the same page in multiple tabs instead.</p> <p><img src="https://files.smashing.media/articles/modal-separate-page-ux-decision-tree/5-modal.jpg"></p> <p>For more complex flows and multi-step processes, <strong>standalone pages work best</strong>. Pages also work better when they demand the user’s full attention, and reference to the previous screen isn’t very helpful. And drawers work for sub-tasks that are too complex for a simple modal, but don't need a full page navigation.</p> <p><strong>When to avoid modals</strong>:</p> <p>🚫 Avoid modals for <strong>error messages</strong>.<br>🚫 Avoid modals for <strong>feature notifications</strong>.<br>🚫 Avoid modals for <strong>onboarding experience</strong>.<br>🚫 Avoid modals for complex, <strong>lengthy multi-step-tasks</strong>.<br>🚫 Avoid <strong>multiple nested modals</strong> and use prev/next instead.<br>🚫 Avoid <strong>auto-triggered modals</strong> unless absolutely necessary.</p> Avoid Both For Repeated Tasks <p>In many complex, task-heavy products, users will find themselves performing the same tasks repeatedly, over and over again. There, <strong>both modals and new page navigations add friction</strong> because they interrupt the flow or force users to gather missing data between all the different tabs or views.</p> <p>Too often, users end up with a broken experience, full of never-ending confirmations, exaggerated warnings, verbose instructions, or just missing reference points. As <a href="https://www.linkedin.com/feed/update/urn:li:activity:7417845782365560832/?dashCommentUrn=urn%3Ali%3Afsd_comment%3A%287417848602338902016%2Curn%3Ali%3Aactivity%3A7417845782365560832%29">Saulius Stebulis mentioned</a>, in these scenarios, <strong>expandable sections</strong> or <strong>in-place editing</strong> often work better — they keep the task anchored to the current screen.</p> <p>In practice, in many scenarios, users don’t complete their tasks in isolation. They need to look up data, copy-paste values, refine entries in different places, or just review similar records as they work through their tasks.</p> <p>Overlays and drawers are more helpful in maintaining access to background data during the task. As a result, the context always stays in its place, available for reference or copy-paste. Save modals and page navigation for moments where the interruption genuinely adds value — especially to prevent critical mistakes.</p> Modals vs. Pages: A Decision Tree <p>A while back, Ryan Neufeld put together a <a href="https://uxplanet.org/modal-vs-page-a-decision-making-framework-34453e911129">very helpful guide</a> to help designers <strong>choose between modals and pages</strong>. It comes with a handy <a href="https://miro.medium.com/v2/1*JQSGKbw1_iv5b85xYyNL-Q.png">PNG cheatsheet</a> and a <a href="https://docs.google.com/spreadsheets/d/1fZhXsV-IFWM0ZuMLLc8gG1BXqeQxFkCoYvSJt0gl2II/edit?gid=150659778#gid=150659778">Google Doc template</a> with questions broken down across 7 sections.</p> <p>It’s lengthy, extremely thorough, but very easy to follow:</p> <p><img src="https://files.smashing.media/articles/modal-separate-page-ux-decision-tree/6-decision-tree-diagram-ui-design.png"></p> <p>It might look daunting, but it's a quite simple <strong>4-step process</strong>:</p> <ol> <li> <strong>Context of the screen</strong>.<br>First, we check if users need to maintain the context of the underlying screen.</li> <li> <strong>Task complexity and duration</strong>.<br>Simpler, focused, non-distracting tasks could use a modal, but long, complex flows need a page.</li> <li> <strong>Reference to underlying page</strong>.<br>Then, we check if users often need to refer to data in the background or if the task is a simple confirmation or selection.</li> <li> <strong>Choosing the right overlay</strong>.<br>Finally, if an overlay is indeed a good option, it guides us to choose between modal or nonmodal (leaning towards a nonmodal).</li> </ol> Wrapping Up <p>Whenever possible, avoid blocking the entire UI. Have a dialog floating, partially covering the UI, but allowing navigation, scrolling, and copy-pasting. Or show the contents of the modal as a side drawer. Or use a vertical accordion instead. Or bring users to a separate page if you need to show a lot of detail.</p> <p>But if you want to boost users’ efficiency and speed, <strong>avoid modals at all costs</strong>. Use them to slow users down, to bundle their attention, to prevent mistakes. As <a href="https://www.nngroup.com/articles/modal-nonmodal-dialog/">Therese Fessenden noted</a>, no one likes to be interrupted, but if you must, make sure it’s absolutely worth the cost.</p> Meet “Smart Interface Design Patterns” <p>You can find a <strong>whole section about modals</strong> and alternatives in <a href="https://smart-interface-design-patterns.com/"><strong>Smart Interface Design Patterns</strong></a>, our <strong>15h-video course</strong> with 100s of practical examples from real-life projects — with a live UX training later this year. Everything from mega-dropdowns to complex enterprise tables — with 5 new segments added every year. <a href="https://www.youtube.com/watch?v=jhZ3el3n-u0">Jump to a free preview</a>. Use code <a href="https://smart-interface-design-patterns.com/"><strong>BIRDIE</strong></a> to <strong>save 15%</strong> off.</p> <a href="https://smart-interface-design-patterns.com/"><img src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/7cc4e1de-6921-474e-a3fb-db4789fc13dd/b4024b60-e627-177d-8bff-28441f810462.jpeg"></a>Meet <a href="https://smart-interface-design-patterns.com/">Smart Interface Design Patterns</a>, our video course on interface design &amp; UX. <div><div> <ul> <li><a href="https://www.smashingmagazine.com/#"> Video + UX Training</a></li> <li><a href="https://www.smashingmagazine.com/#">Video only</a></li> </ul> <div> <h3>Video + UX Training</h3>$ 579.00 $ 699.00 <a href="https://smart-interface-design-patterns.thinkific.com/enroll/1645405?price_id=2163032"> Get Video + UX Training<div></div></a><p>25 video lessons (15h) + <a href="https://smashingconf.com/online-workshops/workshops/vitaly-friedman-impact-design/">Live UX Training</a>.<br>100 days money-back-guarantee.</p> </div> <div> <h3>Video only</h3> <div>$ 275.00$ 350.00</div> <a href="https://smart-interface-design-patterns.thinkific.com/enroll/1645405?et=paid"> Get the video course<div></div></a><p>40 video lessons (15h). Updated yearly.<br>Also available as a <a href="https://smart-interface-design-patterns.thinkific.com/enroll/3082557?price_id=3951421">UX Bundle with 2 video courses.</a></p> </div> </div></div> Useful Resources <ul> <li> <a href="https://www.nngroup.com/articles/popups/">Different Types of Popups</a>, by Anna Kaley</li> <li> <a href="https://app.uxcel.com/courses/ui-components-n-patterns/modals--dialogs-best-practices-166">Best Practices for Designing UI Modals</a>, by Uxcel</li> <li> <a href="https://modalzmodalzmodalz.com/">We Use Too Many Damn Modals: UX Guidelines</a>, by Adrian Egger</li> <li> <a href="https://www.nngroup.com/articles/modal-nonmodal-dialog/">Modal &amp; Nonmodal Dialogs</a>, by Therese Fessenden</li> <li> <a href="https://medium.com/pulsar/modern-enterprise-ui-design-part-2-modal-dialogs-2ccd3cc33c92">Modern Enterprise UI Design: Modal Dialogs</a>, by James Jacobs</li> <li><a href="https://designsystems.surf/components/modal">Modals in Design Systems</a></li> </ul>

Anime vs. Marvel/DC: Designing Digital Products With Emotion In Flow

<p>Design isn’t only pixels and patterns. It’s pacing and feelings, too. Some products feel cinematic as they guide us through uncertainty, relief, confidence, and calm without yanking us around. That’s <strong>Emotion in Flow</strong>. Others undercut their own moments with a joke in the wrong place, a surprise pop-up, or a jumpy transition. That’s <strong>Emotion in Conflict</strong>.</p> <p>These aren’t UX-only ideas. You can see them everywhere in entertainment. And the clearest way to feel the difference is to compare how <strong>anime</strong> handles emotional shifts versus how <strong>Marvel and DC films</strong> stumble. We’ll use two specific examples, one from <em>Dan da Dan</em> (anime series on Netflix) and one from James Gunn’s <em>Superman</em> movie, to define the two concepts, and then translate them into practical product design patterns you can apply right away.</p> <p><strong>Note</strong>: <em>We’ll focus on</em> <strong><em>digital products</em></strong>, <em>including apps, SaaS, and web.</em></p> Emotion In Flow (Anime: Dan da Dan) <p>In <em>Dan da Dan</em>, the tonal range is wild, horror, comedy, tenderness, yet it <strong>flows</strong>.</p> <p>Example: In one arc, the protagonists are on a bizarre, comedic quest involving the “golden genitals” of one of the main characters (yes, really), and in another, we’re drawn into a heartbreaking story of a mother whose child is kidnapped. On paper, that shift should be a car crash. On screen, it’s coherent and emotionally legible.</p> <p>Why does this work on screen?</p> <ul> <li> <strong>Continuity of stakes.</strong><br>Even when a gag lands, the characters’ goals and danger stay intact. Humor releases tension after a mini‑resolution; it doesn’t deny the threat.</li> <li> <strong>Clear mood cues.</strong><br>Music, framing, pacing, and character reactions telegraph the next feeling. You’re primed for the shift, so you ride it rather than getting yanked.</li> <li> <strong>One emotional anchor.</strong><br>Relationships remain the North Star, so the scene’s heart doesn’t get lost when the tone moves.</li> </ul> <p><strong>How does this translate to UX?</strong></p> <p>Good products do the same: <strong>prepare</strong>, <strong>transition</strong>, <strong>resolve</strong>, so users stay immersed as the emotional tone shifts.</p> <p><img src="https://files.smashing.media/articles/anime-marvel-dc-designing-digital-products-emotion-flow/1-dan-da-dan.jpg"></p> Emotion In Conflict (Marvel/DC: James Gunn’s Superman) <p>Lois &amp; Clark are having a heartfelt, intimate conversation, a slow, human moment, while in the background a running gag plays out (a monster getting clobbered with a giant baseball bat). The gag steals the focus right when the scene asks you to feel something real. The result is a tonal clash that punctures the emotion instead of releasing it.</p> <p>Why does this fail on screen?</p> <ul> <li> <strong>Increased cognitive load.</strong><br>What’s happening here maps directly to cognitive load theory. When a scene (or interface) asks users to process two competing emotional signals at once, it introduces <em>extraneous cognitive load</em>, mental effort that has nothing to do with the task or moment itself. Instead of focusing on the emotional beat, attention is split between signals that don’t resolve each other. In products, this is what happens when humor, promotions, or unexpected UI changes intrude on high-stakes moments: users are forced to interpret tone and intent at the same time they’re trying to act, which slows comprehension and increases stress.</li> <li> <strong>Competing beats at the same time.</strong><br>The joke overlaps the climax of a serious beat; the audience pays attention to the switch rather than the feeling.</li> <li> <strong>No tonal handoff.</strong><br>There’s no transition that lands the intimacy before humor arrives, so the moment feels undercut rather than resolved.</li> </ul> <p><strong>How does this translate to UX?</strong></p> <p>In products, this is the confetti-before-confirmation problem, the cheeky error in a money flow, or the promo modal that appears right in the middle of a critical task. This also spikes cognitive load: users must process the humor while trying to fix a problem, which slows them down and increases stress.</p> <p><img src="https://files.smashing.media/articles/anime-marvel-dc-designing-digital-products-emotion-flow/2-superman.jpg"></p> Quick Definitions <blockquote> <strong>Emotion in Flow</strong><br>Emotional shifts feel earned, telegraphed, and timed so they resolve prior beats. Immersion holds.<br><br><strong>Emotion in Conflict</strong><br>A jarring switch (or hard cut) that punctures a live emotional beat. Immersion breaks.</blockquote> <p>Now that we’ve named it: how does this connect to UX?</p> How Emotions Shape Product Memorability <p>People don’t remember the average of an experience; they remember peaks and the ending. If your flow’s peak is frustration, or your ending is messy, that’s what sticks. So design the emotional curve on purpose.</p> <p>Emotions live across three layers (from <a href="https://www.academia.edu/27771503/Emotional_Design_Donald_Norman">Don Norman’s Emotional Design</a>), and your product needs to line them up:</p> <ul> <li> <strong>Visceral (gut):</strong> First-impression signals: visuals, motion, haptics, sound.<br><em>Examples:</em> A steady skeleton loader calms more than a jittery spinner; a gentle success chime/haptic tap lets the win land without shouting; consistent easing/direction tells the eye what changed.</li> <li> <strong>Behavioral (doing):</strong> Can I complete my task smoothly? Friction here means stress.<br><em>Examples:</em> Three clear payment steps with predictable progress; error states that explain what happened and how to recover; inline validation instead of end-of-form explosions.</li> <li> <strong>Reflective (meaning):</strong> The story I tell myself after, <em>“Was that worth it? Do I trust this?”</em><br><em>Examples:</em> A tidy wrap-up screen (“Done. You’ll get X by Friday.”) gives closure; a small recap (“You saved €18 this year”) creates pride without fireworks.</li> </ul> <p><a href="https://www.nngroup.com/articles/microinteractions/#toc-what-are-microinteractions-1">Microinteractions</a> are the emotional glue. Each one has a trigger (I tap Pay), rules (what the system does), feedback (progress and a clear result), and loops or modes (what happens if the user tries again). Get these right, and your transitions bridge feelings. Get them wrong, and they break the flow.</p> <p><img src="https://files.smashing.media/articles/anime-marvel-dc-designing-digital-products-emotion-flow/3-emotional-beat-curve.jpg"></p> <p>The emotional beat sheet maps cleanly onto Norman’s layers of experience:</p> <ul> <li> <strong>Uncertainty</strong> lives in the <strong>visceral</strong> and early <strong>behavioral</strong> layers, where users rely on sensory cues (motion, clarity, feedback) to understand what’s happening.</li> <li> <strong>Clarity</strong> is firmly in the <strong>behavioral</strong> layer, the moment when the system’s intent and the user’s next action lock into place.</li> <li> <strong>Anticipation</strong> is a blend of <strong>behavioral</strong> (the user is doing something with purpose) and <strong>reflective</strong> (the user is already predicting the outcome and imagining what comes next).</li> <li> <strong>Achievement</strong> is a <strong>reflective peak</strong>, where the user evaluates success, trust, and whether the experience “felt right.”</li> <li> <strong>Calm/Closure</strong> is primarily <strong>reflective</strong>, helping users wrap up the meaning of the interaction and decide if the product is trustworthy and worth returning to.</li> </ul> <p>In real products, this sequence doesn’t disappear when things go wrong. Errors, latency, and degraded states are not exceptions to the emotional arc — they are part of it. Seen through a narrative lens, these moments are the obstacles in the hero’s journey. A well-designed recovery state acknowledges the setback, clarifies what happened, and guides the next step without introducing new emotional noise. When failure is treated as a beat instead of a rupture, emotional flow can be preserved even under stress.</p> UX Examples: Emotion In Flow vs. Emotion In Conflict <h3>Emotion In Flow</h3> <p>Checkout done right (Stripe/Apple Pay style): short steps, clear progress, and a crisp success state (a checkmark with an optional soft haptic). The peak (success) lands, and the end gives closure (receipt or next step).</p> <p><img src="https://files.smashing.media/articles/anime-marvel-dc-designing-digital-products-emotion-flow/4-emotion-in-flow.jpg"></p> <p>Pickup status (ride‑hailing apps, e.g., Uber, Free Now, or Bolt): progressive updates maintain orientation and reduce anxiety (“Driver arriving”, “2 min away”, “Arrived”). Uncertainty turns into clarity, with gentle motion preparing each transition.</p> <p><img src="https://files.smashing.media/articles/anime-marvel-dc-designing-digital-products-emotion-flow/5-emotion-in-flow-uber.jpg"></p> <h3>Emotion In Conflict</h3> <p><strong>Note</strong>: <em>We’re not naming specific products here — we respect the work behind them. Instead, we’re showing the patterns that cause emotional conflict and exactly how to fix them.</em></p> <ul> <li> <strong>Jokes in serious moments.</strong><br>Cheeky copy-in-error states for money/health/security. Users are stressed; humor amplifies irritation.</li> <li> <strong>Celebration before resolution.</strong><br>Confetti, fireworks, or loud sounds before confirmation. The party interrupts the climax.</li> <li> <strong>Hard state jumps.</strong><br>Surprise modals/promos mid‑task, full‑screen takeovers without preparation. Feels like an abrupt cut during an emotional beat.</li> </ul> <p><img src="https://files.smashing.media/articles/anime-marvel-dc-designing-digital-products-emotion-flow/6-emotion-in-conflict.jpg"></p> What You Can Do To Ensure Emotion in Flow <p>Here’s a Notion page with the full template you can duplicate:</p> <ul> <li> <a href="https://ludicrous-maraca-88d.notion.site/Emotional-Beat-Sheet-Template-2b9b9dbc8bf080dc8c63c77c42c66242?source=copy_link">Emotional beat sheet template</a>.</li> </ul> <h3>1. Write The Emotional Beat Sheet First</h3> <p>For each core flow (onboarding, payment, recovery), map the feelings per step: uncertainty → clarity → anticipation → achievement → calm. Attach copy, motion, and microinteractions to each beat. (Who carries the emotion where?)</p> <h3>2. Align Tone With Task Risk</h3> <p>Create a tone matrix (risk level × state). In high‑risk errors, be calm, plain, and solution‑oriented. Save playfulness for low‑risk contexts.</p> <p>Template snippets:</p> <ul> <li> <strong>High‑risk error</strong>: “We couldn’t verify your ID. Try again or contact support.”</li> <li> <strong>Low‑risk empty state</strong>: “Nothing here yet. Want to start with a sample?”</li> </ul> <p>This is where many mature products quietly drift into emotional conflict. Over time, teams add delight by habit rather than intent.</p> <p>A useful self-check is to ask: If we removed every playful or celebratory element from this step, would the flow still feel humane — or were those elements masking friction?</p> <p>Good emotional design clarifies experience; great emotional design doesn’t need decoration to compensate for confusion.</p> <h3>3. Design Peak And End On Purpose</h3> <p>Engineer one clear peak (the moment of success) and one clean end (confirmation and what happens next). Measure recall and satisfaction at both points.</p> <h3>4. Use Microinteractions As Bridges, Not Spotlights</h3> <ul> <li>Prepare: Small, consistent motion hints before a big state change.</li> <li>Confirm: Success gets a subtle settle, with a slightly slower ease-out and an optional light haptic.</li> <li>Recover: Repeated failure gracefully shifts tone from upbeat to supportive and guides the next step.</li> </ul> <h3>5. Test For Emotional Continuity</h3> <p>In usability sessions, don’t just ask <em>“Was that easy?”</em> Instead, you can ask <em>“What feeling changed here?”</em> If you hear “confused → amused → confused,” you’ve got conflict, not flow. Iterate transitions, not just screens.</p> How To Avoid Emotion in Conflict: Fast Checklist <p>Red flags → fixes:</p> <ul> <li>Jokes in serious moments → swap for calm, direct language, and a clear recovery path.</li> <li>Celebration before resolution → move celebration to after confirmation; tone it down for high‑risk tasks.</li> <li>Hard state jumps → pre‑announce transitions; keep framing consistent; use meaningful motion to preserve continuity.</li> <li>Cross‑team tone drift → centralize voice &amp; tone guidelines with examples per risk level and state.</li> </ul> <p>There are moments when breaking emotional flow is intentional and necessary. Security warnings, legal confirmations, and safety-critical alerts often benefit from abrupt tonal shifts. In these cases, disruption signals importance and demands attention. The problem isn’t emotional conflict itself; it’s <strong>accidental conflict</strong>. When designers choose disruption deliberately, users understand the stakes instead of feeling whiplash.</p> Conclusion <p><strong>Great experiences are directed experiences.</strong> Dan da Dan shows how to move through feelings without losing us: it prepares, transitions, and resolves. The Superman scene shows the opposite: a gag colliding with a heartfelt beat.</p> <p>Do the former. Map your emotional beats, align tone to task risk, and let microinteractions bridge feelings so users remember the right peak and the right end, not the whiplash in the middle.</p>

Moving From Moment.js To The JS Temporal API

<p>Almost any kind of application written in JavaScript works with times or dates in some capacity. In the beginning, this was limited to the built-in <code>Date</code> API. This API includes basic functionality, but is quite limited in what it can do.</p> <p>Third-party libraries like Moment.js, and later built-in APIs such as the <code>Intl</code> APIs and the new <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal">Temporal API</a>, add much greater flexibility to working with times and dates.</p> The Rise And Fall Of Moment.js <p><a href="https://momentjs.com/">Moment.js</a> is a JavaScript library with powerful utilities for working with times and dates. It includes missing features from the basic <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date">Date API</a>, such as time zone manipulation, and makes many common operations simpler. Moment also includes functions for formatting dates and times. It became a widely used library in many different applications.</p> <p>However, Moment also had its share of issues. It’s a large library, and can add significantly to an application’s bundle size. Because the library doesn’t support tree shaking (a feature of modern bundlers that can remove unused parts of libraries), the entire Moment library is included even if you only use one or two of its functions.</p> <p>Another issue with Moment is the fact that the objects it creates are <em>mutable</em>. Calling certain functions on a Moment object has side effects and mutates the value of that object. This can lead to unexpected behavior or bugs.</p> <p>In 2020, the maintainers of Moment decided to put the library into maintenance mode. No new feature development is being done, and the maintainers recommend against using it for new projects.</p> <p>There are other JavaScript date libraries, such as <code>date-fns</code>, but there’s a new player in town, an API built directly into JavaScript: <strong>Temporal</strong>. It’s a new standard that fills in the holes of the original <code>Date</code> API as well as solves some of the limitations found in Moment and other libraries.</p> What Is Temporal? <p>Temporal is a new time and date API being added to the ECMAScript standard, which defines modern JavaScript. As of March 2026, it has reached Stage 4 of the TC39 process (the committee that oversees proposals and additions to the JavaScript language), and will be included in the next version of the ECMAScript specification. It has already been implemented in several browsers: <a href="https://developer.chrome.com/release-notes/144">Chrome</a> <a href="https://developer.chrome.com/release-notes/144">144+</a> and <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/139#javascript">Firefox</a> <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/139#javascript">139+</a>, with <a href="https://bugs.webkit.org/show_bug.cgi?id=223166">Safari expected to follow soon</a>. A <a href="https://github.com/js-temporal/temporal-polyfill">polyfill is also available</a> for unsupported browsers and Node.js.</p> <p>The Temporal API creates objects that, generally, represent moments in time. These can be full-time and date stamps in a given time zone, or they can be a generic instance of “wall clock” time without any time zone or date information. Some of the main features of Temporal include:</p> <ul> <li> <strong>Times with or without dates.</strong><br>A Temporal object can represent a specific time on a specific date, or a time without any date information. A specific date, without a time, can also be represented.</li> <li> <strong>Time zone support.</strong><br>Temporal objects are fully time zone aware and can be converted across different time zones. Moment supports time zones, too, but it requires the additional <code>moment-timezone</code> library.</li> <li> <strong>Immutability.</strong><br>Once a Temporal object is created, it cannot be changed. Time arithmetic or time zone conversions do not modify the underlying object. Instead, they generate a new Temporal object.</li> <li> <strong>1-based indexing.</strong><br>A common source of bugs with the Date API (as well as with Moment) is that months are zero-indexed. This means that January is month <code>0</code>, rather than month <code>1</code> as we all understand in real life. Temporal fixes this by using 1-based indexing — January is month <code>1</code>.</li> <li> <strong>It’s built into the browser.</strong><br>Since Temporal is an API in the browser itself, it adds nothing to your application’s bundle size.</li> </ul> <p>It’s also important to note that the Date API isn’t going away. While Temporal supersedes this API, it is not being removed or deprecated. Many applications would break if browsers suddenly removed the Date API. However, also keep in mind that Moment is now considered a legacy project in maintenance mode.</p> <p>In the rest of the article, we’ll look at some “recipes” for migrating Moment-based code to the new Temporal API. Let’s start refactoring!</p> Creating Date And Time Objects <p>Before we can manipulate dates and times, we have to create objects representing them. To create a Moment object representing the current date and time, use the <code>moment</code> function.</p> <pre><code>const now = moment(); console.log(now); // Moment&lt;2026-02-18T21:26:29-05:00&gt; </code></pre> <p>This object can now be formatted or manipulated as needed.</p> <div> <pre><code>// convert to UTC // warning: This mutates the Moment object and puts it in UTC mode! console.log(now.utc()); // Moment&lt;2026-02-19T02:26:29Z&gt; // print a formatted string - note that it's using the UTC time now console.log(now.format('MM/DD/YYYY hh:mm:ss a')); // 02/19/2026 02:27:07 am </code></pre> </div> <p>The key thing to remember about Moment is that a Moment object always includes information about the time <em>and</em> the date. If you only need to work with time information, this is usually fine, but it can cause unexpected behavior in situations like Daylight Saving Time or leap years, where the date can have an effect on time calculations.</p> <p>Temporal is more flexible. You can create an object representing the current date and time by creating a <code>Temporal.Instant</code> object. This represents a point in time defined by the time since “the epoch” (midnight UTC on January 1, 1970). Temporal can reference this instant in time with nanosecond-level precision.</p> <pre><code>const now = Temporal.Now.instant(); // see raw nanoseconds since the epoch console.log(now.epochNanoseconds); // 1771466342612000000n // format for UTC console.log(now.toString()); // 2026-02-19T01:55:27.844Z // format for a particular time zone console.log(now.toString({ timeZone: 'America/New_York' })); // 2026-02-18T20:56:57.905-05:00 </code></pre> <p><code>Temporal.Instant</code> objects can also be created for a specific time and date by using the <code>from</code> static method.</p> <div> <pre><code>const myInstant = Temporal.Instant.from('2026-02-18T21:10:00-05:00'); // Format the instant in the local time zone. Note that this only controls // the formatting - it does not mutate the object like <code>moment.utc</code> does. console.log(myInstant.toString({ timeZone: 'America/New_York' })); // 2026-02-18T21:10:00-05:00 </code></pre> </div> <p>You can also create other types of Temporal objects, including:</p> <ul> <li> <strong><code>Temporal.PlainDate</code></strong>: A date with no time information.</li> <li> <strong><code>Temporal.PlainTime</code></strong>: A time with no date information.</li> <li> <strong><code>Temporal.ZonedDateTime</code></strong>: A date and time in a specific time zone.</li> </ul> <p>Each of these has a <code>from</code> method that can be called with an object specifying the date and/or time, or a date string to parse.</p> <pre><code>// Just a date const today = Temporal.PlainDate.from({ year: 2026, month: 2, // note we're using 2 for February day: 18 }); console.log(today.toString()); // 2026-02-18 // Just a time const lunchTime = Temporal.PlainTime.from({ hour: 12 }); console.log(lunchTime.toString()); // 12:00:00 // A date and time in the US Eastern time zone const dueAt = Temporal.ZonedDateTime.from({ timeZone: 'America/New_York', year: 2026, month: 3, day: 1, hour: 12, minute: 0, second: 0 }); console.log(dueAt.toString()); // 2026-03-01T12:00:00-05:00[America/New_York] </code></pre> Parsing <p>We’ve covered programmatic creation of date and time information. Now let’s look at parsing. Parsing is one area where Moment is more flexible than the built-in Temporal API. </p> <p>You can parse a date string by passing it to the <code>moment</code> function. With a single argument, Moment expects an ISO date string, but you can use alternative formats if you provide a second argument specifying the date format being used.</p> <div> <pre><code>const isoDate = moment('2026-02-21T09:00:00'); const formattedDate = moment('2/21/26 9:00:00', 'M/D/YY h:mm:ss'); console.log(isoDate); // Moment&lt;2026-02-21T09:00:00-05:00&gt; console.log(formattedDate); // Moment&lt;2026-02-21T09:00:00-05:00&gt; </code></pre> </div> <p>In older versions, Moment would make a best guess to parse any arbitrarily formatted date string. This could lead to unpredictable results. For example, is <code>02-03-2026</code> February 2 or March 3? For this reason, newer versions of Moment display a prominent deprecation warning if it’s called without an ISO formatted date string (unless the second argument with the desired format is also given).</p> <p>Temporal will only parse a specifically formatted date string. The string must be compliant with the ISO 8601 format or its extension, RFC 9557. If a non-compliant date string is passed to a <code>from</code> method, Temporal will throw a <code>RangeError</code>.</p> <div> <pre><code>// Using an RFC 9557 date string const myDate = Temporal.Instant.from('2026-02-21T09:00:00-05:00[America/New_York]'); console.log(myDate.toString({ timeZone: 'America/New_York' })); // 2026-02-21T09:00:00-05:00 // Using an unknown date string const otherDate = Temporal.Instant.from('2/21/26 9:00:00'); // RangeError: Temporal error: Invalid character while parsing year value. </code></pre> </div> <p>The exact requirements of the date string depend on which kind of Temporal object you’re creating. In the above example, <code>Temporal.Instant</code> requires a full ISO 8601 or RFC 9557 date string specifying the date and time with a time zone offset, but you can also create <code>PlainDate</code> or <code>PlainTime</code> objects using just a subset of the date format.</p> <pre><code>const myDate = Temporal.PlainDate.from('2026-02-21'); console.log(myDate.toString()); // 2026-02-21 const myTime = Temporal.PlainTime.from('09:00:00'); console.log(myTime.toString()); // 09:00:00 </code></pre> <p>Note that these strings must still comply with the expected format, or an error will be thrown.</p> <div> <pre><code>// Using a non-compliant time strings. These will all throw a RangeError. Temporal.PlainTime.from('9:00'); Temporal.PlainTime.from('9:00:00 AM'); </code></pre> </div> <blockquote> <strong>Pro tip: Handling non-ISO strings</strong><br><br>Because Temporal prioritizes reliability, it won’t try to guess the format of a string like <code>02-01-2026</code>. If your data source uses such strings, you will need to do some string manipulation to rearrange the values into an ISO string like <code>2026-02-01</code> before attempting to use it with Temporal.</blockquote> Formatting <p>Once you have a Moment or Temporal object, you’ll probably want to convert it to a formatted string at some point. </p> <p>This is an instance where Moment is a bit more terse. You call the object’s <code>format</code> method with a string of tokens that describe the desired date format. </p> <pre><code>const date = moment(); console.log(date.format('MM/DD/YYYY')); // 02/22/2026 console.log(date.format('MMMM Do YYYY, h:mm:ss a')); // February 22nd 2026, 8:18:30 pm </code></pre> <p>On the other hand, Temporal requires you to be a bit more verbose. Temporal objects, such as <code>Instant</code>, have a <code>toLocaleString</code> method that accepts various formatting options specified as properties of an object.</p> <div> <pre><code>const date = Temporal.Now.instant(); // with no arguments, we'll get the default format for the current locale console.log(date.toLocaleString()); // 2/22/2026, 8:23:36 PM (assuming a locale of en-US) // pass formatting options to generate a custom format string console.log(date.toLocaleString('en-US', { month: 'long', day: 'numeric', year: 'numeric', hour: '2-digit', minute: '2-digit' })); // February 22, 2026 at 8:23 PM // only pass the fields you want in the format string console.log(date.toLocaleString('en-US', { month: 'short', day: 'numeric' })); // Feb 22 </code></pre> </div> <p><strong>Temporal date formatting actually uses the <code>Intl.DateTimeFormat</code> API</strong> (which is already readily available in modern browsers) under the hood. That means you can create a reusable <code>DateTimeFormat</code> object with your custom formatting options, then pass Temporal objects to its <code>format</code> method. Because of this, it doesn’t support custom date formats like Moment does. If you need something like <code>'Q1 2026'</code> or other specialized formatting, you may need some custom date formatting code or reach for a third-party library.</p> <pre><code>const formatter = new Intl.DateTimeFormat('en-US', { month: '2-digit', day: '2-digit', year: 'numeric' }); const date = Temporal.Now.instant(); console.log(formatter.format(date)); // 02/22/2026 </code></pre> <p>Moment’s formatting tokens are simpler to write, but they aren’t locale-friendly. The format strings “hard code” things like month/day order. The advantage of using a configuration object, as Temporal does, is that it will automatically adapt to any given locale and use the correct format.</p> <pre><code>const date = Temporal.Now.instant(); const formatOptions = { month: 'numeric', day: 'numeric', year: 'numeric' }; console.log(date.toLocaleString('en-US', formatOptions)); // 2/22/2026 console.log(date.toLocaleString('en-GB', formatOptions)); // 22/02/2026 </code></pre> Date calculations <p>In many applications, you’ll need to end up performing some calculations on a date. You may want to add or subtract units of time (days, hours, seconds, etc.). For example, if you have the current date, you may want to show the user the date 1 week from now.</p> <p>Moment objects have methods such as <code>add</code> and <code>subtract</code> that perform these operations. These functions take a value and a unit, for example: <code>add(7, 'days')</code>. One very important difference between Moment and Temporal, however, is that when performing these date calculations, the underlying object is modified and its original value is lost.</p> <pre><code>const now = moment(); console.log(now); // Moment&lt;2026-02-24T20:08:36-05:00&gt; const nextWeek = now.add(7, 'days'); console.log(nextWeek); // Moment&lt;2026-03-03T20:08:36-05:00&gt; // Gotcha - the original object was mutated console.log(now); // Moment&lt;2026-03-03T20:08:36-05:00&gt; </code></pre> <p>To avoid losing the original date, you can call <code>clone</code> on the Moment object to create a copy.</p> <pre><code>const now = moment(); const nextWeek = now.clone().add(7, 'days'); console.log(now); // Moment&lt;2026-02-24T20:12:55-05:00&gt; console.log(nextWeek); // Moment&lt;2026-03-03T20:12:55-05:00&gt; </code></pre> <p>On the other hand, Temporal objects are <em>immutable</em>. Once you’ve created an object like an <code>Instant</code>, <code>PlainDate</code>, and so on, the value of that object will never change. Temporal objects also have <code>add</code> and <code>subtract</code> methods. </p> <p>Temporal is a little picky about which time units can be added to which object types. For example, you can’t add days to an <code>Instant</code>:</p> <div> <pre><code>const now = Temporal.Now.instant(); const nextWeek = now.add({ days: 7 }); // RangeError: Temporal error: Largest unit cannot be a date unit </code></pre> </div> <p>This is because <code>Instant</code> objects represent a specific point in time in UTC and are calendar-agnostic. Because the length of a day can change based on time zone rules such as Daylight Saving Time, this calculation isn’t available on an <code>Instant</code>. You <em>can</em>, however, perform this operation on other types of objects, such as a <code>PlainDateTime</code>:</p> <pre><code>const now = Temporal.Now.plainDateTimeISO(); console.log(now.toLocaleString()); // 2/24/2026, 8:23:59 PM const nextWeek = now.add({ days: 7 }); // Note that the original PlainDateTime remains unchanged console.log(now.toLocaleString()); // 2/24/2026, 8:23:59 PM console.log(nextWeek.toLocaleString()); // 3/3/2026, 8:23:59 PM </code></pre> <p>You can also calculate how much time is between two Moment or Temporal objects. </p> <p>With Moment’s <code>diff</code> function, you need to provide a unit for granularity, otherwise it will return the difference in milliseconds.</p> <pre><code>const date1 = moment('2026-02-21T09:00:00'); const date2 = moment('2026-02-22T10:30:00'); console.log(date2.diff(date1)); // 91800000 console.log(date2.diff(date1, 'days')); // 1 </code></pre> <p>To do this with a Temporal object, you can pass another Temporal object to its <code>until</code> or <code>since</code> methods. This returns a <code>Temporal.Duration</code> object containing information about the time difference. The <code>Duration</code> object has properties for each component of the difference, and also can generate an <a href="https://en.wikipedia.org/wiki/ISO_8601#Durations">ISO 8601</a> duration string representing the time difference.</p> <div> <pre><code>const date1 = Temporal.PlainDateTime.from('2026-02-21T09:00:00'); const date2 = Temporal.PlainDateTime.from('2026-02-22T10:30:00'); // largestUnit specifies the largest unit of time to represent // in the duration calculation const diff = date2.since(date1, { largestUnit: 'day' }); console.log(diff.days); // 1 console.log(diff.hours); // 1 console.log(diff.minutes); // 30 console.log(diff.toString()); // P1DT1H30M // (ISO 8601 duration string: 1 day, 1 hour, 30 minutes) </code></pre> </div> Comparing Dates And Times <p>Moment and Temporal both let you compare dates and times to determine which comes before the other, but take different approaches with the API.</p> <p>Moment provides methods such as <code>isBefore</code>, <code>isAfter</code>, and <code>isSame</code> to compare two Moment objects.</p> <pre><code>const date1 = moment('2026-02-21T09:00:00'); const date2 = moment('2026-02-22T10:30:00'); console.log(date1.isBefore(date2)); // true </code></pre> <p>Temporal uses a static <code>compare</code> method to perform a comparison between two objects of the same type. It returns <code>-1</code> if the first date comes before the second, <code>0</code> if they are equal, or <code>1</code> if the first date comes after the second. The following example shows how to compare two <code>PlainDate</code> objects. Both arguments to <code>Temporal.PlainDate.compare</code> must be <code>PlainDate</code> objects.</p> <div> <pre><code>const date1 = Temporal.PlainDate.from({ year: 2026, month: 2, day: 24 }); const date2 = Temporal.PlainDate.from({ year: 2026, month: 3, day: 24 }); // date1 comes before date2, so -1 console.log(Temporal.PlainDate.compare(date1, date2)); // Error if we try to compare two objects of different types console.log(Temporal.PlainDate.compare(date1, Temporal.Now.instant())); // TypeError: Temporal error: Invalid PlainDate fields provided. </code></pre> </div> <p>In particular, this makes it easy to sort an array of Temporal objects chronologically.</p> <pre><code>// An array of Temporal.PlainDate objects const dates = [ ... ]; // use Temporal.PlainDate.compare as the comparator function dates.sort(Temporal.PlainDate.compare); </code></pre> Time Zone Conversions <p>The core Moment library doesn’t support time zone conversions. If you need this functionality, you also need to install the <code>moment-timezone</code> package. This package is not tree-shakable, and therefore can add significantly to your bundle size. Once you’ve installed <code>moment-timezone</code>, you can convert Moment objects to different time zones with the <code>tz</code> method. As with other Moment operations, this mutates the underlying object.</p> <pre><code>// Assuming US Eastern time const now = moment(); console.log(now); // Moment&lt;2026-02-28T20:08:20-05:00&gt; // Convert to Pacific time. // The original Eastern time is lost. now.tz('America/Los_Angeles'); console.log(now); // Moment&lt;2026-02-28T17:08:20-08:00&gt; </code></pre> <p>Time zone functionality is built into the Temporal API when using a <code>Temporal.ZonedDateTime</code> object. These objects include a <code>withTimeZone</code> method that returns a new <code>ZonedDateTime</code> representing the same moment in time, but in the specified time zone.</p> <pre><code>// Again, assuming US Eastern time const now = Temporal.Now.zonedDateTimeISO(); console.log(now.toLocaleString()); // 2/28/2026, 8:12:02 PM EST // Convert to Pacific time const nowPacific = now.withTimeZone('America/Los_Angeles'); console.log(nowPacific.toLocaleString()); // 2/28/2026, 5:12:02 PM PST // Original object remains unchanged console.log(now.toLocaleString()); // 2/28/2026, 8:12:02 PM EST </code></pre> <p><strong>Note:</strong> <em>The formatted values returned by <code>toLocaleString</code> are, as the name implies, locale-dependent. The sample code was developed in the <code>en-US</code> locale, so the format is like this: <code>2/28/2026, 5:12:02 PM PST</code>. In another locale, this may be different. For example, in the <code>en-GB</code> locale, you would get something like <code>28/2/2026, 17:12:02 GMT-8</code>.</em></p> A Real-world Refactoring <p>Suppose we’re building an app for scheduling events across time zones. Part of this app is a function, <code>getEventTimes</code>, which takes an ISO 8601 string representing the time and date of the event, a local time zone, and a target time zone. The function creates formatted time and date strings for the event in both time zones.</p> <p>If the function is given an input string that’s not a valid time/date string, it will throw an error.</p> <p>Here’s the original implementation, using Moment (also requiring use of the <code>moment-timezone</code> package).</p> <div> <pre><code>import moment from 'moment-timezone'; function getEventTimes(inputString, userTimeZone, targetTimeZone) { const timeFormat = 'MMM D, YYYY, h:mm:ss a z'; // 1. Create the initial moment in the user's time zone const eventTime = moment.tz( inputString, moment.ISO_8601, // Expect an ISO 8601 string true, // Strict parsing userTimeZone ); // Throw an error if the inputString did not represent a valid date if (!eventTime.isValid()) { throw new Error('Invalid date/time input'); } // 2. Calculate the target time // CRITICAL: We must clone, or 'eventTime' changes forever! const targetTime = eventTime.clone().tz(targetTimeZone); return { local: eventTime.format(timeFormat), target: targetTime.format(timeFormat), }; } const schedule = getEventTimes( '2026-03-05T15:00-05:00', 'America/New_York', 'Europe/London', ); console.log(schedule.local); // Mar 5, 2026, 3:00:00 pm EST console.log(schedule.target); // Mar 5, 2026, 8:00:00 pm GMT </code></pre> </div> <p>In this example, we’re using an expected date format of ISO 8601, which is helpfully built into Moment. We’re also using strict parsing, which means Moment won’t try to guess with a date string that doesn’t match the format. If a non-ISO date string is passed, it will result in an invalid date object, and we throw an error.</p> <p>The Temporal implementation looks similar, but has a few key differences.</p> <div> <pre><code>function getEventTimes(inputString, userTimeZone, targetTimeZone) { // 1. Parse the input directly into an Instant, then create // a ZonedDateTime in the user's zone. const instant = Temporal.Instant.from(inputString); const eventTime = instant.toZonedDateTimeISO(userTimeZone); // 2. Convert to the target zone // This automatically returns a NEW object; 'eventTime' is safe. const targetTime = eventTime.withTimeZone(targetTimeZone); // 3. Format using Intl (built-in) const options = { year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit', second: '2-digit', timeZoneName: 'short' }; return { local: eventTime.toLocaleString(navigator.language, options), target: targetTime.toLocaleString(navigator.language, options) }; } const schedule = getEventTimes( '2026-03-05T15:00-05:00', 'America/New_York', 'Europe/London', ); console.log(schedule.local); // Mar 5, 2026, 3:00:00 PM EST console.log(schedule.target); // Mar 5, 2026, 8:00:00 PM GMT </code></pre> </div> <p>With Moment, we have to explicitly specify a format string for the resulting date strings. Regardless of the user’s location or locale, the event times will always be formatted as <code>Mar 5, 2026, 3:00:00 pm EST</code>. </p> <p>Also, we don’t have to explicitly throw an exception. If an invalid string is passed to <code>Temporal.Instant.from</code>, Temporal will throw the exception for us. One thing to note is that even with strict parsing, the Moment version is still more lenient. Temporal requires the time zone offset at the end of the string.</p> <p>You should also note that since we’re using <code>navigator.language</code>, this code will only run in a browser environment, as <code>navigator</code> is not defined in a Node.js environment.</p> <p>The Temporal implementation uses the browser’s current locale (<code>navigator.language</code>), so the user will automatically get event times formatted in their local time format. In the <code>en-US</code> locale, this is <code>Mar 5, 2026, 3:00:00 pm EST</code>. However, if the user is in London, for example, the event times will be formatted as <code>5 Mar 2026, 15:00:00 GMT-5</code>.</p> Summary <table> <thead><tr> <th>Action</th> <th>Moment.js</th> <th>Temporal</th> </tr></thead> <tbody> <tr> <td>Current time</td> <td><code>moment()</code></td> <td><code>Temporal.Now.zonedDateTimeISO()</code></td> </tr> <tr> <td>Parsing ISO</td> <td><code>moment(str)</code></td> <td><code>Temporal.Instant.from(str)</code></td> </tr> <tr> <td>Add time</td> <td> <code>.add(7, 'days')</code> (mutates)</td> <td> <code>.add({ days: 7 })</code> (new object)</td> </tr> <tr> <td>Difference</td> <td><code>.diff(other, 'hours')</code></td> <td><code>.since(other).hours</code></td> </tr> <tr> <td>Time zone</td> <td><code>.tz('Zone/Name')</code></td> <td><code>.withTimeZone('Zone/Name')</code></td> </tr> </tbody> </table> <p>At first glance, the difference may be slightly different (and in the case of Temporal, sometimes more verbose and more strict) syntax, but there are several key advantages to using Temporal over Moment.js:</p> <ul> <li>Being more explicit means <strong>fewer surprises and unintended bugs</strong>. Moment may appear to be more lenient, but it involves “guesswork,” which can sometimes result in incorrect dates. If you give Temporal something invalid, it throws an error. If the code runs, you know you’ve got a valid date.</li> <li>Moment can add significant size to the application’s bundle, particularly if you’re using the <code>moment-timezone</code> package. Temporal adds nothing (once it’s shipped in your target browsers).</li> <li> <strong>Immutability</strong> gives you the confidence that you’ll never lose or overwrite data when performing date conversions and operations.</li> <li> <strong>Different representations of time</strong> (<code>Instant</code>, <code>PlainDateTime</code>, <code>ZonedDateTime</code>) depending on your requirements, where Moment is always a wrapper around a UTC timestamp.</li> <li>Temporal uses the <strong><code>Intl</code> APIs for date formatting</strong>, which means you can have locale-aware formatting without having to explicitly specify tokens.</li> </ul> Notes On The Polyfill <p>As mentioned earlier, there is a Temporal polyfill available, distributed as an npm package named <code>@js-temporal/polyfill</code>. If you want to use Temporal today, you’ll need this polyfill to support browsers like Safari that haven’t shipped the API yet. The bad news with this is that it will add to your bundle size. The good news is that it still adds significantly less than <code>moment</code> or <code>moment-timezone</code>. Here is a comparison of the bundle sizes as reported by Bundlephobia.com, a website that presents information on npm package sizes (click on each package name to see the Bundlephobia analysis):</p> <table> <thead><tr> <th>Package</th> <th>Minified</th> <th>Minified &amp; gzipped</th> </tr></thead> <tbody> <tr> <td><a href="https://bundlephobia.com/package/@js-temporal/polyfill"><code>@js-temporal/polyfill</code></a></td> <td>154.1 kB</td> <td>44.1 kB</td> </tr> <tr> <td><a href="https://bundlephobia.com/package/moment"><code>moment</code></a></td> <td>294.4 kB</td> <td>75.4 kB</td> </tr> <tr> <td><a href="https://bundlephobia.com/package/moment-timezone"><code>moment-timezone</code></a></td> <td>1 MB</td> <td>114.2 kB</td> </tr> </tbody> </table> <p>The polyfill also has historically had some performance issues around memory usage, and at the time of writing, it’s considered to be in an alpha state. Because of this, you may not want to use it in production until it reaches a more mature state.</p> <p>The other good news is that hopefully the polyfill won’t be needed much longer (unless you need to support older browsers, of course). At the time of writing, Temporal has shipped in Chrome, Edge, and Firefox. It’s not quite ready in Safari yet, though it appears to be available with a runtime flag on the latest Technology Preview.</p>

Beyond `border-radius`: What The CSS `corner-shape` Property Unlocks For Everyday UI

<p>When I first started building websites, rounded corners required five background images, one for each corner, one for the body, and a prayer that the client wouldn’t ask for a different radius. Then the <code>border-radius</code> property landed, and the entire web collectively sighed with relief. That was over fifteen years ago, and honestly, we’ve been riding that same wave ever since. Just as then, I hope that we can look at this feature as a progressive enhancement slowly making its way to other browsers.</p> <p>I like a good <code>border-radius</code> like any other guy, but the fact is that it only gives us one shape. Round. That’s it. Want beveled corners? Clip-path. Scooped ticket edges? SVG mask. Squircle app icons? A carefully tuned SVG that you hope nobody asks you to animate. We’ve been hacking around the limitations of <code>border-radius</code> for years, and those hacks come with real trade-offs: borders don’t follow clip-paths, shadows get cut off, and you end up with brittle code that breaks the moment someone changes a padding value.</p> <p>Well, the new <strong><code>corner-shape</code></strong> changes all of that.</p> What Is <code>corner-shape</code>? <p>The <a href="https://css-tricks.com/almanac/properties/c/corner-shape/"><code>corner-shape</code></a> property is a companion to <code>border-radius</code>. It doesn’t replace it; it modifies the <em>shape</em> of the curve that <code>border-radius</code> creates. Without <code>border-radius</code>, <code>corner-shape</code> does nothing. But together, they’re a powerful pair.</p> <p>The property accepts these values:</p> <ul> <li> <strong><code>round</code></strong>: the default, same as regular <code>border-radius</code>,</li> <li> <strong><code>squircle</code></strong>: a superellipse, the smooth Apple-style rounded square,</li> <li> <strong><code>bevel</code></strong>: a straight line between the two radius endpoints (snipped corners),</li> <li> <strong><code>scoop</code></strong>: an inverted curve, creating concave corners,</li> <li> <strong><code>notch</code></strong>: sharp inward cuts,</li> <li> <strong><code>square</code></strong>: effectively removes the rounding, overriding <code>border-radius</code>.</li> </ul> <p>And you can set different values per corner, just like <code>border-radius</code>:</p> <pre><code>*corner-shape: bevel round scoop squircle; /* top-left, top-right, bottom-right, bottom-left */ </code></pre> <p>You can also use the <a href="https://css-tricks.com/almanac/functions/s/superellipse/"><code>superellipse()</code></a> function with a numeric parameter for fine-grained control.</p> <pre><code>.element { border-radius: 25px; corner-shape: superellipse(0); /* equal to 'bevel' */ } </code></pre> <p>So the question here might be: why not call this property “<code>border-shape</code>” instead? Well, first of all, that is <a href="https://una.im/border-shape">something completely different that we’ll get to play around with soon</a>. Second, it does apply to a bit more than borders, such as outlines, box shadows, and backgrounds. That’s the thing that the <code>clip-path</code> property could never do.</p> Why Progressive Enhancement Matters Here <p>At the time of writing (March 2026), <code>corner-shape</code> is only supported in Chrome 139+ and other Chromium-based browsers. That’s a significant chunk of users, but certainly not everyone. The temptation is to either ignore the property until it’s everywhere or to build demos that fall apart without it.</p> <p>I don’t think either approach is right. The way I see it, <code>corner-shape</code> is the perfect candidate for progressive enhancement, just as <code>border-radius</code> was in the age of Internet Explorer 6. The baseline should use the techniques we already know, such as <code>border-radius</code>, <code>clip-path</code>, <code>radial-gradient</code> masks and look intentionally good. Then, for browsers that support <code>corner-shape</code>, we upgrade the experience. Sometimes this can be as simple as just providing a more basic default; sometimes it might need to be a bit more.</p> <p><strong>Every demo in this article is created with that progressive enhancement idea.</strong> The structure for the demos looks like:</p> <pre><code>@layer base, presentation, demo; </code></pre> <p>The <code>presentation</code> layer contains the full polished UI using proven techniques. The <code>demo</code> layer wraps everything in <code>@supports</code>:</p> <pre><code>@layer demo { @supports (corner-shape: bevel) { /* upgrade styles here */ } } </code></pre> <p>No fallback banners, no “your browser doesn’t support this” messages. Just two tiers of design: good and better. I thought it could be nice just to show some examples. There are a few out there already, but I hope I can add a bit of extra inspiration on top of those.</p> Demo 1: Product Cards With Ribbon Badges <p>Every e-commerce site has them: those little “New” or “Sale” badges pinned to the corner of a product card. Traditionally, getting that ribbon shape means reaching for <code>clip-path: polygon()</code> or a rotated pseudo-element, let's call it “fiddly code” that has the chance to fall apart the moment someone changes a padding value.</p> <p>But here’s the thing: we don’t <em>need</em> the ribbon shape in the baseline. A simple badge with slightly rounded corners tells the same story and looks perfectly fine:</p> <pre><code>.product__badge { border-radius: 0 4px 4px 0; background-color: var(--badge-bg); } </code></pre> <p>That’s it. A small, clean label sitting flush against the left edge of the card. Nothing fancy, nothing broken. It works in every browser.</p> <p><img src="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/1-product-cards-corner-badges.png"></p> <p>For browsers that support <code>corner-shape</code>, we enhance:</p> <pre><code>@layer demo { /* If the browser supports `corner-shape` */ @supports (corner-shape: bevel) { .product { border-radius: 40px; corner-shape: squircle; } .product__badge { padding: 0.35rem 1.4rem 0.35rem 1rem; border-radius: 0 16px 16px 0; corner-shape: round bevel bevel round; } } } </code></pre> <p>The <code>round bevel bevel round</code> combination creates a directional ribbon. Round where it meets the card edge, beveled to a point on the other side. No <code>clip-path</code>, no pseudo-element tricks. Borders, shadows, and backgrounds all follow the declared shape because it <em>is</em> the shape.</p> <p>The cards themselves upgrade from <code>border-radius: 12px</code> to a larger size and the <code>squircle</code> corner-shape, that smooth superellipse curve that makes standard rounding look slightly off by comparison. Designers will notice immediately. Everyone else will just say it “feels more premium.”</p> <p><img src="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/2-product-cards-ribbon-badges.png"></p> <p><strong>Hot tip:</strong> Using the <code>squircle</code> value on card components is one of those upgrades where the before-and-after difference can be subtle in isolation, but transformative across an entire page. It’s the iOS effect: once everything uses superellipse curves, plain circular arcs start looking out of place. In this demo, I did exaggerate a bit.</p> <p><img src="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/3-buttons-before.png"></p> <p><img src="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/4-buttons-after.png"></p> <p>The primary button starts beveled, faceted, and gem-like, and softens to <code>squircle</code> on hover. Because <code>corner-shape</code> values animate via their <code>superellipse()</code> equivalents, the transition is smooth. It’s a fun interaction that used to be hard to achieve but is now a single property (used alongside <code>border-radius</code>, of course).</p> <p>The secondary button uses <code>superellipse(0.5)</code>, a value that is <em>between</em> a standard circle and a squircle, combined with a larger <code>border-radius</code> for a distinctive pill-like shape. The danger button gets a more prominent <code>squircle</code> with a generous radius. And <code>notch</code> and <code>scoop</code> each bring their own sharp or concave personality.</p> <p>Beyond buttons, the status tags get <code>corner-shape: notch</code>, those sharp inward cuts that give them a machine-stamped look. The directional arrow tags use <code>round bevel bevel round</code> (and its reverse for the back arrow), replacing what used to require <code>clip-path: polygon()</code>. Now borders and shadows work correctly across all states.</p> <p><img src="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/5-testimonials-before.png"></p> <p><img src="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/6-testimonials-after.png"></p> <p><strong>Hot tip:</strong> <code>corner-shape: scoop</code> pairs beautifully with serif fonts and warm color palettes. The concave curves echo the organic shapes found in editorial design, calligraphy, and print layouts. For geometric sans-serif designs, stick with <code>squircle</code> or <code>bevel</code>.</p> <p><img src="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/7-pricing-before.png"></p> <p><img src="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/8-pricing-after.png"></p> <p>What I like about this demo is how the shape hierarchy mirrors the content hierarchy. The most important element (featured plan) gets the most distinctive shape (<code>scoop</code>). The badge gets the sharpest shape (<code>bevel</code>). Everything else gets a simpler upgrade (<code>squircle</code>). Shape becomes a tool for visual emphasis, not just decoration.</p> <p><img src="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/9-music-before.png"></p> <p><img src="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/10-music-after.png"></p> Browser Support <p>As of writing, <code>corner-shape</code> is available in Chrome 139+ and Chromium-based browsers. Firefox and Safari don’t support it yet. The spec lives in <a href="https://drafts.csswg.org/css-borders/#propdef-corner-shape">CSS Borders and Box Decorations Module Level 4</a>, which is a W3C Working Draft as of this writing.</p> <p>For practical use, that’s fine. That’s the whole point of how these demos are built. The <code>presentation</code> layer delivers a polished, complete UI to every browser. The <code>demo</code> layer is a bonus for supporting browsers, wrapped in <code>@supports (corner-shape: ...)</code>. I lived through the time when <code>border-radius</code> was only available in Firefox. Somewhere along the line, it seems like we have forgotten that not every website needs to look exactly the same in every browser. What we really want is: no “broken” layouts and no “your browser doesn’t support this” messages, but rather a beautiful experience that just works, and can progressively enhance a bit of extra joy. In other words, we’re working with two tiers of design: good and better.</p> Wrapping Up <p>The approach I keep coming back to is: don’t design for <code>corner-shape</code>, and don’t design <em>around</em> the lack of it. Design a solid baseline with <code>border-radius</code> and then enhance it. The presentation layer in every demo looks intentionally good. It’s not a degraded version waiting for a better browser. It’s a <strong>complete design</strong>. The <code>demo</code> layer adds a dimension that <code>border-radius</code> alone can’t express.</p> <p>What surprises me most about <code>corner-shape</code> is the <em>range</em> it offers — the amazing powerhouse we have with this single property: <code>squircle</code> for that premium, superellipse feel on cards and avatars; <code>bevel</code> for directional elements and gem-like badges; <code>scoop</code> for editorial warmth and visual hierarchy; <code>notch</code> for mechanical precision on tags; and <code>superellipse()</code> for fine control between <code>round</code> and <code>squircle</code>. And the ability to mix values per corner (<code>round bevel bevel round</code>, <code>scoop round</code>) opens up shapes that would have required SVG masks or <code>clip-path</code> hacks.</p> <p>We went from five background images to <code>border-radius</code>, to <code>corner-shape</code>. Each step removed a category of workarounds. I’m excited to see what designers do with this one.</p> <h3>Further Reading</h3> <ul> <li> <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/corner-shape"><code>corner-shape</code></a> (MDN)</li> <li>“<a href="https://css-tricks.com/what-can-we-actually-do-with-corner-shape/">What Can We Actually Do With <code>corner-shape</code>?</a>”, Daniel Schwarz</li> <li> <a href="https://drafts.csswg.org/css-borders/#propdef-corner-shape">CSS Borders and Box Decorations Module Level 4</a> (W3C specification)</li> <li> <a href="https://codepen.io/bySebastian/pen/VYjPzYo">A fun demo for “eco-labels”</a>, Sebastian on CodePen</li> </ul>

Building Dynamic Forms In React And Next.js

<p>This article is a sponsored by <a href="https://surveyjs.io/">SurveyJS</a></p> <p>There’s a mental model most React developers share without ever discussing it out loud. That forms are <em>always</em> supposed to be components. This means a stack like:</p> <ul> <li> <strong>React Hook Form</strong> for local state (minimal re-renders, ergonomic field registration, imperative interaction).</li> <li> <strong>Zod</strong> for validation (input correctness, boundary validation, type-safe parsing).</li> <li> <strong>React Query</strong> for backend: submission, retries, caching, server sync, and so on.</li> </ul> <p>And for the vast majority of forms — your login screens, your settings pages, your CRUD modals — this works really well. Each piece does its job, they compose cleanly, and you can move on to the parts of your application that actually differentiate your product.</p> <p>But every once in a while, a form starts accumulating things like visibility rules that depend on earlier answers, or derived values that cascade through three fields. Maybe even entire pages that should be skipped or shown based on a running total. </p> <p>You handle the first conditional with a <code>useWatch</code> and an inline branch, which is fine. Then another. <a href="https://zod.dev/api#superrefine">Then you’re reaching for <code>superRefine</code></a> to encode cross-field rules that your Zod schema can’t express in the normal way. Then, step navigation starts leaking business logic. At some point, you look at what you’ve built and realize that the form isn’t really UI anymore. It’s more of a decision process, and the component tree is just where you happened to store it.</p> <p>This is where I think the mental model for forms in React breaks down, and it’s really nobody’s fault. The RHF + Zod stack is excellent at what it was designed for. <strong>The issue is that we tend to keep using it past the point where its abstractions match the problem</strong> because the alternative requires a different way of thinking about forms entirely.</p> <p>This article is about that alternative. To show this, we’ll build the exact same multi-step form twice: </p> <ol> <li>With React Hook Form + Zod wired to React Query for submission,</li> <li>With SurveyJS, which treats a form as data — a simple JSON schema — rather than a component tree. </li> </ol> <p>Same requirements, same conditional logic, same API call at the end. Then we’ll map exactly what moved and what stayed, and lay out a practical way to decide which model you should use, and when.</p> <p><strong>The form we’re building:</strong></p> <p><img src="https://files.smashing.media/articles/building-dynamic-forms-react-next-js/1-dynamic-form.png"></p> <p>This form will use a 4-step flow:</p> <p><strong>Step 1: Details</strong></p> <ul> <li>First name (required),</li> <li>Email (required, valid format).</li> </ul> <p><strong>Step 2: Order</strong></p> <ul> <li>Unit price,</li> <li>Quantity,</li> <li>Tax rate,</li> <li>Derived:<ul> <li>Subtotal,</li> <li>Tax,</li> <li>Total.</li> </ul> </li> </ul> <p><strong>Step 3: Account &amp; Feedback</strong></p> <ul> <li>Do you have an account? (Yes/No)<ul> <li>If Yes → username + password, both required.</li> <li>If No → email already collected in step 1.</li> </ul> </li> <li>Satisfaction rating (1–5)<ul> <li>If ≥ 4 → ask “What did you like?”</li> <li>If ≤ 2 → ask “What can we improve?”</li> </ul> </li> </ul> <p><strong>Step 4: Review</strong></p> <ul> <li>Only appears if <code>total &gt;= 100</code> </li> <li>Final submission.</li> </ul> <p>This is not extreme. But it’s enough to expose architectural differences.</p> Part 1: Component-Driven (React Hook Form + Zod) <h3>Installation</h3> <pre><code>npm install react-hook-form zod @hookform/resolvers @tanstack/react-query </code></pre> <h3>Zod Schema</h3> <p>Let’s start with the Zod schema, because that’s usually where the shape of the form gets established. For the first two steps — personal details and order inputs — everything is straightforward: required strings, numbers with minimums, and an enum. The interesting part starts when you try to express the conditional rules.</p> <div> <pre><code>import { z } from "zod"; export const formSchema = z.object({<br> firstName: z.string().min(1, "Required"),<br> email: z.string().email("Invalid email"),<br> price: z.number().min(0),<br> quantity: z.number().min(1),<br> taxRate: z.number(),<br> hasAccount: z.enum(["Yes", "No"]),<br> username: z.string().optional(),<br> password: z.string().optional(),<br> satisfaction: z.number().min(1).max(5),<br> positiveFeedback: z.string().optional(),<br> improvementFeedback: z.string().optional(),<br>}).superRefine((data, ctx) =&gt; {<br> if (data.hasAccount === "Yes") {<br> if (!data.username) {<br> ctx.addIssue({ code: "custom", path: ["username"], message: "Required" });<br> }<br> if (!data.password || data.password.length &lt; 6) {<br> ctx.addIssue({ code: "custom", path: ["password"], message: "Min 6 characters" });<br> }<br> } if (data.satisfaction &gt;= 4 &amp;&amp; !data.positiveFeedback) {<br> ctx.addIssue({ code: "custom", path: ["positiveFeedback"], message: "Please share what you liked" });<br> } if (data.satisfaction &lt;= 2 &amp;&amp; !data.improvementFeedback) {<br> ctx.addIssue({ code: "custom", path: ["improvementFeedback"], message: "Please tell us what to improve" });<br> }<br>}); export type FormData = z.infer&lt;typeof formSchema&gt;; </code></pre> </div> <p>Notice that <code>username</code> and <code>password</code> are typed as <code>optional()</code> even though they’re conditionally required because Zod’s type-level schema describes the <em>shape</em> of the object, not the rules governing when fields matter. </p> <p>The conditional requirement has to live inside <code>superRefine</code>, which runs after the shape is validated and has access to the full object. That separation is not a flaw; it’s just what the tool is designed for: <code>superRefine</code> is where cross-field logic goes when it can’t be expressed in the schema structure itself.</p> <p>What’s also notable here is what this schema <em>doesn’t</em> express. It has no concept of pages, no concept of which fields are visible at which point, and no concept of navigation. All of that will live somewhere else.</p> <h3>Form Component</h3> <div> <pre><code>import { useForm, useWatch } from "react-hook-form";<br>import { zodResolver } from "@hookform/resolvers/zod";<br>import { useMutation } from "@tanstack/react-query";<br>import { useState, useMemo } from "react";<br>import { formSchema, type FormData } from "./schema"; const STEPS = ["details", "order", "account", "review"]; type OrderPayload = FormData &amp; { subtotal: number; tax: number; total: number }; export function RHFMultiStepForm() {<br> const [step, setStep] = useState(0); const mutation = useMutation({ mutationFn: async (payload: OrderPayload) =&gt; { const res = await fetch("/api/orders", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload), }); if (!res.ok) throw new Error("Failed to submit"); return res.json(); }, }); const {<br> register,<br> control,<br> handleSubmit,<br> formState: { errors },<br> } = useForm&lt;FormData&gt;({<br> resolver: zodResolver(formSchema),<br> defaultValues: {<br> price: 0,<br> quantity: 1,<br> taxRate: 0.1,<br> satisfaction: 3,<br> hasAccount: "No",<br> },<br> });<br> const price = useWatch({ control, name: "price" });<br> const quantity = useWatch({ control, name: "quantity" });<br> const taxRate = useWatch({ control, name: "taxRate" });<br> const hasAccount = useWatch({ control, name: "hasAccount" });<br> const satisfaction = useWatch({ control, name: "satisfaction" });<br> const subtotal = useMemo(() =&gt; (price ?? 0) * (quantity ?? 1), [price, quantity]);<br> const tax = useMemo(() =&gt; subtotal * (taxRate ?? 0), [subtotal, taxRate]);<br> const total = useMemo(() =&gt; subtotal + tax, [subtotal, tax]);<br> const onSubmit = (data: FormData) =&gt; mutation.mutate({ ...data, subtotal, tax, total });<br> const showSubmit = (step === 2 &amp;&amp; total &lt; 100) || (step === 3 &amp;&amp; total &gt;= 100) return (<br> &lt;form onSubmit={handleSubmit(onSubmit)}&gt;<br> {step === 0 &amp;&amp; (<br> &lt;&gt;<br> &lt;input {...register("firstName")} placeholder="First Name" /&gt;<br> &lt;input {...register("email")} placeholder="Email" /&gt;<br> &lt;/&gt;<br> )} {step === 1 &amp;&amp; (<br> &lt;&gt;<br> &lt;input type="number" {...register("price", { valueAsNumber: true })} /&gt;<br> &lt;input type="number" {...register("quantity", { valueAsNumber: true })} /&gt;<br> &lt;select {...register("taxRate", { valueAsNumber: true })}&gt;<br> &lt;option value="0.05"&gt;5%&lt;/option&gt;<br> &lt;option value="0.1"&gt;10%&lt;/option&gt;<br> &lt;option value="0.15"&gt;15%&lt;/option&gt;<br> &lt;/select&gt; &lt;div&gt;Subtotal: {subtotal}&lt;/div&gt;<br> &lt;div&gt;Tax: {tax}&lt;/div&gt;<br> &lt;div&gt;Total: {total}&lt;/div&gt;<br> &lt;/&gt;<br> )} {step === 2 &amp;&amp; (<br> &lt;&gt;<br> &lt;select {...register("hasAccount")}&gt;<br> &lt;option value="Yes"&gt;Yes&lt;/option&gt;<br> &lt;option value="No"&gt;No&lt;/option&gt;<br> &lt;/select&gt; {hasAccount === "Yes" &amp;&amp; (<br> &lt;&gt;<br> &lt;input {...register("username")} placeholder="Username" /&gt;<br> &lt;input {...register("password")} placeholder="Password" /&gt;<br> &lt;/&gt;<br> )} &lt;input type="number" {...register("satisfaction", { valueAsNumber: true })} /&gt; {satisfaction &gt;= 4 &amp;&amp; (<br> &lt;textarea {...register("positiveFeedback")} /&gt;<br> )} {satisfaction &lt;= 2 &amp;&amp; (<br> &lt;textarea {...register("improvementFeedback")} /&gt;<br> )}<br> &lt;/&gt;<br> )} {step === 3 &amp;&amp; total &gt;= 100 &amp;&amp; &lt;div&gt;Review and submit&lt;/div&gt;} &lt;div&gt;<br> {step &gt; 0 &amp;&amp; &lt;button type="button" onClick={() =&gt; setStep(step - 1)}&gt;Back&lt;/button&gt;}<br> {showSubmit ? (<br> &lt;button type="submit" disabled={mutation.isPending}&gt;<br> {mutation.isPending ? "Submitting…" : "Submit"}<br> &lt;/button&gt;<br> ) : step &lt; STEPS.length - 1 ? (<br> &lt;button type="button" onClick={() =&gt; setStep(step + 1)}&gt;Next&lt;/button&gt;<br> ) : null}<br> &lt;/div&gt;<br> {mutation.isError &amp;&amp; &lt;div&gt;Error: {mutation.error.message}&lt;/div&gt;}<br> &lt;/form&gt;<br> );<br>} </code></pre> </div> <p>See the Pen <a href="https://codepen.io/smashingmag/pen/gbwwmNO">SurveyJS-03-RHF [forked]</a> by <a href="https://codepen.io/sixthextinction">sixthextinction</a>.</p> <p>There’s quite a lot happening here, and it’s worth slowing down to notice where things ended up.</p> <ul> <li>The derived values — <code>subtotal</code>, <code>tax</code>, <code>total</code> — are computed in the component via <code>useWatch</code> and <code>useMemo</code> because they depend on live field values and there’s no other natural place for them. </li> <li>The visibility rules for <code>username</code>, <code>password</code>, <code>positiveFeedback</code>, and <code>improvementFeedback</code> live in JSX as inline conditionals. </li> <li>The step-skipping logic — the review page only appearing when <code>total &gt;= 100</code> — is embedded into the <code>showSubmit</code> variable and the render condition on step 3.</li> <li>Navigation itself is just a <code>useState</code> counter that we’re manually incrementing.</li> <li>React Query handles retries, caching, and invalidation. The form just calls <code>mutation.mutate</code> with validated data. </li> </ul> <p>None of this is <em>wrong,</em> per se. This is still idiomatic React, and the component is quite performant thanks to how RHF isolates re-renders. </p> <p>But if you were to hand this to someone who hadn’t written it and ask them to explain <em>under what conditions the review page appears</em>, they’d have to trace through <code>showSubmit</code>, the step 3 render condition, and the nav button logic — three separate places — to reconstruct a rule that could have been stated in one line. </p> <p><strong>The form works, yes, but the behavior isn’t really inspectable as a system.</strong> It has to be executed mentally.</p> <p>More importantly, changing it requires engineering involvement. Even a small tweak, like adjusting when the review step shows up, means editing the component, updating validation, opening a pull request, waiting for review, and deploying again.</p> Part 2: Schema-Driven (SurveyJS) <p>Now let’s build the same flow using a schema.</p> <h3>Installation</h3> <pre><code>npm install survey-core survey-react-ui @tanstack/react-query </code></pre> <ul> <li> <code>survey-core</code><br>The MIT-licensed platform-independent runtime engine that powers SurveyJS’s form rendering — the part we care about here. It takes a JSON schema, builds an internal model from it, and handles everything that would otherwise live in your React component: evaluating visibility expressions, computing derived values, managing page state, tracking validation, and deciding what “complete” means given which pages were actually shown. </li> <li> <code>survey-react-ui</code><br>The UI / rendering layer that connects that model to React. It’s essentially a <code>&lt;Survey model={model} /&gt;</code> component that re-renders whenever the engine’s state changes. SurveyJS UI libraries are also available for <a href="https://www.npmjs.com/package/survey-angular">Angular</a>, <a href="https://www.npmjs.com/package/survey-vue3-ui">Vue3</a>, and many other frameworks.</li> </ul> <p>Together, they give you a fully functional, multi-page form runtime without writing a single line of control flow. </p> <p>The schema format itself is, as said before, just a JSON — no DSL or anything proprietary. You can inline it, import it from a file, fetch it from an API, or store it in a database column and hydrate it at runtime. </p> <h3>The Same Form, As Data</h3> <p>Here’s the same form, this time expressed as a JSON object. The schema defines everything: structure, validation, visibility rules, derived calculations, page navigation — and hands it to a <code>Model</code> that evaluates it at runtime. Here’s what that looks like in full:</p> <div> <pre><code>export const surveySchema = {<br> title: "Order Flow",<br> showProgressBar: "top",<br> pages: [<br> {<br> name: "details",<br> elements: [<br> { type: "text", name: "firstName", isRequired: true },<br> { type: "text", name: "email", inputType: "email", isRequired: true, validators: [{ type: "email", text: "Invalid email" }] }<br> ]<br> },<br> {<br> name: "order",<br> elements: [<br> { type: "text", name: "price", inputType: "number", defaultValue: 0 },<br> { type: "text", name: "quantity", inputType: "number", defaultValue: 1 },<br> {<br> type: "dropdown",<br> name: "taxRate",<br> defaultValue: 0.1,<br> choices: [<br> { value: 0.05, text: "5%" },<br> { value: 0.1, text: "10%" },<br> { value: 0.15, text: "15%" }<br> ]<br> },<br> {<br> type: "expression",<br> name: "subtotal",<br> expression: "{price} <em> {quantity}"<br> },<br> {<br> type: "expression",<br> name: "tax",<br> expression: "{subtotal} </em> {taxRate}"<br> },<br> {<br> type: "expression",<br> name: "total",<br> expression: "{subtotal} + {tax}"<br> }<br> ]<br> },<br> {<br> name: "account",<br> elements: [<br> {<br> type: "radiogroup",<br> name: "hasAccount",<br> choices: ["Yes", "No"]<br> },<br> {<br> type: "text",<br> name: "username",<br> visibleIf: "{hasAccount} = 'Yes'",<br> isRequired: true<br> },<br> {<br> type: "text",<br> name: "password",<br> inputType: "password",<br> visibleIf: "{hasAccount} = 'Yes'",<br> isRequired: true,<br> validators: [{ type: "text", minLength: 6, text: "Min 6 characters" }]<br> },<br> {<br> type: "rating",<br> name: "satisfaction",<br> rateMin: 1,<br> rateMax: 5<br> },<br> {<br> type: "comment",<br> name: "positiveFeedback",<br> visibleIf: "{satisfaction} &gt;= 4"<br> },<br> {<br> type: "comment",<br> name: "improvementFeedback",<br> visibleIf: "{satisfaction} &lt;= 2"<br> }<br> ]<br> },<br> {<br> name: "review",<br> visibleIf: "{total} &gt;= 100",<br> elements: []<br> }<br> ]<br>}; </code></pre> </div> <p>Compare this to the RHF version for a moment.</p> <ul> <li>The <code>superRefine</code> block that conditionally required <code>username</code> and <code>password</code> is gone. <code>visibleIf: "{hasAccount} = 'Yes'"</code> combined with <code>isRequired: true</code> handles both concerns together, on the field itself, where you'd expect to find them. </li> <li>The <code>useWatch</code> + <code>useMemo</code> chain that computed <code>subtotal</code>, <code>tax</code>, and <code>total</code> is replaced by three <code>expression</code> fields that reference each other by name. </li> <li>The review page condition, which in the RHF version was reconstructable only by tracing through <code>showSubmit</code>, the step 3 render branch.</li> <li>And finally, the nav button logic is a single <code>visibleIf</code> property on the page object.</li> </ul> <p>The same logic is there. It’s just that the schema gives it a place to live where it’s visible in isolation, rather than spread across the component.</p> <p>Also, note that the schema uses <code>type: 'expression'</code> for subtotal, tax, and total. <a href="https://surveyjs.io/form-library/documentation/api-reference/expression-model">Expression</a> is read-only and used mainly to display calculated values. SurveyJS also supports <code>type: 'html'</code> for static content, but for calculated values, <code>expression</code> is the right choice.</p> <p>Now for the React side. </p> <h3>Rendering And Submission</h3> <p>Very simple. Wire <code>onComplete</code> to your API the same way — via <code>useMutation</code> or plain <code>fetch</code>:</p> <div> <pre><code>import { useState, useEffect, useRef } from "react";<br>import { useMutation } from "@tanstack/react-query";<br>import { Model } from "survey-core";<br>import { Survey } from "survey-react-ui";<br>import "survey-core/survey-core.css"; export function SurveyForm() {<br> const [model] = useState(() =&gt; new Model(surveySchema)); const mutation = useMutation({ mutationFn: async (data) =&gt; { const res = await fetch("/api/orders", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data), }); if (!res.ok) throw new Error("Failed to submit"); return res.json(); }, }); const mutationRef = useRef(mutation); mutationRef.current = mutation; useEffect(() =&gt; {<br> const handler = (sender) =&gt; mutationRef.current.mutate(sender.data);<br> model.onComplete.add(handler);<br> return () =&gt; model.onComplete.remove(handler);<br> }, [model]); // ref avoids re-registering handler every render (mutation object identity changes) return ( &lt;&gt; &lt;Survey model={model} /&gt;<br> {mutation.isError &amp;&amp; &lt;div&gt;Error: {mutation.error.message}&lt;/div&gt;} &lt;/&gt; ); } </code></pre> </div> <p>See the Pen <a href="https://codepen.io/smashingmag/pen/emddWNV">SurveyJS-03-SurveyJS [forked]</a> by <a href="https://codepen.io/sixthextinction">sixthextinction</a>.</p> <ul> <li> <code>onComplete</code> fires when the user reaches the end of the last <em>visible</em> page. So if <code>total</code> never crosses 100 and the review page is skipped, it still fires correctly because SurveyJS evaluates visibility before deciding what “last page” means. </li> <li>Then, <code>sender.data</code> contains all answers along with the calculated values (<code>subtotal</code>, <code>tax</code>, <code>total</code>) as first-class fields, so the API payload is identical to what the RHF version assembled manually in <code>onSubmit</code>. </li> <li>The <code>mutationRef</code> pattern is the same one you’d reach for anywhere you need a stable event handler over a value that changes on every render — nothing SurveyJS-specific about it.</li> </ul> <p>The React component no longer contains any business logic at all. There’s no <code>useWatch</code>, no conditional JSX, no step counter, no <code>useMemo</code> chain, no <code>superRefine</code>. React is doing what it’s actually good at: rendering a component and wiring it to an API call.</p> What Moved Out Of React? <table> <thead><tr> <th>Concern</th> <th>RHF Stack</th> <th>SurveyJS</th> </tr></thead> <tbody> <tr> <td>Visibility</td> <td>JSX branches</td> <td><code>visibleIf</code></td> </tr> <tr> <td>Derived values</td> <td> <code>useWatch</code> / <code>useMemo</code> </td> <td><code>expression</code></td> </tr> <tr> <td>Cross-field rules</td> <td><code>superRefine</code></td> <td>Schema conditions</td> </tr> <tr> <td>Navigation</td> <td> <code>step</code> state</td> <td>Page <code>visibleIf</code> </td> </tr> <tr> <td>Rule location</td> <td>Distributed across files</td> <td>Centralized in the schema</td> </tr> </tbody> </table> <p>What stays in React is layout, styling, submission wiring, and app integration, which is to say, <strong>the things React is actually designed for</strong>.</p> <p>Everything else moved into the schema, and because the schema is just a JSON object, it can be stored in a database, versioned independently of your application code, or edited through internal tooling without requiring a deploy. </p> <p>A product manager who needs to change the threshold that triggers the review page can do that without touching the component. That’s a meaningful operational difference for teams where form behavior evolves frequently and isn’t always driven by engineers.</p> When To Use Each Approach? <p>Here’s a good rule of thumb that works for me: <strong>imagine deleting the form entirely</strong>. What would you lose?</p> <ul> <li>If it’s screens, you want component-driven forms. </li> <li>If it’s business logic, like thresholds, branching rules, and conditional requirements that encode real decisions, you want a schema engine. </li> </ul> <p>Similarly, if the changes coming your way are mostly about labels, fields, and layout, RHF will serve you fine. If they’re about conditions, outcomes, and rules that your ops or legal team might need to adjust on a Tuesday afternoon without filing a ticket, the schema model with SurveyJS is the more honest fit.</p> <p><strong>These two approaches are not really in competition with each other.</strong> They address different classes of problems, and the mistake worth avoiding is mismatching the abstraction to the weight of the logic — treating a rule system like a component because that’s the familiar tool, or reaching for a policy engine because a form grew to three steps and acquired a conditional field. </p> <p>The form we built here sits near the boundary deliberately, complex enough to expose the difference but not so extreme that the comparison feels rigged. Most real forms that have gotten unwieldy in your codebase probably sit near that same boundary, and the question is usually just whether anyone has named what they actually are.</p> <p><strong>Use React Hook Form + Zod when:</strong></p> <ul> <li>Forms are CRUD-oriented;</li> <li>Logic is shallow and UI-driven;</li> <li>Engineers own all behavior;</li> <li>Backend remains the source of truth.</li> </ul> <p><strong>Use SurveyJS when:</strong></p> <ul> <li>Forms encode business decisions;</li> <li>Rules evolve independently of UI;</li> <li>Logic must be visible, auditable, or versioned;</li> <li>Non-engineers influence behavior;</li> <li>The same form must run across multiple frontends.</li> </ul>