<?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: Danny Engelman</title>
    <description>The latest articles on DEV Community by Danny Engelman (@dannyengelman).</description>
    <link>https://dev.to/dannyengelman</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F108898%2F57f8bc74-d9d8-449a-88bd-7bd59b4c2751.jpeg</url>
      <title>DEV Community: Danny Engelman</title>
      <link>https://dev.to/dannyengelman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dannyengelman"/>
    <language>en</language>
    <item>
      <title>Web Components did not fail!</title>
      <dc:creator>Danny Engelman</dc:creator>
      <pubDate>Thu, 08 Oct 2026 09:52:55 +0000</pubDate>
      <link>https://dev.to/dannyengelman/web-components-did-not-fail-3a2b</link>
      <guid>https://dev.to/dannyengelman/web-components-did-not-fail-3a2b</guid>
      <description>&lt;p&gt;My comment to yesterdays Dev.to post: &lt;a href="https://dev.to/matthewdean/web-components-failed-we-can-fix-them-1o37"&gt;Web components failed. We can fix them&lt;/a&gt; became a full post:&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR:
&lt;/h2&gt;

&lt;p&gt;Web Components never failed.&lt;br&gt;
Browser vendors have used Web Component-based architecture for decades.&lt;br&gt;
Yet developers keep building apps, inventing frameworks, and adding dependencies instead of embracing the platform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build apps with frameworks. Build components with Web Components.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The technology isn't the problem. Our mindset is.&lt;/p&gt;

&lt;p&gt;From the comments:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The line about every &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; being proof really stuck with me.&lt;br&gt;
I swapped a framework-tied date picker for a Web Component a while back.&lt;br&gt;
And it's the only piece that survived two framework migrations untouched.&lt;/em&gt;&lt;/p&gt;


&lt;h1&gt;
  
  
  Web Components Never Failed
&lt;/h1&gt;


&lt;h3&gt;
  
  
  Web Component history
&lt;/h3&gt;

&lt;p&gt;The Web Component story didn't start with today's Custom Elements.&lt;/p&gt;

&lt;p&gt;Almost &lt;strong&gt;28 years ago&lt;/strong&gt;, in 1998, Microsoft proposed &lt;strong&gt;HTML Components (HTC)&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.w3.org/TR/NOTE-HTMLComponents" rel="noopener noreferrer"&gt;https://www.w3.org/TR/NOTE-HTMLComponents&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In 2006, Mozilla took its own stab at componentizing the Web with &lt;strong&gt;XBL&lt;/strong&gt;, first developed for Mozilla and later proposed as a specification:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www-archive.mozilla.org/projects/xbl/" rel="noopener noreferrer"&gt;https://www-archive.mozilla.org/projects/xbl/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Different technologies, different APIs — but the same underlying desire:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Make pieces of the Web reusable, encapsulated, and programmable.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h3&gt;
  
  
  Your Web Browser serves you Web Components... &lt;br&gt;on every Web page!
&lt;/h3&gt;

&lt;p&gt;Browser vendors have been using Web Component machinery for many moons longer than we mortal developers have had today's standardized Web Components APIs.&lt;/p&gt;

&lt;p&gt;To Us, Modern Web Components became broadly available roughly around:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chrome 2016 · Safari 2017 · Firefox 2018 · Edge 2020&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But browsers themselves have always had that same problem to solve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The WHATWG specifies &lt;strong&gt;what an HTML element should do&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Browser vendors still have to decide &lt;strong&gt;how to build it&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Take a complex native element such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;textarea&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the developer's perspective, that's one element.&lt;/p&gt;

&lt;p&gt;Underneath, there may be an entire internal UI: buttons, sliders, labels, tracks, controls and state.&lt;/p&gt;

&lt;p&gt;That should sound familiar.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It is the same &lt;em&gt;Web Component&lt;/em&gt; technology us mortal developers use!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://devtoolstips.org/tips/en/inspect-user-agent-dom/" rel="noopener noreferrer"&gt;the appropriate DevTools settings&lt;/a&gt;, browsers can expose these internal &lt;em&gt;shadowDOM&lt;/em&gt; trees for inspection.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; with sahdowDOM in Chromium
&lt;/h3&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa90hvfm0jivufjv8xfye.png" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa90hvfm0jivufjv8xfye.png" alt="Chromium video Shadow DOM" width="731" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; with shadowDOM in Firefox
&lt;/h3&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcgt7acvzv8ymyyi6vvjl.png" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcgt7acvzv8ymyyi6vvjl.png" alt="Firefox video Shadow DOM" width="767" height="183"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They're not your DOM to manipulate.&lt;/p&gt;

&lt;p&gt;They're implementation details.&lt;/p&gt;

&lt;p&gt;And that's precisely the point.&lt;/p&gt;




&lt;h2&gt;
  
  
  Web Components did NOT fail
&lt;/h2&gt;

&lt;p&gt;So saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Web Components failed."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;has always sounded a little strange to me.&lt;/p&gt;

&lt;p&gt;We interact with componentized browser &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; UI &lt;strong&gt;every single day&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The browser platform itself demonstrates why encapsulated components are useful.&lt;/p&gt;

&lt;p&gt;The question isn't whether components work.&lt;/p&gt;

&lt;p&gt;The interesting question is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why don't we build more of our own software that way?&lt;/strong&gt;&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fruj9zqu4dslmbi5upub8.png" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fruj9zqu4dslmbi5upub8.png" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Mortal developers and Web Components
&lt;/h2&gt;

&lt;p&gt;I think part of the problem is that we keep thinking in &lt;strong&gt;Apps&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Frameworks encourage that.&lt;/p&gt;

&lt;p&gt;They scaffold applications.&lt;/p&gt;

&lt;p&gt;They give us routing, state management, rendering systems, build pipelines, dependency graphs and application architecture.&lt;/p&gt;

&lt;p&gt;And that's perfectly fine when you're building an application.&lt;/p&gt;

&lt;p&gt;But:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Frameworks scaffold Apps.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Components are components.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A component doesn't necessarily need to know anything about your application.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;&amp;lt;date-picker&amp;gt;&lt;/code&gt; doesn't care whether the surrounding application uses React, Vue, PHP, Django or plain HTML. Or the car is painted red.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;&amp;lt;relative-time&amp;gt;&lt;/code&gt; shouldn't need to know either.&lt;/p&gt;

&lt;p&gt;Neither should:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;car&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;tire&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;steering&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;wheel&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;playing&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;card&lt;/span&gt; &lt;span class="nx"&gt;rank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Queen&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;suit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hearts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/playing-card&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;mark&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;down&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;playing-card-component-usage.md&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/mark-down&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;They should just work!&lt;/strong&gt;&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fruj9zqu4dslmbi5upub8.png" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fruj9zqu4dslmbi5upub8.png" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  We &lt;em&gt;are&lt;/em&gt; still building Apps like it's 1899
&lt;/h2&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff9dyvoye3w5atvfrb3bf.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff9dyvoye3w5atvfrb3bf.jpg" alt=" " width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There's another problem.&lt;/p&gt;

&lt;p&gt;Many developers learned one particular way of building software and then taught those patterns to coworkers, and — directly or indirectly — to AI.&lt;/p&gt;

&lt;p&gt;So AI happily reproduces them — and teaches the next generation that this is simply how software is built.&lt;/p&gt;

&lt;p&gt;Ask AI to build something and you'll often get an entire application architecture when what you actually needed was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;something&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;useful&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tool isn't necessarily wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We're asking it to build the wrong thing.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's a mindset change.&lt;/p&gt;

&lt;p&gt;Change your perspective from:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Everything is an App&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;to:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apps with frameworks. Components with Web Components.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are &lt;em&gt;Henry Fords&lt;/em&gt; out there already working differently.&lt;/p&gt;

&lt;p&gt;And I suspect some of them aren't shouting about it.&lt;/p&gt;

&lt;p&gt;Why would they?&lt;/p&gt;

&lt;p&gt;Once you've trained your tools — and your AI — to produce small, independent components instead of miniature applications, it can become a competitive advantage.&lt;/p&gt;




&lt;h2&gt;
  
  
  "I can do Web Components better!"
&lt;/h2&gt;

&lt;p&gt;In 2022 there were already around &lt;strong&gt;60&lt;/strong&gt; &lt;em&gt;Frameworks, Libraries and BaseClasses&lt;/em&gt; listed in:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://webcomponents.dev/blog/all-the-ways-to-make-a-web-component/" rel="noopener noreferrer"&gt;I-can-do-Web-Components-better&lt;/a&gt; (aka All the ways to make a Web Component)&lt;/p&gt;

&lt;p&gt;Sixty!&lt;/p&gt;

&lt;p&gt;And here's where I think we repeatedly take the wrong turn.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You discover Web Components&lt;/li&gt;
&lt;li&gt;You develop a few helper functions&lt;/li&gt;
&lt;li&gt;Then: &lt;em&gt;Oh, it needs this feature...&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Then another feature&lt;/li&gt;
&lt;li&gt;And another&lt;/li&gt;
&lt;li&gt;Soon you've created conventions&lt;/li&gt;
&lt;li&gt;Then abstractions&lt;/li&gt;
&lt;li&gt;Then dependencies&lt;/li&gt;
&lt;li&gt;Then documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Congratulations!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;You're building a framework&lt;/strong&gt; (or a Design System)&lt;br&gt;
&lt;strong&gt;And your ego just publsihed it to NPM&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead, write the abstractions &lt;strong&gt;you&lt;/strong&gt; need for &lt;strong&gt;your&lt;/strong&gt; components.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They don't have to become somebody else's architecture.&lt;/li&gt;
&lt;li&gt;They don't even have to be shared abstractions in your components. &lt;/li&gt;
&lt;li&gt;Duplicate your code! Something every "guru" developer told you &lt;strong&gt;not&lt;/strong&gt; to do.
A well trained AI is great at managing those.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What about (Google) Lit?
&lt;/h2&gt;

&lt;p&gt;Yes, I consider Lit a framework.&lt;/p&gt;

&lt;p&gt;It provides its own abstractions for rendering, reactivity and component state. &lt;/p&gt;

&lt;p&gt;That's useful if that's how you want to work.&lt;/p&gt;

&lt;p&gt;But it's not the only way to build Web Components.&lt;/p&gt;

&lt;p&gt;You don't have to write Lit's HTML template blobs.&lt;/p&gt;

&lt;p&gt;The DOM already has an API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&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;p&gt;isn't primitive.&lt;/p&gt;

&lt;p&gt;It's &lt;strong&gt;powerful&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You have the entire browser platform underneath you.&lt;/p&gt;

&lt;p&gt;Use it.&lt;/p&gt;

&lt;p&gt;Write a &lt;strong&gt;one line&lt;/strong&gt; &lt;em&gt;helper function&lt;/em&gt; (sell it to your PM as a &lt;em&gt;mini-Framework&lt;/em&gt;)&lt;br&gt;
&lt;/p&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;createElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
                       &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you are really using the platform!&lt;/p&gt;

&lt;p&gt;Note: That "guru" developer in your team now tells you to make this a library you can &lt;em&gt;import&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Don't! You are creating a &lt;em&gt;dependency&lt;/em&gt;!&lt;br&gt;
Use AI to manage your code! It is an AI &lt;em&gt;skill&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;customElements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;the-obligatory-counter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;HTMLElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// sets and returns this scope&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attachShadow&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;open&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="c1"&gt;// sets and returns this.shadowRoot&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&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="na"&gt;part&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;plus button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;textContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;onclick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;
                &lt;span class="p"&gt;}),&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;count-value&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="na"&gt;part&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;count value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;textContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
                &lt;span class="p"&gt;}),&lt;/span&gt;
                &lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&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="na"&gt;part&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;min button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;textContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;onclick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
                &lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;~~&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt;&lt;span class="p"&gt;;&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;h2&gt;
  
  
  Developing Web Components
&lt;/h2&gt;

&lt;p&gt;Develop Web Components like you use &lt;code&gt;.reduce()&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No developer ever told you that you must use it exactly like they do.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's the freedom Web Components give us.&lt;/p&gt;

&lt;p&gt;There doesn't have to be &lt;strong&gt;one architecture&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There doesn't have to be &lt;strong&gt;one framework&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There doesn't have to be &lt;strong&gt;one correct abstraction&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Build the component.&lt;/p&gt;

&lt;p&gt;Give it a useful API.&lt;/p&gt;

&lt;p&gt;Let the browser do the rest.&lt;/p&gt;




&lt;p&gt;So:&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Web Components never failed.&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Maybe we just haven't learned how to use them yet.&lt;/p&gt;

&lt;p&gt;Browser vendors already showed us how.&lt;/p&gt;

&lt;p&gt;Every &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt; is proof that complex functionality can live behind one simple HTML element.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If Browser vendors can do it. Why can't we?&lt;/strong&gt;&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsk0neww4wflv68qk4617.png" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsk0neww4wflv68qk4617.png" alt=" " width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;




</description>
      <category>webcomponents</category>
      <category>webdev</category>
      <category>ai</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Web Components without JavaScript?!</title>
      <dc:creator>Danny Engelman</dc:creator>
      <pubDate>Tue, 16 Sep 2025 13:34:46 +0000</pubDate>
      <link>https://dev.to/dannyengelman/web-components-without-javascript-ka4</link>
      <guid>https://dev.to/dannyengelman/web-components-without-javascript-ka4</guid>
      <description>&lt;h2&gt;
  
  
  You can replace all &lt;code&gt;&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  with &lt;code&gt;&amp;lt;tag-name&amp;gt;&amp;lt;/tag-name&amp;gt;&lt;/code&gt;
&lt;/h2&gt;





&lt;h3&gt;
  
  
  (since 2018) &lt;em&gt;ANY&lt;/em&gt; tagname with a &lt;em&gt;dash&lt;/em&gt; is a valid &lt;code&gt;HTMLElement&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Let me repeat that for clarity:&lt;/p&gt;

&lt;h3&gt;
  
  
  👉 &lt;em&gt;ANY&lt;/em&gt; 🤯 tagname with a &lt;em&gt;dash&lt;/em&gt; &lt;strong&gt;is a valid &lt;code&gt;HTMLElement&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  NOT &lt;code&gt;HTMLUnknownElement&lt;/code&gt; as some claim
&lt;/h3&gt;





&lt;p&gt;That means you can &lt;strong&gt;replace EVERY&lt;/strong&gt; &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; with &lt;em&gt;valid&lt;/em&gt; HTML&lt;/p&gt;

&lt;h3&gt;
  
  
  Then this &lt;em&gt;DIV-soup&lt;/em&gt;:
&lt;/h3&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%2Fm5du6vk7dzrg70fyyna3.png" 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%2Fm5du6vk7dzrg70fyyna3.png" alt="DIV soup" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Becomes &lt;em&gt;valid&lt;/em&gt; HTML:
&lt;/h3&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%2Fgao4rreq9z586gyu0etz.png" 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%2Fgao4rreq9z586gyu0etz.png" alt="No DIVs semantic HTML" width="799" height="397"&gt;&lt;/a&gt;&lt;/p&gt;





&lt;h3&gt;
  
  
  🧠 Good to know
&lt;/h3&gt;

&lt;p&gt;✅ Absolutely NO JavaScript required, its only HTML and CSS&lt;/p&gt;

&lt;p&gt;✅ This is &lt;strong&gt;standard&lt;/strong&gt; behaviour in all browsers since 2020&lt;br&gt;
(When Microsoft Edge switched to the Chromium Engine)&lt;br&gt;
and already in Chrome, Safari, Firefox many moons &lt;em&gt;before&lt;/em&gt; 2020&lt;/p&gt;

&lt;p&gt;✅ The &lt;a href="https://validator.w3.org/#validate_by_input" rel="noopener noreferrer"&gt;W3C HTML Validator&lt;/a&gt; accepts &lt;strong&gt;all&lt;/strong&gt; &lt;code&gt;&amp;lt;tag-name&amp;gt;&lt;/code&gt; Custom Elements with a dash as &lt;code&gt;HTMLElement&lt;/code&gt;.&lt;br&gt;
It does not accept &lt;code&gt;&amp;lt;tagname&amp;gt;&lt;/code&gt; (no dash), those are &lt;code&gt;HTMLUnknownElement&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;✅ &lt;a href="https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/html/resources/html.css;drc=5606f221713df59faee4d92851998db4d9d15aeb" rel="noopener noreferrer"&gt;The UA - UserAgent StyleSheet&lt;/a&gt; (Browsers &lt;em&gt;default stylesheet&lt;/em&gt;)&lt;br&gt;
defines CSS &lt;code&gt;[hidden] { display:none }&lt;/code&gt;.&lt;br&gt;
But Custom Elements do not inherit the &lt;em&gt;default stylesheet&lt;/em&gt;;&lt;br&gt;
so you have to add that behaviour yourself in your stylesheet.&lt;/p&gt;

&lt;p&gt;✅ &lt;code&gt;&amp;lt;DIV&amp;gt;&lt;/code&gt; is &lt;code&gt;display:block&lt;/code&gt; only in the &lt;em&gt;UA StyleSheet&lt;/em&gt;&lt;br&gt;
You have to set 𝙙𝙞𝙨𝙥𝙡𝙖𝙮: 𝙗𝙡𝙤𝙘𝙠 / 𝙞𝙣𝙡𝙞𝙣𝙚-𝙗𝙡𝙤𝙘𝙠; on these Custom Elements yourself&lt;br&gt;
(You will forget this 20 times, then you never make the mistake again)&lt;/p&gt;

&lt;p&gt;✅ The &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:defined" rel="noopener noreferrer"&gt;CSS :𝙙𝙚𝙛𝙞𝙣𝙚𝙙&lt;/a&gt; pseudo selector targets standard HTML tags and JavaScript defined Custom Elements  &lt;/p&gt;

&lt;p&gt;✅ Thus the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:defined#examples" rel="noopener noreferrer"&gt;CSS :𝙣𝙤𝙩(:𝙙𝙚𝙛𝙞𝙣𝙚𝙙)&lt;/a&gt; pseudo selector targets the 𝙪𝙣𝙙𝙚𝙛𝙞𝙣𝙚𝙙 &lt;strong&gt;Custom Elements&lt;/strong&gt;; they are still &lt;strong&gt;valid&lt;/strong&gt; &lt;code&gt;HTMLElement&lt;/code&gt;, CSS applies like any element&lt;/p&gt;

&lt;p&gt;✅ &lt;code&gt;&amp;lt;you-are-not-bound-to-one-dash&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;✅ &lt;a href="https://web.dev/articles/declarative-shadow-dom" rel="noopener noreferrer"&gt;Declarative ShadowDOM&lt;/a&gt;:&lt;br&gt;
&lt;code&gt;&amp;lt;template shadowrootmode="open"&amp;gt;&lt;/code&gt; creates &lt;strong&gt;undefined&lt;/strong&gt; Custom Elements with a shadowDOM&lt;/p&gt;

&lt;p&gt;✅ The &lt;strong&gt;Custom Elements API&lt;/strong&gt; (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements" rel="noopener noreferrer"&gt;MDN&lt;/a&gt;) requires JavaScript to convert &lt;strong&gt;undefined&lt;/strong&gt; Custom Elements (but valid HTMLElement!) into &lt;strong&gt;defined&lt;/strong&gt; Custom Elements.&lt;/p&gt;




&lt;h1&gt;
  
  
  🎉🎉🎉
&lt;/h1&gt;
&lt;h3&gt;
  
  
  No more hunting for that &lt;strong&gt;&lt;em&gt;closing&lt;/em&gt;&lt;/strong&gt; &lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt; tag
&lt;/h3&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;&amp;lt;/tag-name&amp;gt;&lt;/code&gt; is just there!
&lt;/h3&gt;




&lt;h2&gt;
  
  
  Are they &lt;em&gt;Web Components&lt;/em&gt;?
&lt;/h2&gt;

&lt;p&gt;Technologies &lt;strong&gt;&lt;em&gt;NOT&lt;/em&gt;&lt;/strong&gt; used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;shadowDOM&lt;/li&gt;
&lt;li&gt;Custom Elements &lt;strong&gt;API&lt;/strong&gt; (create &lt;strong&gt;defined&lt;/strong&gt; elements with JavaScript)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🛠 Prove ANY tagname with a dash IS a &lt;code&gt;HTMLElement&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;        &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;tagname&amp;gt;&amp;lt;/tagname&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;tag-name&amp;gt;&amp;lt;/tag-name&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;tag-name-foo&amp;gt;&amp;lt;/tag-name-foo&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;tag-name-bar&amp;gt;&amp;lt;/tag-name-bar&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;iframe src="https://jsfiddle.net/WebComponents/cmgjux9h/embedded/result,html//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;





&lt;h1&gt;
  
  
  NO MORE DIV-SOUP!
&lt;/h1&gt;

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

&lt;p&gt;✅ If you believe AI over a random Dev.to post:&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%2Fbuvtjw1hkevqkj11h7a4.png" 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%2Fbuvtjw1hkevqkj11h7a4.png" alt="https://i.imgur.com/LPM8BKB.png" width="571" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: every &lt;em&gt;evergreen&lt;/em&gt; browser knows what a Custom Element is, just ask yourself:&lt;/p&gt;

&lt;p&gt;(after reading: &lt;a href="https://web.dev/articles/declarative-shadow-dom" rel="noopener noreferrer"&gt;https://web.dev/articles/declarative-shadow-dom&lt;/a&gt;)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What happens with &lt;code&gt;&amp;lt;tag-name&amp;gt;&lt;/code&gt;, and CSS applied, when you &lt;em&gt;omit&lt;/em&gt; the &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt;?
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;tag-name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;shadowrootmode=&lt;/span&gt;&lt;span class="s"&gt;"open"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/tag-name&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;

&lt;br&gt;
&lt;br&gt;&lt;br&gt;

&lt;br&gt;
&lt;br&gt;

&lt;p&gt;&lt;iframe src="https://jsfiddle.net/WebComponents/62f1eLay/embedded/result,html,js//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>html</category>
      <category>webcomponents</category>
    </item>
    <item>
      <title>Using HTML to its full extend</title>
      <dc:creator>Danny Engelman</dc:creator>
      <pubDate>Wed, 06 Aug 2025 09:19:02 +0000</pubDate>
      <link>https://dev.to/dannyengelman/using-html-to-its-full-extend-24e</link>
      <guid>https://dev.to/dannyengelman/using-html-to-its-full-extend-24e</guid>
      <description>&lt;p&gt;After writing HTML for 31 years&lt;/p&gt;

&lt;p&gt;I switched from writing DIV-soup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"article-header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Hello, sad man&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to writing &lt;em&gt;Semanctic&lt;/em&gt; HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;article-header&amp;gt;&lt;/span&gt;Hello, happy man&lt;span class="nt"&gt;&amp;lt;/article-header&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;No&lt;/strong&gt; JavaScript required!&lt;/p&gt;

&lt;p&gt;Only CSS required, to replicate DIV block behaviour&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;article-header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;block&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;p&gt;This works,&lt;br&gt;
because modern browsers treat a &lt;code&gt;&amp;lt;tag-name&amp;gt;&lt;/code&gt; (with a dash) as a valid &lt;code&gt;HTMLElement&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Also read: &lt;a href="https://dev.to/dannyengelman/not-a-div-insidein-sightsite-18lj"&gt;https://dev.to/dannyengelman/not-a-div-insidein-sightsite-18lj&lt;/a&gt;&lt;/p&gt;

</description>
      <category>html</category>
      <category>webdev</category>
      <category>career</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Web Components - the untold story</title>
      <dc:creator>Danny Engelman</dc:creator>
      <pubDate>Mon, 04 Aug 2025 18:56:18 +0000</pubDate>
      <link>https://dev.to/dannyengelman/web-components-the-untold-story-417i</link>
      <guid>https://dev.to/dannyengelman/web-components-the-untold-story-417i</guid>
      <description>&lt;p&gt;In the mid-1990s, long before the era of React and Angular, the seeds of componentized web UI were already being sown:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Microsoft’s “HTML Components”&lt;/strong&gt; (HTCs) for Internet Explorer 4 (circa 1997) let you define reusable widgets in HTML, CSS, and JScript—living in &lt;code&gt;.htc&lt;/code&gt; files and attached via &lt;code&gt;behavior:url(...)&lt;/code&gt;. It was clunky, Windows-only, and plagued by cross-browser woes, but it proved the allure of packaged, reusable UI.&lt;/p&gt;

&lt;p&gt;A few years later, &lt;strong&gt;Mozilla&lt;/strong&gt; experimented with XBL (XML Binding Language) in Firefox 1.0 (2004). XBL let you declare new tags in XML, bind them to scripts and styles, and even override native widget behavior. Again, powerful—but complex, tied to the browser’s internals, and ultimately never standardized.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  2011: Alex Russell’s Amsterdam Lightbulb Moment
&lt;/h3&gt;

&lt;p&gt;At a crisp autumn conference in Amsterdam, &lt;em&gt;Googler&lt;/em&gt; Alex Russell took the stage with a simple yet radical vision:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“What if we let authors define their own elements—HTML tags—with their own markup, styles, and behavior—natively in the browser?”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;He sketched out four core primitives—&lt;strong&gt;Custom Elements&lt;/strong&gt;, &lt;strong&gt;Shadow DOM&lt;/strong&gt;, &lt;strong&gt;HTML Imports&lt;/strong&gt;, and &lt;strong&gt;HTML Templates&lt;/strong&gt;—that together would let web developers build encapsulated, reusable widgets without frameworks.&lt;/p&gt;

&lt;p&gt;Fast Forward to: 38m :&lt;a href="https://vimeo.com/33430613?#t=38m59s" rel="noopener noreferrer"&gt;&lt;em&gt;"Web Components and Model driven Views"&lt;/em&gt;&lt;/a&gt;&lt;br&gt;
Be aware the presented syntax totally changed when implemented as &lt;strong&gt;Web Components V1&lt;/strong&gt;!&lt;/p&gt;




&lt;h3&gt;
  
  
  Browser Vendors Eat Their Own Dog Food
&lt;/h3&gt;

&lt;p&gt;Fast-forward a few years, and these primitives were battle-tested inside the browsers themselves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; controls, with their dropdowns, keyboard handling, and focus rings, were refactored atop Shadow DOM to isolate complex internals.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;audio&amp;gt;&lt;/code&gt; players, complete with controls, timelines, and captions, too—each browser shipping its own custom element sealed behind a protective Shadow Root.&lt;/li&gt;
&lt;li&gt;Even form controls like &lt;code&gt;&amp;lt;input type="date"&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;progress&amp;gt;&lt;/code&gt; leverage these same technologies under the hood.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By using component tech for &lt;em&gt;their&lt;/em&gt; standard tags, browser vendors proved the performance, security, and maintainability benefits of encapsulation—and gave developers a live demo of Shadow DOM and Custom Elements in action.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;And then the Browser vendors opened up the technology to us mortal developers. But not as you might know it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  EVERY &lt;code&gt;&amp;lt;tag-name&amp;gt;&lt;/code&gt; Is a Custom Element
&lt;/h3&gt;

&lt;p&gt;Here’s the kicker: &lt;strong&gt;any valid HTML tag name containing a dash&lt;/strong&gt;—for example &lt;code&gt;&amp;lt;user-card&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;app-nav&amp;gt;&lt;/code&gt;, or even &lt;code&gt;&amp;lt;weather-widget&amp;gt;&lt;/code&gt;—is &lt;em&gt;already&lt;/em&gt; a fully-fledged &lt;code&gt;HTMLElement&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It parses, lays out, and styles just like &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It participates in the CSS cascade and can be targeted with selectors:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;  &lt;span class="nt"&gt;weather-widget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#ccc&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;ul&gt;
&lt;li&gt;It reserves the namespace so you’ll never conflict with a future standard tag.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That means you can immediately start structuring your markup semantically—replacing generic &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;s with &lt;code&gt;&amp;lt;site-header&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;product-list&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;chat-bubble&amp;gt;&lt;/code&gt;, etc.—and style them purely with CSS. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Absolutly NO JavaScript required to get the semantic and style benefits of “components.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Do remember to set &lt;code&gt;display:block&lt;/code&gt; (default on a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;) yourself!&lt;/p&gt;




&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;From Microsoft HTCs to Mozilla XBL, from Alex Russell’s talk in Amsterdam to the browser-built &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; controls, the Web Components idea has been decades in the making. &lt;/p&gt;

&lt;p&gt;Today, &lt;strong&gt;ANY&lt;/strong&gt; custom tag name is a native &lt;code&gt;HTMLElement&lt;/code&gt;. You don’t &lt;em&gt;need&lt;/em&gt; JavaScript to reap immediate gains in readability, maintainability, and style encapsulation—just start writing HTML and CSS with meaningful tag names. &lt;/p&gt;

&lt;h2&gt;
  
  
  The era of “div-soup” is finally over!
&lt;/h2&gt;

&lt;p&gt;Well... has been for nearly a decade now.&lt;/p&gt;

&lt;p&gt;And you might not want to pay for a "Web Components" course, that starts with a JavaScript example.&lt;/p&gt;




&lt;p&gt;Also read: &lt;a href="https://dev.to/dannyengelman/not-a-div-insidein-sightsite-18lj"&gt;https://dev.to/dannyengelman/not-a-div-insidein-sightsite-18lj&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Example replacing the DIV-soup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  This &lt;em&gt;DIV-soup&lt;/em&gt;:
&lt;/h3&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%2Fm5du6vk7dzrg70fyyna3.png" 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%2Fm5du6vk7dzrg70fyyna3.png" alt="DIV soup" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Without using any JavaScript!&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Becomes &lt;em&gt;valid&lt;/em&gt; HTML:
&lt;/h3&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%2Fgao4rreq9z586gyu0etz.png" 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%2Fgao4rreq9z586gyu0etz.png" alt="No DIVs semantic HTML" width="799" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webcomponents</category>
      <category>html</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Your first Web Component (without JavaScript)</title>
      <dc:creator>Danny Engelman</dc:creator>
      <pubDate>Wed, 23 Jul 2025 09:45:07 +0000</pubDate>
      <link>https://dev.to/dannyengelman/your-first-web-component-without-javascript-3m7d</link>
      <guid>https://dev.to/dannyengelman/your-first-web-component-without-javascript-3m7d</guid>
      <description>&lt;p&gt;Change your CSS grid definition:&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%2F31h9r9n3418kh72nje87.png" 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%2F31h9r9n3418kh72nje87.png" alt="oldskool DIV soup" width="641" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;to:&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%2F9maprfdbb5rtxxanz9ma.png" 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%2F9maprfdbb5rtxxanz9ma.png" alt="modern (non-javascript) Web Components" width="642" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and you are done writing your first Custom Element/Web Component&lt;/p&gt;

&lt;p&gt;No more &lt;em&gt;hunting&lt;/em&gt; for that closing &lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;YES! &lt;strong&gt;any&lt;/strong&gt; tagname with a (-) dash in the name is a valid &lt;code&gt;HTMLElement&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Also see: &lt;a href="https://dev.to/dannyengelman/not-a-div-insidein-sightsite-18lj"&gt;https://dev.to/dannyengelman/not-a-div-insidein-sightsite-18lj&lt;/a&gt;&lt;/p&gt;

</description>
      <category>html</category>
      <category>webdev</category>
      <category>webcomponents</category>
    </item>
    <item>
      <title>Not a DIV inside / in sight / in site</title>
      <dc:creator>Danny Engelman</dc:creator>
      <pubDate>Fri, 18 Jul 2025 09:00:59 +0000</pubDate>
      <link>https://dev.to/dannyengelman/not-a-div-insidein-sightsite-18lj</link>
      <guid>https://dev.to/dannyengelman/not-a-div-insidein-sightsite-18lj</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;You can replace all &lt;code&gt;&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt; with &lt;code&gt;&amp;lt;tag-name&amp;gt;&amp;lt;/tag-name&amp;gt;&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;





&lt;h4&gt;
  
  
  Later written blogposts:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;(Nov 2025) &lt;a href="https://matthewjamestaylor.com/div-custom-elements" rel="noopener noreferrer"&gt;https://matthewjamestaylor.com/div-custom-elements&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;





&lt;h3&gt;
  
  
  &lt;em&gt;ANY&lt;/em&gt; &lt;code&gt;&amp;lt;tag-name&amp;gt;&lt;/code&gt; &lt;em&gt;with a dash&lt;/em&gt; is a valid &lt;code&gt;HTMLElement&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Let me repeat that for clarity:&lt;/p&gt;

&lt;h3&gt;
  
  
  👉 &lt;em&gt;ANY&lt;/em&gt; 🤯 &lt;code&gt;&amp;lt;tag-name&amp;gt;&lt;/code&gt; &lt;em&gt;with a dash&lt;/em&gt; &lt;strong&gt;is a valid &lt;code&gt;HTMLElement&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  NOT &lt;code&gt;HTMLUnknownElement&lt;/code&gt; as some claim
&lt;/h3&gt;





&lt;p&gt;That means you can &lt;strong&gt;replace EVERY&lt;/strong&gt; &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; with &lt;em&gt;valid&lt;/em&gt; HTML&lt;/p&gt;

&lt;h3&gt;
  
  
  Then this &lt;em&gt;DIV-soup&lt;/em&gt;:
&lt;/h3&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%2Fm5du6vk7dzrg70fyyna3.png" 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%2Fm5du6vk7dzrg70fyyna3.png" alt="DIV soup" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Becomes &lt;em&gt;valid&lt;/em&gt; HTML:
&lt;/h3&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%2Fgao4rreq9z586gyu0etz.png" 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%2Fgao4rreq9z586gyu0etz.png" alt="No DIVs semantic HTML" width="799" height="397"&gt;&lt;/a&gt;&lt;/p&gt;





&lt;h3&gt;
  
  
  🧠 Good to know
&lt;/h3&gt;

&lt;p&gt;✅ Absolutely NO JavaScript required, it is only HTML and CSS&lt;/p&gt;

&lt;p&gt;✅ This is &lt;strong&gt;standard&lt;/strong&gt; behaviour in all browsers.&lt;br&gt;
Chrome (2016) Safari (2017) FireFox (2018) Edge (2020)&lt;/p&gt;

&lt;p&gt;✅ The &lt;a href="https://validator.w3.org/#validate_by_input" rel="noopener noreferrer"&gt;W3C HTML Validator&lt;/a&gt; accepts &lt;strong&gt;all&lt;/strong&gt; &lt;code&gt;&amp;lt;tag-name&amp;gt;&lt;/code&gt; Custom Elements with a dash as &lt;code&gt;HTMLElement&lt;/code&gt;.&lt;br&gt;
It does not accept &lt;code&gt;&amp;lt;tagname&amp;gt;&lt;/code&gt; (no dash), those are &lt;code&gt;HTMLUnknownElement&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;✅ Custom Elements do not inherit the standard [hidden] behaviour;&lt;br&gt;
so you have to add that behaviour yourself in your stylesheet.&lt;/p&gt;

&lt;p&gt;✅ Same for &lt;code&gt;&amp;lt;DIV&amp;gt;&lt;/code&gt; &lt;code&gt;display:block&lt;/code&gt;. You have to set 𝙙𝙞𝙨𝙥𝙡𝙖𝙮: 𝙗𝙡𝙤𝙘𝙠 / 𝙞𝙣𝙡𝙞𝙣𝙚-𝙗𝙡𝙤𝙘𝙠; on these Custom Elements yourself&lt;br&gt;
(You will forget this 20 times, then you never make the mistake again)&lt;/p&gt;

&lt;p&gt;✅ The &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:defined" rel="noopener noreferrer"&gt;CSS :𝙙𝙚𝙛𝙞𝙣𝙚𝙙&lt;/a&gt; pseudo selector targets standard HTML tags and JavaScript defined Custom Elements  &lt;/p&gt;

&lt;p&gt;✅ Thus the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:defined#examples" rel="noopener noreferrer"&gt;CSS :𝙣𝙤𝙩(:𝙙𝙚𝙛𝙞𝙣𝙚𝙙)&lt;/a&gt; pseudo selector targets the 𝙪𝙣𝙙𝙚𝙛𝙞𝙣𝙚𝙙 &lt;strong&gt;Custom Elements&lt;/strong&gt;; they are still &lt;strong&gt;valid&lt;/strong&gt; &lt;code&gt;HTMLElement&lt;/code&gt;, CSS applies like any element&lt;/p&gt;

&lt;p&gt;✅ &lt;code&gt;&amp;lt;you-are-not-bound-to-one-dash&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;✅ &lt;a href="https://web.dev/articles/declarative-shadow-dom" rel="noopener noreferrer"&gt;Declarative ShadowDOM&lt;/a&gt;:&lt;br&gt;
&lt;code&gt;&amp;lt;template shadowrootmode="open"&amp;gt;&lt;/code&gt; creates the same &lt;strong&gt;&lt;em&gt;undefined&lt;/em&gt; Custom Elements&lt;/strong&gt; &lt;em&gt;with a shadowDOM&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;✅ The &lt;strong&gt;Custom Elements API&lt;/strong&gt; (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements" rel="noopener noreferrer"&gt;MDN&lt;/a&gt;) requires JavaScript to convert &lt;strong&gt;&lt;em&gt;undefined&lt;/em&gt; Custom Elements&lt;/strong&gt; (but valid HTMLElements!) into &lt;strong&gt;&lt;em&gt;defined&lt;/em&gt; Custom Elements&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  🎉🎉🎉
&lt;/h1&gt;
&lt;h3&gt;
  
  
  No more hunting for that &lt;strong&gt;&lt;em&gt;closing&lt;/em&gt;&lt;/strong&gt; &lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt; tag
&lt;/h3&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;&amp;lt;/tag-name&amp;gt;&lt;/code&gt; is just there!
&lt;/h3&gt;




&lt;h3&gt;
  
  
  Repetition is always great
&lt;/h3&gt;

&lt;p&gt;✅ Absolutely NO JavaScript required, its only HTML and CSS&lt;/p&gt;




&lt;h2&gt;
  
  
  Are they &lt;em&gt;Web Components&lt;/em&gt;?
&lt;/h2&gt;

&lt;p&gt;Technologies &lt;strong&gt;&lt;em&gt;NOT&lt;/em&gt;&lt;/strong&gt; used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;shadowDOM&lt;/li&gt;
&lt;li&gt;Custom Elements &lt;strong&gt;API&lt;/strong&gt; (create &lt;strong&gt;defined&lt;/strong&gt; elements with JavaScript)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🛠 Prove ANY tagname with a dash IS a &lt;code&gt;HTMLElement&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;        &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;tagname&amp;gt;&amp;lt;/tagname&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;tag-name&amp;gt;&amp;lt;/tag-name&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;tag-name-foo&amp;gt;&amp;lt;/tag-name-foo&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;tag-name-bar&amp;gt;&amp;lt;/tag-name-bar&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;iframe src="https://jsfiddle.net/WebComponents/cmgjux9h/embedded/result,html//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7xola48v5b8ot0q0wpe8.png" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7xola48v5b8ot0q0wpe8.png" alt="Elements Diagram" width="799" height="443"&gt;&lt;/a&gt;&lt;/p&gt;





&lt;h1&gt;
  
  
  NO MORE DIV-SOUP!
&lt;/h1&gt;

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

&lt;p&gt;✅ If you believe AI over a random Dev.to post:&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%2Fbuvtjw1hkevqkj11h7a4.png" 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%2Fbuvtjw1hkevqkj11h7a4.png" alt="https://i.imgur.com/LPM8BKB.png" width="571" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: every &lt;em&gt;evergreen&lt;/em&gt; browser knows what a Custom Element is, just ask yourself:&lt;/p&gt;

&lt;p&gt;(after reading: &lt;a href="https://web.dev/articles/declarative-shadow-dom" rel="noopener noreferrer"&gt;https://web.dev/articles/declarative-shadow-dom&lt;/a&gt;)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What happens with &lt;code&gt;&amp;lt;tag-name&amp;gt;&lt;/code&gt;, and CSS applied, when you &lt;em&gt;omit&lt;/em&gt; the &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt;?
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;tag-name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;shadowrootmode=&lt;/span&gt;&lt;span class="s"&gt;"open"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/tag-name&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;

&lt;br&gt;
&lt;br&gt;&lt;br&gt;

&lt;br&gt;
&lt;br&gt;

&lt;p&gt;&lt;iframe src="https://jsfiddle.net/WebComponents/62f1eLay/embedded/result,html,js//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>html</category>
      <category>webdev</category>
      <category>webcomponents</category>
    </item>
    <item>
      <title>AI beaten by a &lt;chess-board&gt; Web Component</title>
      <dc:creator>Danny Engelman</dc:creator>
      <pubDate>Sat, 14 Jun 2025 10:34:27 +0000</pubDate>
      <link>https://dev.to/dannyengelman/ai-beaten-by-a-web-component-2791</link>
      <guid>https://dev.to/dannyengelman/ai-beaten-by-a-web-component-2791</guid>
      <description>&lt;p&gt;I submitted my &lt;a href="https://stackoverflow.com/beta/challenges/79651567/code-challenge-2-secret-messages-in-game-boards" rel="noopener noreferrer"&gt;Stack Overflow Challenges&lt;/a&gt; "cipher" entry&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://stackoverflow-challenges.github.io/cipher/index.html" rel="noopener noreferrer"&gt;https://stackoverflow-challenges.github.io/cipher/index.html&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;em&gt;cipher&lt;/em&gt; is about black rook &lt;strong&gt;moves&lt;/strong&gt; creating a Letter pattern on a chessboard. White pieces can not be captured.&lt;/p&gt;

&lt;p&gt;Can you see what pixelated letter is on this board?&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%2Fmifsrkwjo2tetndzkhcf.png" 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%2Fmifsrkwjo2tetndzkhcf.png" width="268" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ChatGPT: &lt;em&gt;What squares can the black rooks goto? Then what is the pixelated letter? White pieces can not be captured&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;it... eventually... comes up with the wrong answer:&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%2Fncukbvkhjq0rajb2kl0p.png" 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%2Fncukbvkhjq0rajb2kl0p.png" width="729" height="693"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Clear for every human:
&lt;/h3&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%2Flmxdt8c8eg5k0e36ea15.png" 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%2Flmxdt8c8eg5k0e36ea15.png" width="263" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  AI is cool, but it ain't intelligent
&lt;/h3&gt;

</description>
      <category>ai</category>
      <category>webcomponents</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>&lt;select-language&gt; Web Component</title>
      <dc:creator>Danny Engelman</dc:creator>
      <pubDate>Thu, 16 Jan 2025 10:31:57 +0000</pubDate>
      <link>https://dev.to/dannyengelman/web-component-j9p</link>
      <guid>https://dev.to/dannyengelman/web-component-j9p</guid>
      <description>&lt;p&gt;Sorry, I don't have the time to write an extensive blog post.&lt;/p&gt;

&lt;p&gt;Then again, a good &lt;strong&gt;Web Component&lt;/strong&gt; should explain itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  More docs: &lt;a href="https://language-select.github.io/" rel="noopener noreferrer"&gt;https://language-select.github.io/&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;After loading the Web Component, all HTML required is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;language-select&lt;/span&gt; &lt;span class="na"&gt;caption=&lt;/span&gt;&lt;span class="s"&gt;"Select a language"&lt;/span&gt; 
                 &lt;span class="na"&gt;selected=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt; 
                 &lt;span class="na"&gt;languages=&lt;/span&gt;&lt;span class="s"&gt;"en,nl,es,pt,jp,sk"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/language-select&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;iframe src="https://jsfiddle.net/WebComponents/c0jgfkrt/embedded/result,html//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;

&lt;br&gt;
&lt;br&gt;&lt;br&gt;

&lt;br&gt;
&lt;br&gt;

&lt;p&gt;&lt;iframe src="https://jsfiddle.net/WebComponents/62f1eLay/embedded/result,html,js//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>webcomponents</category>
      <category>html</category>
      <category>javascript</category>
    </item>
    <item>
      <title>My 1 year old GPT: Web Component Creator - is free source now</title>
      <dc:creator>Danny Engelman</dc:creator>
      <pubDate>Wed, 25 Dec 2024 16:40:29 +0000</pubDate>
      <link>https://dev.to/dannyengelman/my-1-year-old-gpt-web-component-creator-is-free-source-now-45pf</link>
      <guid>https://dev.to/dannyengelman/my-1-year-old-gpt-web-component-creator-is-free-source-now-45pf</guid>
      <description>&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;an OPENAI Plus (or more) account&lt;/li&gt;
&lt;li&gt;Knowing how to copy-paste text&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My online GPT is at:&lt;br&gt;
&lt;a href="https://chatgpt.com/g/g-quK0nMtwZ-web-component-creator-vanilla-javascript" rel="noopener noreferrer"&gt;https://chatgpt.com/g/g-quK0nMtwZ-web-component-creator-vanilla-javascript&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  How to create your own ChatGPT
&lt;/h1&gt;

&lt;p&gt;► Click &lt;strong&gt;Explore GPTs&lt;/strong&gt; in the left bar:&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%2Ffoxq5bf8rahwpueqxqsp.png" 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%2Ffoxq5bf8rahwpueqxqsp.png" width="197" height="73"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;► Click &lt;strong&gt;create&lt;/strong&gt; in the top-right:&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%2Fruc2wje1cizatqv6bndi.png" 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%2Fruc2wje1cizatqv6bndi.png" width="170" height="88"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;► Copy these GPT instructions: (select-all -&amp;gt; copy)&lt;br&gt;
Make any changes you want&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://jsfiddle.net/WebComponents/oaxz95dg/embedded/html//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Set Title, Description and (above) &lt;strong&gt;Instructions&lt;/strong&gt;&lt;br&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%2Fhd5d7pce0egcgzrt1qb1.png" 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%2Fhd5d7pce0egcgzrt1qb1.png" width="715" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;► Save&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%2Fdn2yyvx4cfc6e8pzu9wf.png" 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%2Fdn2yyvx4cfc6e8pzu9wf.png" width="172" height="89"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Share you knowledge
&lt;/h2&gt;

&lt;p&gt;I am not asking any money for this. If you make cool changes let them know in the comments&lt;/p&gt;



&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;

&lt;br&gt;
&lt;br&gt;&lt;br&gt;

&lt;br&gt;
&lt;br&gt;

&lt;p&gt;&lt;iframe src="https://jsfiddle.net/WebComponents/62f1eLay/embedded/result,html,js//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>webcomponents</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>:nth-child builder in a Web Component</title>
      <dc:creator>Danny Engelman</dc:creator>
      <pubDate>Fri, 13 Dec 2024 13:37:14 +0000</pubDate>
      <link>https://dev.to/dannyengelman/nth-child-builder-in-a-web-component-3bh2</link>
      <guid>https://dev.to/dannyengelman/nth-child-builder-in-a-web-component-3bh2</guid>
      <description>&lt;p&gt;Just a quick prototype.&lt;/p&gt;

&lt;p&gt;It is &lt;a href="https://github.com/nth-children/nth-children.github.io/blob/main/element.js" rel="noopener noreferrer"&gt;more about the source code&lt;/a&gt; than the visual result&lt;/p&gt;

&lt;p&gt;Better viewed at: &lt;a href="https://nth-children.github.io" rel="noopener noreferrer"&gt;https://nth-children.github.io&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;nth-children&lt;/span&gt; &lt;span class="na"&gt;cellcount=&lt;/span&gt;&lt;span class="s"&gt;"20"&lt;/span&gt; &lt;span class="na"&gt;smile=&lt;/span&gt;&lt;span class="s"&gt;"🤪"&lt;/span&gt; &lt;span class="na"&gt;columns=&lt;/span&gt;&lt;span class="s"&gt;"5"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/nth-children&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;iframe src="https://jsfiddle.net/WebComponents/qx0h2ypf/embedded/result,html//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>webcomponents</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Show favicon over A href link with a Web Component</title>
      <dc:creator>Danny Engelman</dc:creator>
      <pubDate>Thu, 12 Dec 2024 09:24:14 +0000</pubDate>
      <link>https://dev.to/dannyengelman/show-favicon-over-a-href-link-with-a-web-component-114d</link>
      <guid>https://dev.to/dannyengelman/show-favicon-over-a-href-link-with-a-web-component-114d</guid>
      <description>&lt;p&gt;After my previous longer blogpost &lt;a href="https://dev.to/dannyengelman/web-components-make-it-so-30gk"&gt;Make It Snow!&lt;/a&gt;,&lt;br&gt;
time for a smaller code-sized Web Component.&lt;/p&gt;

&lt;p&gt;This blogpost: &lt;a href="https://shkspr.mobi/blog/2024/10/using-a-css-cursor-to-show-the-external-links-favicon/" rel="noopener noreferrer"&gt;Using a CSS cursor to show the external link Favicon&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;converted to a &lt;code&gt;&amp;lt;show-favicon&amp;gt;&lt;/code&gt; (Vanilla JavaScript) Web Component:&lt;/p&gt;

&lt;p&gt;[open the &lt;strong&gt;Result&lt;/strong&gt; tab of this JSFiddle and hover over a link]&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://jsfiddle.net/WebComponents/2xvs94a5/embedded/html,result//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;That &lt;code&gt;setTimeout&lt;/code&gt; explained:&lt;br&gt;
&lt;a href="https://dev.to/dannyengelman/web-component-developers-do-not-connect-with-the-connectedcallback-yet-4jo7"&gt;Web Component developers do not connect with the connectedCallback (yet)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webcomponents</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>favicon</category>
    </item>
    <item>
      <title>Web Components? Make it so!</title>
      <dc:creator>Danny Engelman</dc:creator>
      <pubDate>Thu, 05 Dec 2024 17:03:52 +0000</pubDate>
      <link>https://dev.to/dannyengelman/web-components-make-it-so-30gk</link>
      <guid>https://dev.to/dannyengelman/web-components-make-it-so-30gk</guid>
      <description>&lt;p&gt;written: December &lt;strong&gt;2024&lt;/strong&gt;&lt;/p&gt;





&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/xteKObnaA2c" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;





&lt;h2&gt;
  
  
  Zach his &amp;lt;snow-fall&amp;gt; Web Component
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.zachleat.com/web/snow-fall/" rel="noopener noreferrer"&gt;https://www.zachleat.com/web/snow-fall/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/zachleat/snow-fall" rel="noopener noreferrer"&gt;https://github.com/zachleat/snow-fall&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Is a &lt;strong&gt;single &lt;code&gt;&amp;lt;snow-fall&amp;gt;&lt;/code&gt; Web Component&lt;/strong&gt; creating 200 snow-&lt;strong&gt;ball&lt;/strong&gt; DIVs falling down the screen.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://jsfiddle.net/WebComponents/1w2uk40s/embedded/result,html//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;





&lt;h1&gt;
  
  
  Which made me wonder...
&lt;/h1&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;h2&gt;
  
  
  What if instead of &lt;strong&gt;ONE&lt;/strong&gt; Web Component...
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ... each snowball would be a &lt;em&gt;unique&lt;/em&gt; &amp;lt;snow-flake&amp;gt;?
&lt;/h3&gt;

&lt;h3&gt;
  
  
  ... How many &amp;lt;snow-flake&amp;gt; Components can my CPU handle?
&lt;/h3&gt;





&lt;h2&gt;
  
  
  &lt;a href="https://make-it-snow.github.io/" rel="noopener noreferrer"&gt;https://make-it-snow.github.io/&lt;/a&gt;
&lt;/h2&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://github.com/make-it-snow/make-it-snow.github.io" rel="noopener noreferrer"&gt;GitHub source code&lt;/a&gt;
&lt;/h4&gt;





&lt;h1&gt;
  
  
  &amp;lt;make-it-snow&amp;gt; Web Component
&lt;/h1&gt;

&lt;h2&gt;
  
  
  an experiment in more and more Web Components
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Every snowflake is a unique Web Component &amp;lt;snow-flake&amp;gt; with an SVG image.&lt;/li&gt;
&lt;li&gt;Snowflakes are animated with CSS to fall down rotating and drift sideways.
&lt;/li&gt;
&lt;li&gt;Snowflakes are removed from the DOM when they reach the bottom of the screen (&lt;code&gt;onanimationend&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Instead of a fixed amount of snowflakes &lt;strong&gt;more&lt;/strong&gt; snowflakes are added every second. &lt;/li&gt;
&lt;li&gt;CSS animation FPS (Frames Per Second) is tracked.
When FPS is above a &lt;em&gt;threshold&lt;/em&gt; &lt;strong&gt;more&lt;/strong&gt; new snowflakes (Web Components) are added at the top of the screen (5 more every second). Below the &lt;em&gt;treshold&lt;/em&gt; less snowflakes are added.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;FPS can be changed with UP and DOWN arrow keys (once a second, hold down CTRL for 10x).&lt;/p&gt;

&lt;p&gt;On my slow? system I get an &lt;em&gt;&lt;strong&gt;equilibrium&lt;/strong&gt;&lt;/em&gt; at around &lt;strong&gt;400&lt;/strong&gt; total snowflakes on screen:&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%2Fvkk67q0p5wyf8qwj60ws.png" 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%2Fvkk67q0p5wyf8qwj60ws.png" alt="alt text" width="578" height="189"&gt;&lt;/a&gt;&lt;/p&gt;





&lt;h2&gt;
  
  
  &lt;a href="https://make-it-snow.github.io/" rel="noopener noreferrer"&gt;https://make-it-snow.github.io/&lt;/a&gt;
&lt;/h2&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://github.com/make-it-snow/make-it-snow.github.io" rel="noopener noreferrer"&gt;GitHub source code&lt;/a&gt;
&lt;/h4&gt;





&lt;p&gt;&lt;iframe src="https://jsfiddle.net/WebComponents/grafqt76/embedded/result,html//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;





&lt;h2&gt;
  
  
  Creating a unique SVG snowflake
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Create one "spike" from 3 SVG paths with random width and opacity
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;spike&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;M70 70v-60&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;M45 28l25 18l28-16&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;M50 11l20 20l20-20&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="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dpath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;opacity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;path opacity="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" stroke-width="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" d="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dpath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"/&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;iframe src="https://jsfiddle.net/WebComponents/v489mupt/embedded/result,html//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h4&gt;
  
  
  Rotate each &lt;em&gt;spike&lt;/em&gt; 4,6 or 8 times
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;spikecount&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// from random([4,6,8])&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;360&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;spikecount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// calculate degrees offset for each spike&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;degrees&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;spikerotation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;degrees&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// all spikes make up a snowflake&lt;/span&gt;
    &lt;span class="c1"&gt;// every snowflake is in a shadowDOM, so its save to reference ID values!!&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;use href="#spike" transform="rotate(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;spikerotation&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 70 70)"/&amp;gt;`&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;p&gt;That will create all unique SVG snowflakes:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://jsfiddle.net/WebComponents/grafqt76/embedded/result,html//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;





&lt;h2&gt;
  
  
  &lt;a href="https://make-it-snow.github.io/" rel="noopener noreferrer"&gt;https://make-it-snow.github.io/&lt;/a&gt;
&lt;/h2&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://github.com/make-it-snow/make-it-snow.github.io" rel="noopener noreferrer"&gt;GitHub source code&lt;/a&gt;
&lt;/h4&gt;





&lt;h2&gt;
  
  
  URL parameters and Attributes
&lt;/h2&gt;

&lt;p&gt;The &amp;lt;make-it-snow&amp;gt; Web Component can be configured with URL parameters or Attributes. Also see index.html Page Source.&lt;/p&gt;

&lt;h3&gt;
  
  
  URL examples
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://make-it-snow.github.io/?flakecount=400" rel="noopener noreferrer"&gt;https://make-it-snow.github.io/?flakecount=400&lt;/a&gt; (already too much for my system)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://make-it-snow.github.io/?maxflakes=100" rel="noopener noreferrer"&gt;https://make-it-snow.github.io/?maxflakes=100&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://make-it-snow.github.io/?size=4&amp;amp;spikecount=4&amp;amp;color=gold&amp;amp;speed=2" rel="noopener noreferrer"&gt;https://make-it-snow.github.io/?size=4&amp;amp;spikecount=4&amp;amp;color=gold&amp;amp;speed=2&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://make-it-snow.github.io/?fps=60" rel="noopener noreferrer"&gt;https://make-it-snow.github.io/?fps=60&lt;/a&gt;&lt;br&gt;
60 is the default Browser FPS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://make-it-snow.github.io/?fps=1" rel="noopener noreferrer"&gt;https://make-it-snow.github.io/?fps=1&lt;/a&gt;&lt;br&gt;
Will this get us the most snowflakes? And terrible "animation"!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://make-it-snow.github.io/?counters=no&amp;amp;quotes=no" rel="noopener noreferrer"&gt;https://make-it-snow.github.io/?counters=no&amp;amp;quotes=no&lt;/a&gt;  Cleaner UI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://make-it-snow.github.io/index.html?fps=10&amp;amp;quotes=no&amp;amp;size=20" rel="noopener noreferrer"&gt;https://make-it-snow.github.io/index.html?fps=10&amp;amp;quotes=no&amp;amp;size=20&lt;/a&gt; - &lt;br&gt;
Interesting, this make the H1 and H2 at higher z-index flicker&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  parameters
&lt;/h3&gt;

&lt;p&gt;URL parameters only&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Default Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;flakecount&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Number of snow flakes to start with&lt;/td&gt;
&lt;td&gt;&lt;code&gt;300&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;addflakes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Number of snow flakes to add every second&lt;/td&gt;
&lt;td&gt;&lt;code&gt;20&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;maxflakes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A treshold when &lt;strong&gt;not&lt;/strong&gt; to add more &lt;code&gt;&amp;lt;snow-flake&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1000&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fps&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;FPS threshold, change with (ctrl) arrow up/down keys&lt;/td&gt;
&lt;td&gt;&lt;code&gt;30&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;minstrokewidth&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;minimal SVG path width&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;maxstrokewidth&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;maximum SVG path width&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&amp;lt;snow-flake&amp;gt; Attributes OR URL parameters&lt;/p&gt;

&lt;p&gt;See &lt;a href="https://make-it-snow.github.io/index.html" rel="noopener noreferrer"&gt;https://make-it-snow.github.io/index.html&lt;/a&gt; page source&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Default Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;color&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;(string/csv) snowflake color&lt;/td&gt;
&lt;td&gt;random[internal colors]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;(decimal) snowflake size&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rotate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;(int) initial start state&lt;/td&gt;
&lt;td&gt;&lt;code&gt;90&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;spikecount&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;(int/array) number of snowflake spike&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[4,6,8]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;speed&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;(int) fall down speed (seconds)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[4 - 12]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;drift&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;(int) sideways motion&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[-5 - 5]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;default size&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;opacity&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;default opacity&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cssrotation&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CSS rotation&lt;/td&gt;
&lt;td&gt;&lt;code&gt;random(-360,360)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;





&lt;h2&gt;
  
  
  &lt;a href="https://make-it-snow.github.io/" rel="noopener noreferrer"&gt;https://make-it-snow.github.io/&lt;/a&gt;
&lt;/h2&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://github.com/make-it-snow/make-it-snow.github.io" rel="noopener noreferrer"&gt;GitHub source code&lt;/a&gt;
&lt;/h4&gt;





&lt;h2&gt;
  
  
  Observations
&lt;/h2&gt;

&lt;p&gt;Feel free to add more in the comments&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;300 &lt;code&gt;&amp;lt;snow-flake&amp;gt;&lt;/code&gt; are 3 STYLE elements + 1 SVG in a shadowDOM&lt;br&gt;
That is 5 DOM elements for every &amp;lt;snow-flake&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I did not do much animation optimization. Feel free to suggest low hanging fruit&lt;br&gt;
CSS &lt;code&gt;will-change:transform&lt;/code&gt; (or not) doesn't seem to have a notable effect&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Its all CSS animation, I wonder what a fullscreen SVG with SMIL animation would do (requires some refactoring)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I now re-create a &lt;code&gt;&amp;lt;snow-flake&amp;gt;&lt;/code&gt;; wonder what happens when every new snowflake will also become a totally new Web Component &lt;code&gt;&amp;lt;snow-flake-[nr]&amp;gt;&lt;/code&gt;. Since we can not uncreate Web Components, will the &lt;code&gt;customElementRegistry&lt;/code&gt; eventually cause a Stack Overflow error?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;



&lt;br&gt;



&lt;p&gt;&lt;iframe src="https://jsfiddle.net/WebComponents/62f1eLay/embedded/result,html,js//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>webcomponents</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>animation</category>
    </item>
  </channel>
</rss>
