<?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>Forem: Danny Engelman</title>
    <description>The latest articles on Forem by Danny Engelman (@dannyengelman).</description>
    <link>https://forem.com/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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F108898%2F57f8bc74-d9d8-449a-88bd-7bd59b4c2751.jpeg</url>
      <title>Forem: Danny Engelman</title>
      <link>https://forem.com/dannyengelman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dannyengelman"/>
    <language>en</language>
    <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://forem.com/dannyengelman/web-components-without-javascript-ka4</link>
      <guid>https://forem.com/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"&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"&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%2Cformat=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%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffjxkhy3ktvcx3a5kjxgd.webp" alt="DIV soup"&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"&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://forem.com/dannyengelman/using-html-to-its-full-extend-24e</link>
      <guid>https://forem.com/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://forem.com/dannyengelman/web-components-the-untold-story-417i</link>
      <guid>https://forem.com/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;/blockquote&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;h3&gt;
  
  
  2011: Alex Russell’s Amsterdam Lightbulb Moment
&lt;/h3&gt;

&lt;p&gt;At a crisp autumn conference in Amsterdam (often cited as late 2011), Google’s 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;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;NO!! JavaScript required to get the semantic and style benefits of “components.”&lt;/strong&gt;&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;

</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://forem.com/dannyengelman/your-first-web-component-without-javascript-3m7d</link>
      <guid>https://forem.com/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://forem.com/dannyengelman/not-a-div-insidein-sightsite-18lj</link>
      <guid>https://forem.com/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"&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"&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;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%2Cformat=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%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffjxkhy3ktvcx3a5kjxgd.webp" alt="DIV soup"&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"&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://forem.com/dannyengelman/ai-beaten-by-a-web-component-2791</link>
      <guid>https://forem.com/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://forem.com/dannyengelman/web-component-j9p</link>
      <guid>https://forem.com/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://forem.com/dannyengelman/my-1-year-old-gpt-web-component-creator-is-free-source-now-45pf</link>
      <guid>https://forem.com/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://forem.com/dannyengelman/nth-child-builder-in-a-web-component-3bh2</link>
      <guid>https://forem.com/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://forem.com/dannyengelman/show-favicon-over-a-href-link-with-a-web-component-114d</link>
      <guid>https://forem.com/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://forem.com/dannyengelman/web-components-make-it-so-30gk</link>
      <guid>https://forem.com/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 width="710" height="399" src="https://www.youtube.com/embed/xteKObnaA2c"&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>
    <item>
      <title>Rich Harris Web Component Identity Crisis</title>
      <dc:creator>Danny Engelman</dc:creator>
      <pubDate>Thu, 10 Oct 2024 12:08:37 +0000</pubDate>
      <link>https://forem.com/dannyengelman/rich-harris-web-component-identity-crisis-1bdh</link>
      <guid>https://forem.com/dannyengelman/rich-harris-web-component-identity-crisis-1bdh</guid>
      <description>&lt;p&gt;Rich Harris (Svelte) is really giving Web Components some attention now. &lt;/p&gt;

&lt;p&gt;His latest crusade against Web Components is basically a rant &lt;strong&gt;against&lt;/strong&gt; the &lt;strong&gt;standard&lt;/strong&gt; behavior of the &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; tag (available since &lt;strong&gt;2015&lt;/strong&gt;, yes 15)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://x.com/Rich_Harris/status/1844134732306792631" rel="noopener noreferrer"&gt;https://x.com/Rich_Harris/status/1844134732306792631&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Frvckyepnchcus6bh82su.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Frvckyepnchcus6bh82su.png" width="590" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And when people try to explain to him this just is what the &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; does, he continues:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fsm985en4j5fk9n7w7q3z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fsm985en4j5fk9n7w7q3z.png" width="598" height="653"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;h1&gt;
  
  
  Use the standard any way you want
&lt;/h1&gt;

&lt;p&gt;Like it or not this &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; has been around  since &lt;strong&gt;2015&lt;/strong&gt;, and will be around for a long time.&lt;/p&gt;

&lt;p&gt;I say, learn what it does, and doesn't, and use what is useful to you&lt;/p&gt;

&lt;p&gt;I extended Rich his complaint into a playground to play with.&lt;/p&gt;

&lt;p&gt;Here are two examples using both a &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; and a regular &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media.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%2Flh6lj00c88e85jdf0aub.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Flh6lj00c88e85jdf0aub.png" width="544" height="84"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The whole point of a &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; is to be &lt;strong&gt;different&lt;/strong&gt;, as it was for the &lt;strong&gt;past 9 years&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
If you don't want its behavior, use a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note how this blogpost was &lt;strong&gt;not&lt;/strong&gt; about &lt;em&gt;Custom Elements&lt;/em&gt; or &lt;em&gt;shadowDOM&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;PS: &lt;a class="mentioned-user" href="https://dev.to/rich"&gt;@rich&lt;/a&gt;, calm down, this is not good for your health&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F5qc1ycax36w04xxqb0zm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F5qc1ycax36w04xxqb0zm.png" width="752" height="619"&gt;&lt;/a&gt;&lt;/p&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>template</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
