<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Juan Martin</title>
    <description>The latest articles on DEV Community by Juan Martin (@tinchox5).</description>
    <link>https://dev.to/tinchox5</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F139960%2F6df2ccf3-5a97-4a9f-9f3b-add197e8e5fb.jpeg</url>
      <title>DEV Community: Juan Martin</title>
      <link>https://dev.to/tinchox5</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tinchox5"/>
    <language>en</language>
    <item>
      <title>I got tired of page navigation. So I built a zoom-based alternative</title>
      <dc:creator>Juan Martin</dc:creator>
      <pubDate>Mon, 06 Apr 2026 01:10:32 +0000</pubDate>
      <link>https://dev.to/tinchox5/i-got-tired-of-page-navigation-so-i-built-a-zoom-based-alternative-2koo</link>
      <guid>https://dev.to/tinchox5/i-got-tired-of-page-navigation-so-i-built-a-zoom-based-alternative-2koo</guid>
      <description>&lt;p&gt;The idea is simple: instead of navigating between pages, you zoom into content. Mark an element as zoomable, point it to a view, and Zumly handles the transition and inserts the new content. That’s basically it.&lt;/p&gt;

&lt;p&gt;I started this in 2020 after stepping back from Zircle UI, a Vue zooming library I built before. I wanted to take the core idea further without being tied to any framework. So &lt;strong&gt;Zumly&lt;/strong&gt; is framework-agnostic and focused purely on the zoom transition. It doesn’t care about your CSS, your design system, or your stack.&lt;br&gt;
Since then I rewrote the engine several times and changed the approach more than once. Only now am I actually happy with how it feels.&lt;/p&gt;

&lt;p&gt;The landing page is built with Zumly itself, so you get the interaction before touching any code:&lt;br&gt;
&lt;a href="https://zumerlab.github.io/zumly" rel="noopener noreferrer"&gt;https://zumerlab.github.io/zumly&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Still rough edges ahead. Would love to hear what you think about the interaction model and if the API makes sense.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>showdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>From frustration to open source adoption: my journey building SnapDOM</title>
      <dc:creator>Juan Martin</dc:creator>
      <pubDate>Sat, 27 Sep 2025 14:22:02 +0000</pubDate>
      <link>https://dev.to/tinchox5/from-frustration-to-open-source-adoption-my-journey-building-snapdom-4p4o</link>
      <guid>https://dev.to/tinchox5/from-frustration-to-open-source-adoption-my-journey-building-snapdom-4p4o</guid>
      <description>&lt;p&gt;I started hacking on what later became SnapDOM in April this year. At first it wasn’t even meant to be a standalone library — it began as an internal tool for a zoomable UI project (Zumly), I was building. To make that project work, I needed a way to capture DOM elements with high speed and fidelity. Existing DOM-to-image libraries like html2canvas often failed in subtle but important ways: missing pseudo-elements, mis-rendering fonts, ignoring Shadow DOM, or breaking on Safari. What started as a quick internal hack slowly grew into its own project.&lt;br&gt;
Open sourcing SnapDOM changed everything. Suddenly the audience wasn’t just me, but anyone with their own browser, CSS, and HTML quirks. That’s when I realized how immense the attack surface really is. Every combination of engines, DOM structures, styles, and external resources can break in unexpected ways. At times it felt overwhelming, but I’ve learned to treat each bug as a reproducible pattern: isolate it, fix it, and carry the lesson forward.&lt;/p&gt;

&lt;p&gt;From the beginning, two principles guided the work: fidelity and speed. Capturing “every detail” would not matter if the process was unbearably slow, so I spent a lot of time on caching strategies, incremental updates, and efficient DOM cloning. Benchmarking against existing libraries became part of the routine. Performance was never an afterthought — it was always as important as accuracy.&lt;/p&gt;

&lt;p&gt;On the technical side, SnapDOM pushed me into DOM cloning strategies, caching, font embedding heuristics, browser-specific hacks, and the constant tradeoffs between fidelity and performance. On the personal side, it has been just as educational: patience, humility, and learning to really listen to users. Some of the best moments have been receiving thoughtful PRs and clear reproduction cases — collaboration that genuinely made the project better. The respect shown in these contributions has been one of the most motivating parts of the journey.&lt;/p&gt;

&lt;p&gt;Another milestone: only a few months in, SnapDOM already has its first two GitHub Sponsors and has passed 6k stars on GitHub. Knowing that people found enough value to sponsor the project, and that thousands more cared enough to star it, has been incredibly rewarding.&lt;/p&gt;

&lt;p&gt;I’ve also been designing a plugin system, so the core stays lean while features like cropping, filters, or alternative exporters can live as extensions. It’s not merged into the mainline yet, but it’s a direction I’m excited about — and another layer of complexity to manage as the project evolves.&lt;/p&gt;

&lt;p&gt;It’s still early days, but reflecting on the journey from April to now has been meaningful. What started as a small internal helper for a zoomable UI turned into an open source project with real users, contributions, sponsors, and community respect. Balancing the technical struggles with the human side of open source has made this one of the most rewarding experiences I’ve had so far.&lt;/p&gt;

&lt;p&gt;Thank you, Martin&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/zumerlab/snapdom" rel="noopener noreferrer"&gt;https://github.com/zumerlab/snapdom&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>🎉 SnapDOM celebrates 3 months! 🎉</title>
      <dc:creator>Juan Martin</dc:creator>
      <pubDate>Sun, 27 Jul 2025 10:37:36 +0000</pubDate>
      <link>https://dev.to/tinchox5/snapdom-celebrates-3-months-2ee4</link>
      <guid>https://dev.to/tinchox5/snapdom-celebrates-3-months-2ee4</guid>
      <description>&lt;p&gt;Today, 27 July, we mark the first 90 days since Snapdom was born.&lt;br&gt;
We couldn’t be more grateful to the amazing community that made it possible. 🙌&lt;/p&gt;

&lt;p&gt;🚀 In just 3 months, Snapdom has reached:&lt;/p&gt;

&lt;p&gt;⭐ 3550+ stars&lt;br&gt;
🍴 107 forks&lt;br&gt;
📦 18 releases published&lt;br&gt;
👥 14 incredible contributors&lt;br&gt;
Snapdom grew fast, but on a solid foundation. During this time, we’ve added advanced support for:&lt;/p&gt;

&lt;p&gt;✅ Web Components and slots&lt;br&gt;
✅ Complex pseudo-elements&lt;br&gt;
✅ Remote and local fonts (including icon fonts!)&lt;br&gt;
✅ &lt;a class="mentioned-user" href="https://dev.to/import"&gt;@import&lt;/a&gt; and @font-face styles&lt;br&gt;
✅ mask-image, backgrounds, canvas, SVG, and more&lt;br&gt;
✅ Fixes for Safari, Firefox, Edge, Chromium...&lt;br&gt;
✅ Performance optimizations, compression, and smart caching&lt;br&gt;
✅ New benchmarks, CI compatibility, improved DX and documentation&lt;/p&gt;

&lt;p&gt;👩‍🔧 Every release brought significant improvements, with a steady evolution focused on true visual fidelity.&lt;/p&gt;

&lt;p&gt;🔥 What truly sets Snapdom apart is its speed — it is hands down the fastest DOM capture tool available.&lt;/p&gt;

&lt;p&gt;What truly sets Snapdom apart is its speed — it is hands down the fastest DOM capture tool available.&lt;/p&gt;

&lt;p&gt;While other tools like html2canvas, html-to-image, and modern-screenshot may take noticeably longer or face challenges with complex DOMs, Snapdom captures almost instantly, even with deep and dynamic structures. This unmatched speed makes it the go-to solution for real-time apps, visual editors, and any workflow where performance is critical.&lt;/p&gt;

&lt;p&gt;Our benchmarks prove it out: Snapdom surpasses these alternatives by a wide margin, delivering high-fidelity results without compromising speed.&lt;/p&gt;

&lt;p&gt;The secret behind this performance lies mainly in Snapdom’s advanced caching system combined with its intelligent CSS class assembly. By efficiently reusing cached styles and building compact CSS increments, Snapdom drastically reduces final bundle size and speeds up style processing, resulting in lightning-fast captures even in the most demanding scenarios.&lt;/p&gt;

&lt;p&gt;You can check all the progress in the full Changelog, or explore our interactive demos to see what it can do.&lt;/p&gt;

&lt;p&gt;💜 Huge thanks to everyone who opened issues, submitted PRs, starred the repo, or helped test.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
    <item>
      <title>📊 SnapDOM - Performance Benchmarks For clientside screenshots</title>
      <dc:creator>Juan Martin</dc:creator>
      <pubDate>Thu, 10 Jul 2025 16:51:18 +0000</pubDate>
      <link>https://dev.to/tinchox5/snapdom-performance-benchmarks-for-clientside-screenshots-47kf</link>
      <guid>https://dev.to/tinchox5/snapdom-performance-benchmarks-for-clientside-screenshots-47kf</guid>
      <description>&lt;p&gt;Snapdom has made &lt;strong&gt;major performance leaps&lt;/strong&gt; since &lt;code&gt;v1.8.0&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Simple elements (ms, lower is better)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Snapdom (current)&lt;/th&gt;
&lt;th&gt;Snapdom v1.8.0&lt;/th&gt;
&lt;th&gt;html2canvas&lt;/th&gt;
&lt;th&gt;modern-screenshot&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Small (200×100)&lt;/td&gt;
&lt;td&gt;0.4&lt;/td&gt;
&lt;td&gt;1.2&lt;/td&gt;
&lt;td&gt;70.3&lt;/td&gt;
&lt;td&gt;11.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modal (400×300)&lt;/td&gt;
&lt;td&gt;0.4&lt;/td&gt;
&lt;td&gt;1.1&lt;/td&gt;
&lt;td&gt;68.8&lt;/td&gt;
&lt;td&gt;14.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Page View&lt;/td&gt;
&lt;td&gt;0.4&lt;/td&gt;
&lt;td&gt;1.0&lt;/td&gt;
&lt;td&gt;100.5&lt;/td&gt;
&lt;td&gt;34.2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Large Scroll&lt;/td&gt;
&lt;td&gt;0.4&lt;/td&gt;
&lt;td&gt;1.0&lt;/td&gt;
&lt;td&gt;153.1&lt;/td&gt;
&lt;td&gt;77.8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Very Large&lt;/td&gt;
&lt;td&gt;0.4&lt;/td&gt;
&lt;td&gt;1.0&lt;/td&gt;
&lt;td&gt;278.9&lt;/td&gt;
&lt;td&gt;194.7&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Complex elements (ms)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Snapdom (current)&lt;/th&gt;
&lt;th&gt;Snapdom v1.8.0&lt;/th&gt;
&lt;th&gt;html2canvas&lt;/th&gt;
&lt;th&gt;modern-screenshot&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Small (200×100)&lt;/td&gt;
&lt;td&gt;1.1&lt;/td&gt;
&lt;td&gt;3.2&lt;/td&gt;
&lt;td&gt;72.5&lt;/td&gt;
&lt;td&gt;16.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modal (400×300)&lt;/td&gt;
&lt;td&gt;4.5&lt;/td&gt;
&lt;td&gt;14.0&lt;/td&gt;
&lt;td&gt;90.1&lt;/td&gt;
&lt;td&gt;34.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Page View&lt;/td&gt;
&lt;td&gt;32.9&lt;/td&gt;
&lt;td&gt;113.6&lt;/td&gt;
&lt;td&gt;196.1&lt;/td&gt;
&lt;td&gt;181.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Large Scroll&lt;/td&gt;
&lt;td&gt;133.9&lt;/td&gt;
&lt;td&gt;387.4&lt;/td&gt;
&lt;td&gt;446.6&lt;/td&gt;
&lt;td&gt;635.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Very Large&lt;/td&gt;
&lt;td&gt;364.0&lt;/td&gt;
&lt;td&gt;1200.4&lt;/td&gt;
&lt;td&gt;1275.4&lt;/td&gt;
&lt;td&gt;1685.6&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  ⚡ Summary
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Snapdom (current) is &lt;strong&gt;2–4× faster&lt;/strong&gt; than v1.8.0
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Up to 500× faster than html2canvas&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Much faster&lt;/strong&gt; than modern-screenshot, especially with large/complex DOMs
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🧪 Benchmarks run with &lt;strong&gt;Chromium + Vitest&lt;/strong&gt; on a &lt;strong&gt;2018 MacBook Air&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
🏎️ Even better performance on modern hardware!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/zumerlab/snapdom/discussions/102" rel="noopener noreferrer"&gt;https://github.com/zumerlab/snapdom/discussions/102&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>opensource</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>Snapdom: a modern and faster alternative to html2canvas</title>
      <dc:creator>Juan Martin</dc:creator>
      <pubDate>Tue, 01 Jul 2025 07:36:50 +0000</pubDate>
      <link>https://dev.to/tinchox5/snapdom-a-modern-and-faster-alternative-to-html2canvas-1m9a</link>
      <guid>https://dev.to/tinchox5/snapdom-a-modern-and-faster-alternative-to-html2canvas-1m9a</guid>
      <description>&lt;p&gt;In less than two months, &lt;a href="https://github.com/zumerlab/snapdom" rel="noopener noreferrer"&gt;Snapdom&lt;/a&gt; reached &lt;strong&gt;2,120+ stars&lt;/strong&gt;, with 7 contributors and a growing user base. But the goal has been clear since day one:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Build a modern, accurate and fast replacement for &lt;code&gt;html2canvas&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Why a replacement?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;html2canvas&lt;/code&gt; was a milestone. I love it. It brought DOM-to-image to mainstream frontend. But time has passed, and the web platform has evolved: higher DPI screens, complex shadows, pseudo-elements with &lt;code&gt;::before { content: url(...) }&lt;/code&gt;, imported icon fonts, variables inside gradients, shadow DOM, web components, and more.&lt;/p&gt;

&lt;p&gt;Many of those features don’t render correctly in &lt;code&gt;html2canvas&lt;/code&gt;. Snapdom aims to &lt;strong&gt;fix that&lt;/strong&gt; with a new approach.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7863f4h357vzfwx09wow.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7863f4h357vzfwx09wow.gif" alt="Benchmark" width="542" height="496"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  What Snapdom does differently
&lt;/h3&gt;

&lt;p&gt;Snapdom captures how a DOM &lt;strong&gt;looks&lt;/strong&gt;. While tools like &lt;code&gt;html2canvas&lt;/code&gt; attempt to reproduce the layout procedurally using canvas drawing commands, Snapdom takes a different route:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It builds a &lt;strong&gt;visual clone&lt;/strong&gt; of the DOM using a serialized structure and renders it via &lt;strong&gt;SVG with &lt;code&gt;&amp;lt;foreignObject&amp;gt;&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Styles are computed via &lt;code&gt;getComputedStyle()&lt;/code&gt; and inlined per element, or &lt;strong&gt;collapsed into reusable CSS classes&lt;/strong&gt; when &lt;code&gt;compress&lt;/code&gt; mode is enabled.&lt;/li&gt;
&lt;li&gt;Snapdom uses &lt;strong&gt;caching strategies&lt;/strong&gt; for computed styles, fonts, and DOM shape to improve render performance.&lt;/li&gt;
&lt;li&gt;It supports &lt;strong&gt;hi-DPI scaling&lt;/strong&gt;, fixed size snapshots, and consistent box models across browsers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach makes it fast, modular, and portable — and allows Snapdom to produce &lt;strong&gt;SVG output that can be rendered, embedded, or exported&lt;/strong&gt; in almost any format.&lt;/p&gt;

&lt;h3&gt;
  
  
  Visual fidelity
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Captures &lt;code&gt;::before&lt;/code&gt; / &lt;code&gt;::after&lt;/code&gt; / &lt;code&gt;::first-letter&lt;/code&gt;, including icons, URLs and inline content.&lt;/li&gt;
&lt;li&gt;Supports &lt;code&gt;background-image&lt;/code&gt; with multiple layers: &lt;code&gt;url()&lt;/code&gt;, &lt;code&gt;linear-gradient(...)&lt;/code&gt;, &lt;code&gt;var(...)&lt;/code&gt;, mixed.&lt;/li&gt;
&lt;li&gt;Handles shadows, filters, transforms, blend modes, scroll, overflow, and z-index correctly.&lt;/li&gt;
&lt;li&gt;Captures shadow DOM content and visual order.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Fonts and icon support
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Full support for &lt;code&gt;@font-face&lt;/code&gt; via stylesheets or &lt;code&gt;FontFace()&lt;/code&gt; constructor.&lt;/li&gt;
&lt;li&gt;Correct rendering of &lt;strong&gt;icon fonts&lt;/strong&gt; (FontAwesome, Material Icons, etc.) — including inside pseudo-elements.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;embedFonts: true&lt;/code&gt; will inline all fonts into the SVG.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  DOM state
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Captures &lt;strong&gt;current values&lt;/strong&gt; of inputs, selects, and textareas.&lt;/li&gt;
&lt;li&gt;Preserves scroll position (&lt;code&gt;scrollTop&lt;/code&gt;, &lt;code&gt;scrollLeft&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;HiDPI / Retina support via &lt;code&gt;devicePixelRatio&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Optional fixed dimensions with &lt;code&gt;width&lt;/code&gt; and/or &lt;code&gt;height&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;snapdom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;768&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;embedFonts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;compress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Performance-focused
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Snapshots in &lt;strong&gt;milliseconds&lt;/strong&gt;, even on complex pages.&lt;/li&gt;
&lt;li&gt;One-time capture → multiple exports:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;snapdom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toSvg&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toPng&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toWebp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Coming soon: Plugin system
&lt;/h3&gt;

&lt;p&gt;We're working on a &lt;strong&gt;native plugin architecture&lt;/strong&gt; so anyone can extend Snapdom with custom needs.&lt;/p&gt;

&lt;p&gt;Some ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Watermarking&lt;/li&gt;
&lt;li&gt;PDF export&lt;/li&gt;
&lt;li&gt;WebGL / canvas integration&lt;/li&gt;
&lt;li&gt;Post-capture mutation (blurring, tinting, overlays, etc.)&lt;/li&gt;
&lt;li&gt;Integration with visual editors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The plugin API will allow users to hook into preprocessing, postprocessing, and export logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  API at a glance
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;snapdom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;compress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;embedFonts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;crossOrigin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;anonymous&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Exports&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toSvg&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toCanvas&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toPng&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toWebp&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toImg&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;data-capture="exclude"&lt;/code&gt; skips a node and its children.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-capture="placeholder"&lt;/code&gt; replaces a node with an empty box (useful for ads, iframes, etc).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;📦 GitHub → &lt;a href="https://github.com/zumerlab/snapdom" rel="noopener noreferrer"&gt;github.com/zumerlab/snapdom&lt;/a&gt;&lt;br&gt;
🧪 Live demo → &lt;a href="https://zumerlab.github.io/snapdom" rel="noopener noreferrer"&gt;zumerlab.github.io/snapdom&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Snapdom is fully browser-based. No canvas hacks, no server dependency. Just clean JS + SVG + Web APIs.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We're actively looking for feedback and contributors. If you're hitting limits with &lt;code&gt;html2canvas&lt;/code&gt;, try Snapdom and help shape its future.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>opensource</category>
    </item>
    <item>
      <title>A practical way to test HTML and CSS in real-time using only CSS.</title>
      <dc:creator>Juan Martin</dc:creator>
      <pubDate>Wed, 28 Aug 2024 13:16:39 +0000</pubDate>
      <link>https://dev.to/tinchox5/a-practical-way-to-test-html-and-css-in-real-time-using-only-css-3c80</link>
      <guid>https://dev.to/tinchox5/a-practical-way-to-test-html-and-css-in-real-time-using-only-css-3c80</guid>
      <description>&lt;p&gt;Recently, I made public &lt;a href="https://dev.to/tinchox5/orbit-a-css-framework-for-crafting-simple-or-complex-radial-interfaces-2463"&gt;a CSS framework&lt;/a&gt; I developed for creating radial designs. During development, I faced several challenges, including testing different features. I noticed that CSS linters and other tools didn't allow me to see why something wasn't working, even if there were no basic errors. Another typical CSS problem was seeing how it was shared across different browsers. Fortunately, I discovered that certain new CSS features can be used to create a series of real-time tests. These features are &lt;code&gt;@support&lt;/code&gt;, &lt;code&gt;@container&lt;/code&gt;, and &lt;code&gt;:has()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By combining these features, I developed a testing system not only to check if the framework works in the browser but also, and most importantly, to see if we are applying HTML correctly according to the browser's requirements and avoiding involuntary errors when developing an application.&lt;/p&gt;

&lt;p&gt;Since my CSS framework necessarily uses features that only the newest browsers have, such as trigonometric functions like &lt;code&gt;cos()&lt;/code&gt; and &lt;code&gt;sin()&lt;/code&gt;, I created a series of rules to test if they are supported by the browser. If they're not, a message appears asking to update the browser. Similarly, if the browser doesn't support &lt;code&gt;:has()&lt;/code&gt;, which is used throughout the framework.&lt;/p&gt;

&lt;p&gt;There are also typical cases of browser incompatibility, so in some non-critical cases, I use &lt;code&gt;@support&lt;/code&gt; or &lt;code&gt;@container&lt;/code&gt; to hide certain Orbit features that don't affect its use. For example, Safari doesn't accept SVG &lt;code&gt;context-stroke&lt;/code&gt;, so I hide them.&lt;/p&gt;

&lt;p&gt;However, beyond those critical checks and compatibility, the most common issue when using a CSS framework is not knowing how to use it properly. That's why I created other CSS rules that allow analyzing if a parent element has the required child elements and not others. Here, visual alerts also appear while developing to give a hint about where the error is in the code.&lt;/p&gt;

&lt;p&gt;I don't want to bore you with the details specific to Orbit, but I'll leave you the link to the support source and related documentation.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/zumerlab/orbit" rel="noopener noreferrer"&gt;https://github.com/zumerlab/orbit&lt;/a&gt;&lt;br&gt;
Source file: &lt;a href="https://github.com/zumerlab/orbit/blob/main/src/scss/_support.scss" rel="noopener noreferrer"&gt;https://github.com/zumerlab/orbit/blob/main/src/scss/_support.scss&lt;/a&gt;&lt;br&gt;
Orbit Support documtation: &lt;a href="https://zumerlab.github.io/orbit-docs/tools/support/" rel="noopener noreferrer"&gt;https://zumerlab.github.io/orbit-docs/tools/support/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Good to go deeper:  &lt;a href="https://heydonworks.com/article/testing-html-with-modern-css" rel="noopener noreferrer"&gt;https://heydonworks.com/article/testing-html-with-modern-css&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>testing</category>
    </item>
    <item>
      <title>Orbit a CSS framework for crafting simple or complex radial interfaces.</title>
      <dc:creator>Juan Martin</dc:creator>
      <pubDate>Tue, 27 Aug 2024 10:11:02 +0000</pubDate>
      <link>https://dev.to/tinchox5/orbit-a-css-framework-for-crafting-simple-or-complex-radial-interfaces-2463</link>
      <guid>https://dev.to/tinchox5/orbit-a-css-framework-for-crafting-simple-or-complex-radial-interfaces-2463</guid>
      <description>&lt;p&gt;Hi Devs!&lt;/p&gt;

&lt;p&gt;I've been a long-time fan of DEV, but this is my first post. I'm excited to introduce &lt;strong&gt;Orbit&lt;/strong&gt;, a new CSS framework I've created that allows you to build radial interfaces &lt;strong&gt;using only CSS&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Orbit has a flexible API that borrows some spatial design concepts to make it familiar and easy to use. With Orbit, you can create complex radial layouts and designs without writing a single line of JavaScript. Imagine building gauges, charts, watches, Mini Cooper dashboards ;), solar systems, and even esoteric user interfaces seen in sci-fi movies! You can achieve all those and more with CSS. &lt;/p&gt;

&lt;p&gt;I'll stop here, as I just want to introduce Orbit to the community. In future posts, I plan to write some tutorials and examples to help you get started with Orbit. If you have any suggestions for examples or projects you'd like to see, please let me know! &lt;/p&gt;

&lt;p&gt;I left here a Codepen example&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/zircle/embed/poXKqwz?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I'd love to hear your feedback.&lt;/p&gt;

&lt;p&gt;Thank you,&lt;br&gt;
Martin&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/zumerlab/orbit" rel="noopener noreferrer"&gt;Repository link&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zumerlab.github.io/orbit-docs" rel="noopener noreferrer"&gt;Documentation link&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
