<?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: Alan Dávalos</title>
    <description>The latest articles on Forem by Alan Dávalos (@alangdm).</description>
    <link>https://forem.com/alangdm</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%2F91771%2Ffa392b61-cc0d-44d0-a823-a11b071daab5.jpeg</url>
      <title>Forem: Alan Dávalos</title>
      <link>https://forem.com/alangdm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/alangdm"/>
    <language>en</language>
    <item>
      <title>Explaining the new internationalization features in Safari 15.4</title>
      <dc:creator>Alan Dávalos</dc:creator>
      <pubDate>Fri, 18 Mar 2022 09:05:36 +0000</pubDate>
      <link>https://forem.com/alangdm/explaining-the-new-internationalization-features-in-safari-154-7li</link>
      <guid>https://forem.com/alangdm/explaining-the-new-internationalization-features-in-safari-154-7li</guid>
      <description>&lt;p&gt;&lt;a href="https://webkit.org/blog/12445/new-webkit-features-in-safari-15-4/"&gt;Safari 15.4 released recently&lt;/a&gt; and among many things it includes a few new internationalization features. And while the blog post does explain which ones they are, it doesn't really mention what they do. So, I'll give you a brief summary for all of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;Intl.Locale&lt;/code&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;calendars/collations/hourCycles/numberingSystems/timeZones&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;All of these properties will return an array of the things the locale supports. Here are some examples of what each one will return so that you can get an idea of what they're used for.&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="c1"&gt;// calendars for Japanese (Japan) will return the Gregorian calendar and the Japanese calendar&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Locale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ja-JP&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;calendars&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ['gregory', 'japanese']&lt;/span&gt;

&lt;span class="c1"&gt;// collations A.K.A. ordering rules for Spanish (Mexico) will return traditional style ordering, European ordering rules, and emoji&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Locale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;es-MX&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;collations&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ['trad', 'emoji', 'eor']&lt;/span&gt;

&lt;span class="c1"&gt;// hourCycles for Traditional Chinese (China) will be a 23 hour cycle&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Locale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zh-Hant-CN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;hourCycles&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ['h23']&lt;/span&gt;
&lt;span class="c1"&gt;// but for English (USA) it will be a 12 hour cycle&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Locale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;hourCycles&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ['h12']&lt;/span&gt;

&lt;span class="c1"&gt;// numberingSystems for Arabic (Bahrain) will return Arabic-Indic digits&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Locale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ar-BH&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;numberingSystems&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ['arab']&lt;/span&gt;
&lt;span class="c1"&gt;// but for Portuguese (Brazil) it will return Latin digits&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Locale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pr-BR&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;numberingSystems&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ['latn']&lt;/span&gt;

&lt;span class="c1"&gt;// timeZones for English (New Zealand) will return Auckland and Chatham&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Locale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-NZ&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;timeZones&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ['Pacific/Auckland', 'Pacific/Chatham']&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Previous versions of the spec supported the non-plural versions of each of these properties. However, they will be undefined unless they are set through the &lt;code&gt;options&lt;/code&gt; parameter of the &lt;code&gt;Locale&lt;/code&gt; constructor.&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="c1"&gt;// not setting with options&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Locale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ja-JP&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;calendar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Locale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ja-JP&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;calendars&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ['gregory', 'japanese']&lt;/span&gt;

&lt;span class="c1"&gt;// setting with options&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Locale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ja-JP&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;calendar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gregory&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;calendar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 'gregory'&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Locale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ja-JP&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;calendar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gregory&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;calendars&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ['gregory'] as the 'japanese' one will get removed due to the options&lt;/span&gt;

&lt;span class="c1"&gt;// you can also set other calendars not there by default on the locale so be careful&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Locale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ja-JP&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;calendar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;buddhist&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;calendar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 'buddhist'&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Locale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ja-JP&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;calendar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;buddhist&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;calendars&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ['buddhist']&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;textInfo&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;textInfo&lt;/code&gt; property currently contains an object with a single &lt;code&gt;direction&lt;/code&gt; property which serves to indicate whether the locale's text is written right-to-left or left-to-right.&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="c1"&gt;// Arabic&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Locale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textInfo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// { direction: 'rtl'}&lt;/span&gt;
&lt;span class="c1"&gt;// Spanish&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Locale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;es&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textInfo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// { direction: 'ltr'}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;weekInfo&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;weekInfo&lt;/code&gt; currently contains an object with various information regarding how weeks work on that region. It's especially useful when creating calendar UIs.&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="c1"&gt;// week info for the UK&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Locale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en-GB&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;weekInfo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;gb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstDay&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 1 - week starts on Monday&lt;/span&gt;
&lt;span class="nx"&gt;gb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;weekend&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// [6, 7] - weekend is Saturday and Sunday&lt;/span&gt;
&lt;span class="nx"&gt;gb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;minimalDays&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 4 - for a week to be shown as the first week of a month it needs to be at least 4 days long&lt;/span&gt;

&lt;span class="c1"&gt;// week info for Algeria&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dz&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Locale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ar-DZ&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;weekInfo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;dz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstDay&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 6 - week starts on Saturday&lt;/span&gt;
&lt;span class="nx"&gt;dz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;weekend&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// [5, 6] - weekend is Friday and Saturday&lt;/span&gt;
&lt;span class="nx"&gt;dz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;minimalDays&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 1 - for a week to be shown as the first week of a month it needs to be at least 1 days long&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Browser Support
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale#browser_compatibility"&gt;MDN&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All the above features are supported in the following browsers: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Safari: 15.4 - supported&lt;/li&gt;
&lt;li&gt;Chrome/Edge: 92* - supported (MDN says only with a flag but it worked in Edge 99 with no flags)&lt;/li&gt;
&lt;li&gt;Firefox: 99 - not supported&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Intl.DisplayNames
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;type: 'calendar'&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This type option will allow you to get the localized name for any of the supported calendar types.&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="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DisplayNames&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&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;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;calendar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gregory&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 'Gregorian Calendar'&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DisplayNames&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&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;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;calendar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;japanese&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 'Japanese Calendar'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;type: 'dateTimeField'&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;With this type option you can get localized strings for many different common words related to dates and time. Some examples include:&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="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DisplayNames&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&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;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dateTimeField&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;year&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 'year'&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DisplayNames&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&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;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dateTimeField&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;minute&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 'minute'                                               &lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DisplayNames&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&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;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dateTimeField&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;weekday&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 'day of the week'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;languageDisplay&lt;/code&gt; option
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;languageDisplay&lt;/code&gt; option is an option that can only be used for &lt;code&gt;type: 'language'&lt;/code&gt; that determines the format for the string representing the language. It can be either 'dialect' or 'standard'.&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="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DisplayNames&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&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;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;language&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;languageDisplay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dialect&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-AU&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Australian English&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DisplayNames&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&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;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;language&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;languageDisplay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;standard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-AU&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// English (Australia)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Browser Support
&lt;/h3&gt;

&lt;p&gt;No &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames"&gt;MDN&lt;/a&gt; data for these features specifically, but I tested them in the following browsers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Safari: 15.4 - supported&lt;/li&gt;
&lt;li&gt;Chrome/Edge: 99 - supported&lt;/li&gt;
&lt;li&gt;Firefox: 99 developer edition - supported&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Intl.DateTimeFormat
&lt;/h2&gt;

&lt;h3&gt;
  
  
  New &lt;code&gt;timeZoneName&lt;/code&gt; types
&lt;/h3&gt;

&lt;p&gt;Four new types of &lt;code&gt;timeZoneName&lt;/code&gt; were added: 'shortOffset', 'longOffset', 'shortGeneric', and 'longGeneric'.&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;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UTC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&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;23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;738&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&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;timeZone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;JST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;timeZoneName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shortOffset&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// '12/20/2020, GMT+9'&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&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;timeZone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;JST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;timeZoneName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;longOffset&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// '12/20/2020, GMT+09:00'&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&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;timeZone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;JST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;timeZoneName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shortGeneric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// '12/20/2020, Japan Time'&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&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;timeZone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;JST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;timeZoneName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;longGeneric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// '12/20/2020, Japan Standard Time'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Browser Support
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat#browser_compatibility"&gt;MDN&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Safari: 15.4 - supported&lt;/li&gt;
&lt;li&gt;Chrome/Edge: 99* - supported (MDN doesn't list this as supported but it worked in my tests. It might work in earlier versions. &lt;a href="https://github.com/mdn/browser-compat-data/issues/15396"&gt;MDN issue&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Firefox: 91 - supported&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Intl.NumberFormat / Intl.PluralRules
&lt;/h2&gt;

&lt;p&gt;Safari 15.4's release notes mention that it added support for &lt;code&gt;formatRange()&lt;/code&gt; and &lt;code&gt;formatRangeToParts()&lt;/code&gt; in &lt;code&gt;NumberFormat&lt;/code&gt; and for &lt;code&gt;selectRange()&lt;/code&gt; in &lt;code&gt;PluralRules&lt;/code&gt;. However, as the time of writing, those functions don't seem to be actually implemented in Safari 15.4 (Mac OS 10.15) nor have they been implemented in other browsers.&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="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NumberFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;de-DE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;formatRange&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NumberFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;de-DE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;formatRangeToParts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PluralRules&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;de-DE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;selectRange&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Hopefully this article helped you understand better what all these new features were about and whether you can actually begin using them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;Cover photo by &lt;a href="https://unsplash.com/@splashabout?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Nareeta Martin&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/international?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>i18n</category>
      <category>safari</category>
    </item>
    <item>
      <title>Where to begin building Web Components? - Class-based Libraries</title>
      <dc:creator>Alan Dávalos</dc:creator>
      <pubDate>Mon, 29 Jun 2020 09:08:49 +0000</pubDate>
      <link>https://forem.com/alangdm/where-to-begin-building-web-components-class-based-libraries-18m6</link>
      <guid>https://forem.com/alangdm/where-to-begin-building-web-components-class-based-libraries-18m6</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Welcome back to this series where I try to help you find which way of building Web Components best suits you!&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/alangdm/where-to-begin-building-web-components-the-basics-3b78"&gt;previous post&lt;/a&gt;, we covered the Web Components Standards and why you probably will want to use a library to help you build your Web Components at this point of time.&lt;/p&gt;

&lt;p&gt;In this article we'll be covering the first pattern commonly used by Web Components libraries, the class-based pattern.&lt;/p&gt;

&lt;p&gt;Just before we begin, I have one quick note regarding the "bundle" size data.&lt;/p&gt;

&lt;p&gt;I'll be using the fantastic &lt;a href="https://bundlephobia.com/"&gt;BundlePhobia&lt;/a&gt; as the source for the minified + gzip bundle size data of each library.&lt;/p&gt;

&lt;p&gt;However, depending on the approach each library follows, how much the library's bundle size affects your application's bundle when using multiple components based on that library may vary greatly.&lt;/p&gt;

&lt;p&gt;The folks at &lt;a href="https://webcomponents.dev/"&gt;WebComponents.dev&lt;/a&gt; did an &lt;a href="https://webcomponents.dev/blog/all-the-ways-to-make-a-web-component/"&gt;amazing breakdown on that kind of data&lt;/a&gt; so if you're interested in that kind of data go check them out. (You can also test out all the libraries covered in this article in their Web IDE.)&lt;/p&gt;

&lt;p&gt;Now without further ado.&lt;/p&gt;

&lt;h1&gt;
  
  
  What's the Class-based Pattern About?
&lt;/h1&gt;

&lt;p&gt;In the first article of this series, we mentioned that in order to create a Web Component you need to create a class that extends &lt;code&gt;HTMLElement&lt;/code&gt; and then register that class in the &lt;code&gt;CustomElementRegistry&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And of course, extending a class that extends &lt;code&gt;HTMLElement&lt;/code&gt; also counts.&lt;/p&gt;

&lt;p&gt;So what this type of libraries do is exactly that, they create a generic class that extends &lt;code&gt;HTMLElement&lt;/code&gt; and add a bunch of utility code that helps out make creating components easier.&lt;/p&gt;

&lt;p&gt;For example, the &lt;code&gt;SuperAwesomeElement&lt;/code&gt; class defined below could help making updating an element after one of it's attributes changed a lot easier than when manually extending &lt;code&gt;HTMLElement&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can see the code in action &lt;a href="https://glitch.com/~super-awesome-element"&gt;here&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;SuperAwesomeElement&lt;/span&gt; &lt;span class="kd"&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="kd"&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&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="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nx"&gt;attributes&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="p"&gt;{};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nx"&gt;observedAttributes&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="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&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;attributes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;attributeChangedCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;oldValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oldValue&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;newValue&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="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// it basically will just parse the attribute depending on the&lt;/span&gt;
    &lt;span class="c1"&gt;// type you define and set it to the components state property&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;type&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;attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/array|object/i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&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;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/number/i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&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;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;parseFloat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newValue&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;update&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;p&gt;And creating an actual component based on it would look like this:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SuperAwesomeElement&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;super-awesome-element&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;template&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
  &amp;lt;p&amp;gt;Text: &amp;lt;span class="text"&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;Number: &amp;lt;span class="int"&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;Object: &amp;lt;span class="obj"&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;Array: &amp;lt;span class="arr"&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;SuperAwesomeElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&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;int&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="na"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="na"&gt;arr&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shadowRoot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cloneNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_textNode&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;shadowRoot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.text&lt;/span&gt;&lt;span class="dl"&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;_intNode&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;shadowRoot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.int&lt;/span&gt;&lt;span class="dl"&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;_objNode&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;shadowRoot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.obj&lt;/span&gt;&lt;span class="dl"&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;_arrNode&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;shadowRoot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.arr&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="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nx"&gt;attributes&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="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;array&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="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;update&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;_textNode&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&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;_intNode&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;int&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;_objNode&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;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;obj&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;_arrNode&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;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arr&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="nx"&gt;customElements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;my-component&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Naturally, this is just a super simple example that's nowhere near production ready and actual class-based libraries do a lot more things for you.&lt;/p&gt;

&lt;p&gt;But even an example as simple as this reduces the amount of code you need to create a component quite a bit.&lt;/p&gt;

&lt;p&gt;Now imagine what a full-featured library can do for you. 💪&lt;/p&gt;

&lt;h1&gt;
  
  
  Pros and Cons
&lt;/h1&gt;

&lt;p&gt;Components written using this kind of libraries are by definition a lot closer to the standard, which in itself has some pros and cons:&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Easy migration&lt;/strong&gt;: if you ever need to migrate your components to vanilla or another class-based library the migration will be smoother than if you were using one of the other patterns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extensibility&lt;/strong&gt;: If you need extra common features for your components you can use mixins to add them to your components, and these mixins might actually work no matter which class-based library you end up using as they all extend HTMLElement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You learn to use the standards&lt;/strong&gt;: learning how to use one of this libraries will help you understand the standards better.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;More boilerplate code&lt;/strong&gt;: while extending a class-based library does drastically reduce the amount of code you need to write, classes in JS just generally require you to write slightly more boilerplate code than other approaches.

&lt;ul&gt;
&lt;li&gt;This is mostly evident while doing things like having side effects on property changes.&lt;/li&gt;
&lt;li&gt;Note that this doesn't mean the build size will be bigger, it's just about the code you actually write.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Libraries that Follow this Pattern
&lt;/h1&gt;

&lt;p&gt;Here's a list of some of the libraries that follow this pattern in alphabetical order:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Stars/Version/Size data was updated at the time of publishing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  CanJS
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://canjs.com/"&gt;Website&lt;/a&gt; | &lt;a href="https://github.com/canjs/canjs"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stars&lt;/th&gt;
&lt;th&gt;License&lt;/th&gt;
&lt;th&gt;Latest Version&lt;/th&gt;
&lt;th&gt;TS Support&lt;/th&gt;
&lt;th&gt;Bundle Size&lt;/th&gt;
&lt;th&gt;Templating&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1.8k+&lt;/td&gt;
&lt;td&gt;MIT&lt;/td&gt;
&lt;td&gt;1.1.2 (June 2020)&lt;/td&gt;
&lt;td&gt;Couldn't find&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bundlephobia.com/result?p=can-stache-element@1.1.2"&gt;66kB&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;can-stache (mustache-like syntax)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Fun Facts
&lt;/h4&gt;

&lt;p&gt;CanJS's size is actually quite big compared to pretty much every other library introduced throughout this series.&lt;/p&gt;

&lt;p&gt;But that's mostly because unlike the other libraries CanJS is more of a framework based on Web Components than a library to create Web Components.&lt;/p&gt;

&lt;p&gt;So if you build your whole app just around it, it might be worth it for you, but if you're just building a reusable components you're probably better off using other libraries.&lt;/p&gt;

&lt;h3&gt;
  
  
  HyperHTML Element
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/WebReflection/hyperHTML-Element"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stars&lt;/th&gt;
&lt;th&gt;License&lt;/th&gt;
&lt;th&gt;Latest Version&lt;/th&gt;
&lt;th&gt;TS Support&lt;/th&gt;
&lt;th&gt;Bundle Size&lt;/th&gt;
&lt;th&gt;Templating&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.1k+&lt;/td&gt;
&lt;td&gt;ISC&lt;/td&gt;
&lt;td&gt;3.12.3 (March 2020)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bundlephobia.com/result?p=hyperhtml-element@3.12.31"&gt;8.7kB&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;hyperHTML (JS Tagged Template Literals)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Fun Facts
&lt;/h4&gt;

&lt;p&gt;This library is mostly meant to be a helper to create Web Components rendered with hyperHTML.&lt;/p&gt;

&lt;p&gt;As a side node, hyperHTML might be one of the best rendering libraries in terms of performance. ⚡️&lt;/p&gt;

&lt;h3&gt;
  
  
  LitElement
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://lit-element.polymer-project.org/"&gt;Website&lt;/a&gt; | &lt;a href="https://github.com/Polymer/lit-element"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stars&lt;/th&gt;
&lt;th&gt;License&lt;/th&gt;
&lt;th&gt;Latest Version&lt;/th&gt;
&lt;th&gt;TS Support&lt;/th&gt;
&lt;th&gt;Bundle Size&lt;/th&gt;
&lt;th&gt;Templating&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;3.5k+&lt;/td&gt;
&lt;td&gt;BSD 3-Clause&lt;/td&gt;
&lt;td&gt;2.3.1 (March 2020)&lt;/td&gt;
&lt;td&gt;Yes, includes decorators&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bundlephobia.com/result?p=lit-element@2.3.1"&gt;7.1kB&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;lit-html (JS Tagged Template Literals)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Fun Facts
&lt;/h4&gt;

&lt;p&gt;LitElement being made by the Polymer Project team confuses many people since Polymer v3 still "exists".&lt;/p&gt;

&lt;p&gt;To put it simple LitElement is Polymer v4, except that since the approach to creating the components changed quite drastically (and got improved drastically too) they changed the name.&lt;/p&gt;

&lt;p&gt;So if you want to use a "Polymer" library just use LitElement. 😉&lt;/p&gt;

&lt;p&gt;LitElement's first production-ready release was actually v2.0.0 because the lit-element package was previously owned by other people and already had a v1.0.0 release.&lt;/p&gt;

&lt;p&gt;It's sister library, lit-html, has a lot of parallels with a library that was mentioned before, hyperHTML, including the part about being one of the best performing rendering libraries. ⚡️&lt;/p&gt;

&lt;h3&gt;
  
  
  Omi
&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://omijs.org/"&gt;Website&lt;/a&gt; | &lt;a href="https://github.com/Tencent/omi"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stars&lt;/th&gt;
&lt;th&gt;License&lt;/th&gt;
&lt;th&gt;Latest Version&lt;/th&gt;
&lt;th&gt;TS Support&lt;/th&gt;
&lt;th&gt;Bundle Size&lt;/th&gt;
&lt;th&gt;Templating&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;11.1k+&lt;/td&gt;
&lt;td&gt;MIT&lt;/td&gt;
&lt;td&gt;6.19.3 (May 2020)&lt;/td&gt;
&lt;td&gt;Yes, includes decorators&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bundlephobia.com/result?p=omi@6.19.3"&gt;8.3kB&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;JSX (Preact)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Fun Facts
&lt;/h4&gt;

&lt;p&gt;Omi is probably the only class-based library whose docs are on multiple languages by default.&lt;/p&gt;

&lt;p&gt;They seem to all have versions in English and Chinese and some even in Korean. 🇬🇧🇨🇳🇰🇷&lt;/p&gt;

&lt;h3&gt;
  
  
  SkateJS
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://skatejs.netlify.app/"&gt;Website&lt;/a&gt; | &lt;a href="https://github.com/skatejs/skatejs"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stars&lt;/th&gt;
&lt;th&gt;License&lt;/th&gt;
&lt;th&gt;Latest Version&lt;/th&gt;
&lt;th&gt;TS Support&lt;/th&gt;
&lt;th&gt;Bundle Size&lt;/th&gt;
&lt;th&gt;Templating&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;3.1k+&lt;/td&gt;
&lt;td&gt;MIT&lt;/td&gt;
&lt;td&gt;0.0.1 (December 2018)&lt;/td&gt;
&lt;td&gt;Couldn't find&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bundlephobia.com/result?p=@skatejs/element@0.0.1"&gt;1.8kB + render library&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;hyperHTML/lit-html (JS Tagged Template Literals), JSX&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Fun Facts
&lt;/h4&gt;

&lt;p&gt;SkateJS is actually a pretty unique library as it doesn't provide an "official" way of writing templates.&lt;/p&gt;

&lt;p&gt;Instead, it's designed to be used together with either a tagged template literal-based engine like hyperHTML or lit-html or a JSX engine like Preact or React.&lt;/p&gt;

&lt;p&gt;The only bad thing is that it seems like the SkateJS team is mostly focused on improving their SSR functionality right now so there haven't been any updates on the Web Component library itself for a while.&lt;/p&gt;

&lt;h3&gt;
  
  
  SlimJS
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://slimjs.com"&gt;Website&lt;/a&gt; | &lt;a href="https://github.com/slimjs/slim.js"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stars&lt;/th&gt;
&lt;th&gt;License&lt;/th&gt;
&lt;th&gt;Latest Version&lt;/th&gt;
&lt;th&gt;TS Support&lt;/th&gt;
&lt;th&gt;Bundle Size&lt;/th&gt;
&lt;th&gt;Templating&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.7k+&lt;/td&gt;
&lt;td&gt;MIT&lt;/td&gt;
&lt;td&gt;4.0.7 (April 2019)&lt;/td&gt;
&lt;td&gt;Yes, includes decorators&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bundlephobia.com/result?p=slim-js@4.0.7"&gt;3.3kB&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;own library (mustache-like)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Fun Facts
&lt;/h4&gt;

&lt;p&gt;As the name suggests, SlimJS is super slim, it's the smallest library on this article's list and it's one of the smallest I will cover throughout the series in general.&lt;/p&gt;

&lt;p&gt;Just one thing you might want to consider is that the project doesn't seem to have any updates for the past year or so. ☹️&lt;/p&gt;

&lt;h1&gt;
  
  
  What's Next?
&lt;/h1&gt;

&lt;p&gt;Now we have covered the class-based approach, how it works, why it can be good for you, and some of the libraries that use this approach.&lt;/p&gt;

&lt;p&gt;And maybe you already liked something here so much that you want to test it out ASAP, if you did, that's amazing! 🎉&lt;/p&gt;

&lt;p&gt;But don't worry if you haven't, we still have other patterns to cover with many more libraries representing them so stay tuned for the next entry on this series.&lt;/p&gt;

&lt;p&gt;Feel free to leave a comment with any corrections, questions, or suggestions you have for the rest of the series. Especially regarding the libraries and the data I showed on them as I'm not an expert on every single one of them so some of it might be slightly off.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>webcomponents</category>
      <category>javascript</category>
      <category>litelement</category>
    </item>
    <item>
      <title>Where to begin building Web Components? - The Basics</title>
      <dc:creator>Alan Dávalos</dc:creator>
      <pubDate>Thu, 14 May 2020 09:05:12 +0000</pubDate>
      <link>https://forem.com/alangdm/where-to-begin-building-web-components-the-basics-3b78</link>
      <guid>https://forem.com/alangdm/where-to-begin-building-web-components-the-basics-3b78</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;If you're reading this you've probably at least heard a bit about Web Components, a set of web standards that allow us to create our own reusable UI components that can be used in &lt;a href="https://custom-elements-everywhere.com/" rel="noopener noreferrer"&gt;any kind of web application&lt;/a&gt; and natively supported in all modern browsers.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1217578939456970754-490" src="https://platform.twitter.com/embed/Tweet.html?id=1217578939456970754"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1217578939456970754-490');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1217578939456970754&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;What you might not know is where to start, because if there's anything amazing yet terrible about the web development landscape is that where there's an API there will be a bazillion abstractions to "Make it Simpler™".&lt;/p&gt;

&lt;p&gt;And of course, Web Components are not the exception, last time I checked I could find around twenty-something different libraries that provide some sort of abstraction to help you create a Web Component.&lt;/p&gt;

&lt;p&gt;So, for anyone just trying to begin building Web Components just even finding out where to start is pretty difficult, which is why I'm here.&lt;/p&gt;

&lt;p&gt;Throughout this series of articles (yes, it's a series!), I'll cover the following points:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The basics of the Web Components standard: I'll be covering these in this article 😉&lt;/li&gt;
&lt;li&gt;The types of approaches different libraries take to help you be more efficient when creating Web Components: I'll cover each type in a separate article and try to give a brief introduction of most of the libraries I could find that follow each type&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Just bear in mind, this isn't a tutorial per se, I won't be explaining how to build Web Components with each library, I believe that's what the docs for each library are there for to begin with.&lt;/p&gt;

&lt;p&gt;The main purpose of this article is to try to help developers who are just starting with Web Components find a way of building Web Components that they feel comfortable with. 😊&lt;/p&gt;

&lt;p&gt;To quote &lt;a href="https://twitter.com/justinfagnani" rel="noopener noreferrer"&gt;Justin Fagnani&lt;/a&gt;, one of the members of the &lt;a href="https://www.polymer-project.org/" rel="noopener noreferrer"&gt;Polymer Project&lt;/a&gt; which greatly contributed in pushing the Web Components standard:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[...] the big idea with web components is that it shouldn't matter which or even if an approach (to create Web Components) becomes more popular. As long as components interoperate we all win.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, let's stop with the introduction and start with the juicy stuff.&lt;/p&gt;

&lt;h1&gt;
  
  
  What's actually needed to create a Web Component?
&lt;/h1&gt;

&lt;p&gt;To avoid repeating what many other articles have mentioned, I won't explain all the standards that make up Web Components, but if you need a reminder I recommend you to check this &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Web_Components" rel="noopener noreferrer"&gt;MDN article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, knowing what the standards are about is cool and all, but what does a vanilla Web Component actually look like?&lt;/p&gt;

&lt;p&gt;Here's some sample code for a simple Hello World component, don't worry if you don't fully understand what everything is, we'll go through it in more detail later on. 😉&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;template&lt;/span&gt; &lt;span class="o"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;template&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;div&amp;gt;Hello &amp;lt;span class="name"&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;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;MyGreeting&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;World&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Start - Standard Lifecycle Callbacks&lt;/span&gt;
  &lt;span class="c1"&gt;// This gets triggered when the component first is appended to the document&lt;/span&gt;
  &lt;span class="nf"&gt;connectedCallback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&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;shadowRoot&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="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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shadowRoot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cloneNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_nameSpan&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;shadowRoot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.name&lt;/span&gt;&lt;span class="dl"&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;_nameSpan&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// This defines which attributes will trigger a callback when they get set on the component&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nf"&gt;observedAttributes&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="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// This callback will get triggered when one of the observedAttributes gets changed&lt;/span&gt;
  &lt;span class="nf"&gt;attributeChangedCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;oldVal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newVal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oldVal&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;newVal&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;attr&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newVal&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="c1"&gt;// End - Standard Lifecycle Callbacks&lt;/span&gt;

  &lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&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="nf"&gt;safeSetAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &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;_nameSpan&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;_nameSpan&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;value&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;get&lt;/span&gt; &lt;span class="nf"&gt;name&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// a helper function to prevent an endless loop on attribute assignment&lt;/span&gt;
  &lt;span class="nf"&gt;safeSetAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &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="nf"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;value&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="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&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="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&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;my-greeting&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MyGreeting&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this simple code you can see all the Web Components standards in action:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We create a &lt;strong&gt;&lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt;&lt;/strong&gt; that will be used for our component.&lt;/li&gt;
&lt;li&gt;We create a &lt;strong&gt;class&lt;/strong&gt; that extends the native &lt;code&gt;HTMLElement&lt;/code&gt; class which will be registered in the window level &lt;code&gt;CustomElementRegistry&lt;/code&gt;. This will make all the &lt;code&gt;&amp;lt;my-greeting&amp;gt;&lt;/code&gt; tags rendered use our class to know what to render.&lt;/li&gt;
&lt;li&gt;Our class contains some of the &lt;strong&gt;custom elements lifecycle callbacks&lt;/strong&gt; which mostly help us to know when to setup, destroy, or update our component.&lt;/li&gt;
&lt;li&gt;We use the &lt;code&gt;attachShadowRoot&lt;/code&gt; function to &lt;strong&gt;create the Shadow DOM tree&lt;/strong&gt; for our component.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You might think that this code is slightly too cumbersome for what seems to be too little.&lt;/p&gt;

&lt;p&gt;And you're right in thinking that, the Web Components standards, at least in their current form, are low-level standards that require you to write code for things that are needed pretty much for all use cases.&lt;/p&gt;

&lt;h1&gt;
  
  
  Let's "Make it Simpler™"
&lt;/h1&gt;

&lt;p&gt;This is where the abstractions I mentioned before come in, all of them basically aim to solve the pain points of working with each standard by:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Providing a rendering engine that removes all manual DOM manipulation&lt;/li&gt;
&lt;li&gt;Either extend, wrap, or compile to a class that can be registered in the &lt;code&gt;CustomElementRegistry&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Extend the native lifecycle callbacks and sometimes add library-specific callbacks that can help with more use cases like state management and many others.&lt;/li&gt;
&lt;li&gt;Handle the creation of the Shadow DOM tree with fallbacks either to polyfills or no Shadow DOM at all.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All of these abstractions generally make the overall development experience way more pleasant than working with vanilla web components.&lt;/p&gt;

&lt;p&gt;And what's even better is that since most of the final heavy lifting is done by the actual standards the majority of the libraries covered throughout this series won't add even 10kB to your final bundle (after minify/gzip)! 💪&lt;/p&gt;

&lt;h1&gt;
  
  
  What's Next?
&lt;/h1&gt;

&lt;p&gt;So far, I (hopefully) helped you understand what it takes to create a Web Component and why you probably want to use a library to help you out having a nice experience while doing so.&lt;/p&gt;

&lt;p&gt;But let's not forget about the original objective, I'm supposed to be playing cupid here and match you with your perfect library. 💘&lt;/p&gt;

&lt;p&gt;And while I mentioned many abstractions the libraries provide over the standards, I believe the one that has the biggest effect on how you actually end up writing the code for your component is the way to define the "class" for your component.&lt;/p&gt;

&lt;p&gt;Like I mentioned above, most libraries fall into one of three patterns:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;They provide a class that extends &lt;code&gt;HTMLElement&lt;/code&gt; and adds the extra features onto it so that you extend that new class in your code.&lt;/li&gt;
&lt;li&gt;They provide a function that will create a class for your component with both the extra features and your component code when called.&lt;/li&gt;
&lt;li&gt;They provide tools that can be used to compile your code, usually written in a proprietary syntax, into a class for your component with both the extra features and your component called.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the following articles, I'll go into more detail about how each pattern works in detail and try to briefly introduce as many libraries as I can that fall into that pattern.&lt;/p&gt;

&lt;p&gt;Thank you very much for reading this article to the end, I hope you liked it and keep reading the other articles for this series.&lt;/p&gt;

&lt;p&gt;Feel free to leave a comment with any questions or suggestions you have for the rest of the series, especially on what kind of data you would like to hear about from the libraries I'll be introducing.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>webcomponents</category>
      <category>javascript</category>
    </item>
    <item>
      <title>The Quirks of Shadow DOM and How to Take Advantage of Them</title>
      <dc:creator>Alan Dávalos</dc:creator>
      <pubDate>Tue, 18 Feb 2020 04:31:26 +0000</pubDate>
      <link>https://forem.com/alangdm/the-quirks-of-shadow-dom-and-how-to-take-advantage-of-them-4cd1</link>
      <guid>https://forem.com/alangdm/the-quirks-of-shadow-dom-and-how-to-take-advantage-of-them-4cd1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Disclaimer:&lt;/p&gt;

&lt;p&gt;During this article I'll be referring to the "normal" DOM as "Light DOM" to make it clear when I'm talking about it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  What is Shadow DOM?
&lt;/h1&gt;

&lt;p&gt;While Shadow DOM is considered one of the core standards that make up Web Components it's&lt;br&gt;
actually been in the browsers for quite a while as native HTML Elements like &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt;&lt;br&gt;
use it, it just wasn't available for developers to use before it was incorporated in the Web Components standard.&lt;/p&gt;

&lt;p&gt;And now that Edge is based on Chromium all Web Component standards, including Shadow DOM, are available in all modern browsers!! 🎉&lt;/p&gt;

&lt;p&gt;The whole idea of Shadow DOM is that it allows us to create DOM trees that are isolated&lt;br&gt;
from the Light DOM but that can be appended to the Light DOM and be rendered together with it.&lt;/p&gt;

&lt;p&gt;I know that sounds slightly confusing so this image might help understand it better:&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%2Fi%2Fxuc3xnvlh76ur4024mxv.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%2Fi%2Fxuc3xnvlh76ur4024mxv.png" alt="Shadow DOM Visualization"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Source: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM" rel="noopener noreferrer"&gt;"Using Shadow DOM"&lt;/a&gt; by &lt;a href="https://wiki.developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM$history" rel="noopener noreferrer"&gt;Mozilla Contributors&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This isolation is the key feature of Shadow DOM and it solves a couple of problems no other approach can really solve:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Nodes inside Shadow DOM aren't accessible via things like &lt;code&gt;document.querySelector()&lt;/code&gt; so you can prevent unwanted changes from other scripts.&lt;/li&gt;
&lt;li&gt;All CSS in Shadow DOM is scoped to it which has a couple of great benefits:

&lt;ol&gt;
&lt;li&gt;Styles in Shadow DOM don't leak out to Light DOM&lt;/li&gt;
&lt;li&gt;Styles in Light DOM don't bleed in to Shadow DOM*&lt;/li&gt;
&lt;li&gt;These two allow you to use super simple selectors like &lt;code&gt;button&lt;/code&gt; or &lt;code&gt;#someid&lt;/code&gt; without being afraid of anything, this is the biggest reason why we say that Shadow DOM fixes CSS, everything has it's own scope.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, you might have noticed that I put an asterisk when I mentioned that Light DOM styles don't bleed in to Shadow DOM.&lt;/p&gt;

&lt;p&gt;You see, having Shadow DOM have no way of being stylized from Light DOM would make it a bit too restrictive for many common use cases like theming and light customization.&lt;/p&gt;

&lt;p&gt;Which is why Shadow DOM contents can be stylized from Light DOM in certain cases.&lt;/p&gt;

&lt;p&gt;Like many CSS-related things, these are slightly difficult to understand just by reading them, so I'm going to take a Quiz-like approach for the rest of this article.&lt;/p&gt;
&lt;h1&gt;
  
  
  1 - How does inheritance work here?
&lt;/h1&gt;

&lt;p&gt;This is the markup for our first Shadow DOM:&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;style&amp;gt;&lt;/span&gt;
  &lt;span class="nc"&gt;.some-class&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;14px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
  This is some text
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&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;"some-class"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  And here's some more text
&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;And this is the Light DOM&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;style&amp;gt;&lt;/span&gt;
  &lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Helvetica&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;green&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="nc"&gt;.some-class&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&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;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!--
  The Shadow DOM from the previous snippet is
  in this web component
  --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;question-one&amp;gt;&amp;lt;/question-one&amp;gt;&lt;/span&gt;
&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;How do you think this will render? Try not to spoil yourself 😉.&lt;/p&gt;
&lt;h1&gt;
  
  
  Answer
&lt;/h1&gt;


&lt;div class="glitch-embed-wrap"&gt;
  &lt;iframe src="https://glitch.com/embed/#!/embed/shadow-dom-quiz?previewSize=100&amp;amp;path=question-one.html" alt="shadow-dom-quiz on glitch"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;h1&gt;
  
  
  Why?
&lt;/h1&gt;

&lt;p&gt;Nodes inside Shadow DOM by default have no special styles, so properties that inherit such as&lt;br&gt;
&lt;code&gt;font-family&lt;/code&gt; or &lt;code&gt;color&lt;/code&gt; will inherit their values from the Shadow DOM's ancestors.&lt;/p&gt;

&lt;p&gt;Now, as you can see, in &lt;code&gt;some-class&lt;/code&gt; we're actually defining &lt;code&gt;font-family&lt;/code&gt;, &lt;code&gt;font-size&lt;/code&gt;, and &lt;code&gt;color&lt;/code&gt; so that part doesn't inherit styles.&lt;/p&gt;

&lt;p&gt;Bonus points if you noticed that the &lt;code&gt;.container .some-class&lt;/code&gt; selector in the Light DOM is basically useless as it's trying to affect nodes inside the Shadow DOM directly which isn't allowed.&lt;/p&gt;
&lt;h1&gt;
  
  
  2 - Can you style the host?
&lt;/h1&gt;

&lt;p&gt;Here's the Shadow DOM:&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;style&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;/*
  This selector basically applies to the root
  of our shadow DOM
  */&lt;/span&gt;
  &lt;span class="nd"&gt;:host&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;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30px&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;dotted&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;2&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;3&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;And here's the Light DOM:&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;style&amp;gt;&lt;/span&gt;
  &lt;span class="nc"&gt;.some-class&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="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;flex-flow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row-reverse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&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="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;question-two&amp;gt;&amp;lt;/question-two&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;question-two&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"some-class"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/question-two&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;Once again, how do you think this will render? Ready?&lt;/p&gt;
&lt;h1&gt;
  
  
  Answer
&lt;/h1&gt;


&lt;div class="glitch-embed-wrap"&gt;
  &lt;iframe src="https://glitch.com/embed/#!/embed/shadow-dom-quiz?previewSize=100&amp;amp;path=question-two.html" alt="shadow-dom-quiz on glitch"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;h1&gt;
  
  
  Why?
&lt;/h1&gt;

&lt;p&gt;Unlike styles applied to the children nodes, host-level styles in Shadow DOM can be overridden from Light DOM.&lt;/p&gt;

&lt;p&gt;Basically, anything that you define for the host directly is no more than a default style so if you really want to enforce a certain style you probably want to add a container node as a children and style that instead.&lt;/p&gt;

&lt;h1&gt;
  
  
  3 - Are CSS variables applied?
&lt;/h1&gt;

&lt;p&gt;Once more, here's the Shadow DOM:&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;style&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--my-color&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
  Some text
&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;And here's the Light DOM:&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;style&amp;gt;&lt;/span&gt;
  &lt;span class="nc"&gt;.custom-color&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;--my-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;question-three&amp;gt;&amp;lt;/question-three&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;question-three&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"custom-color"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/question-three&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;What will happen with the color on this one?&lt;/p&gt;
&lt;h1&gt;
  
  
  Answer
&lt;/h1&gt;


&lt;div class="glitch-embed-wrap"&gt;
  &lt;iframe src="https://glitch.com/embed/#!/embed/shadow-dom-quiz?previewSize=100&amp;amp;path=question-three.html" alt="shadow-dom-quiz on glitch"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;h1&gt;
  
  
  Why?
&lt;/h1&gt;

&lt;p&gt;CSS Custom Properties (or CSS Variables as most people call them) are one of the few things that can freely style nodes inside a Shadow DOM.&lt;/p&gt;

&lt;p&gt;Of course, like on this example, the style used in the Shadow DOM must define which variables it wants to use and where, but this is an easy way of providing customization on key points.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For more information on CSS Variables &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties" rel="noopener noreferrer"&gt;this article&lt;/a&gt; should help as a starting point.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  4 - What happens to the children nodes?
&lt;/h1&gt;

&lt;p&gt;Ready for one more question? Here's the Shadow DOM:&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;style&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;/*
  the ::slotted(selector) selector applies to
  any nodes appended in the indicated slot
  that match the given selector
  */&lt;/span&gt;
  &lt;span class="nt"&gt;header&lt;/span&gt; &lt;span class="nd"&gt;::slotted&lt;/span&gt;&lt;span class="o"&gt;(*)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;text-decoration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;underline&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;article&lt;/span&gt; &lt;span class="nd"&gt;::slotted&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="nc"&gt;.special&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;turquoise&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;section&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;header&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&amp;lt;slot&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Default Header&lt;span class="nt"&gt;&amp;lt;/slot&amp;gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;slot&amp;gt;&amp;lt;/slot&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;And here's the Light DOM:&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;style&amp;gt;&lt;/span&gt;
  &lt;span class="nc"&gt;.some-class&lt;/span&gt; &lt;span class="nc"&gt;.header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.some-class&lt;/span&gt; &lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;mediumvioletred&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;question-four&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&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;"special"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;2&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;3&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/question-four&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;question-four&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"some-class"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;4&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&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;"special"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;5&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;6&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"header"&lt;/span&gt; &lt;span class="na"&gt;slot=&lt;/span&gt;&lt;span class="s"&gt;"header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Second Element Header
  &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/question-four&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;This one had a bit more things to figure out so take your time, how do you think it will render?&lt;/p&gt;
&lt;h1&gt;
  
  
  Answer
&lt;/h1&gt;


&lt;div class="glitch-embed-wrap"&gt;
  &lt;iframe src="https://glitch.com/embed/#!/embed/shadow-dom-quiz?previewSize=100&amp;amp;path=question-four.html" alt="shadow-dom-quiz on glitch"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;h1&gt;
  
  
  Why?
&lt;/h1&gt;

&lt;p&gt;If this is your first time reading about Shadow DOM I won't blame you if you didn't get this one, but bear with me, I'll do my best to explain this.&lt;/p&gt;

&lt;p&gt;You see, in Shadow DOM there's a special &lt;code&gt;&amp;lt;slot&amp;gt;&lt;/code&gt; tag that serves to basically say what part of the template this element's children will be appended to.&lt;/p&gt;

&lt;p&gt;If you've used &lt;code&gt;children&lt;/code&gt; in React or slots in Vue you probably are familiar with the concept (Vue's slots are based on this standard).&lt;/p&gt;

&lt;p&gt;Now, in styles defined in Shadow DOM we can try to apply styles to children appended through a slot using the &lt;code&gt;::slotted()&lt;/code&gt; selector.&lt;/p&gt;

&lt;p&gt;But as you can see, this works really similar to how host level styles behaved a couple questions ago. Styles applied with &lt;code&gt;::slotted()&lt;/code&gt; are also basically default styles that will merge with the styles coming from Light DOM but the Light DOM styles will have a higher priority.&lt;/p&gt;

&lt;h1&gt;
  
  
  5 - Can you style some parts only?
&lt;/h1&gt;

&lt;p&gt;The last question!! Are you ready? Here's the Shadow DOM:&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;style&amp;gt;&lt;/span&gt;
  &lt;span class="nd"&gt;:host&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="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;64px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;64px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;seagreen&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;part=&lt;/span&gt;&lt;span class="s"&gt;"avatar"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://via.placeholder.com/64x64.jpg?text=Avatar"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;part=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Some Name
&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;And here's the Light DOM:&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;style&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;question-five&lt;/span&gt;&lt;span class="nc"&gt;.custom-part&lt;/span&gt;&lt;span class="nd"&gt;::part&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;avatar&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nt"&gt;question-five&lt;/span&gt;&lt;span class="nc"&gt;.custom-part&lt;/span&gt;&lt;span class="nd"&gt;::part&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Verdana&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;mediumpurple&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;question-five&amp;gt;&amp;lt;/question-five&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;question-five&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"custom-part"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/question-five&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;For the last time, how will this part stuff render?&lt;/p&gt;
&lt;h1&gt;
  
  
  Answer 5
&lt;/h1&gt;


&lt;div class="glitch-embed-wrap"&gt;
  &lt;iframe src="https://glitch.com/embed/#!/embed/shadow-dom-quiz?previewSize=100&amp;amp;path=question-five.html" alt="shadow-dom-quiz on glitch"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;h1&gt;
  
  
  Why?
&lt;/h1&gt;

&lt;p&gt;Now we're entering into cutting edge grounds, unlike the content for all the four previous questions which are all available in all modern browsers, this last one is not yet available in Safari (it's probably coming soon-ish as it's on the Technology Preview and in my tests it worked just fine), but it's available on all Chromium-based browsers (Chrome, Edge, Opera, etc.) and Firefox.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Update: As of October 2020, Safari has implemented this standard so now it works on all modern browsers!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For this demo we use the Shadow Parts Standard, and as the name suggests, it let's us declare "parts" inside our Shadow DOM that can then be styled from Light DOM using the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/::part" rel="noopener noreferrer"&gt;&lt;code&gt;::part()&lt;/code&gt; pseudo element&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As you can probably tell by now, Shadow Parts work similarly to how slots and host level styles work so the properties set using &lt;code&gt;::part()&lt;/code&gt; on the Light DOM styles will take top priority and styles set on the Shadow DOM will work as fallbacks.&lt;/p&gt;

&lt;h1&gt;
  
  
  To Close
&lt;/h1&gt;

&lt;p&gt;Shadow DOM is a really powerful part of the Web Standard but it definitely has some quirks that aren't that evident at first glance.&lt;/p&gt;

&lt;p&gt;I hope this little quiz helped you understand a bit better how Shadow DOM works and how you can make the most of it both when using and when creating your own Web Components (or even if you just use Shadow DOM by itself).&lt;/p&gt;

&lt;h1&gt;
  
  
  More Info
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://developers.google.com/web/fundamentals/web-components/shadowdom" rel="noopener noreferrer"&gt;https://developers.google.com/web/fundamentals/web-components/shadowdom&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>webcomponents</category>
      <category>shadowdom</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Sometimes Chrome is the problem</title>
      <dc:creator>Alan Dávalos</dc:creator>
      <pubDate>Thu, 16 Jan 2020 01:34:02 +0000</pubDate>
      <link>https://forem.com/alangdm/sometimes-chrome-is-the-problem-2dog</link>
      <guid>https://forem.com/alangdm/sometimes-chrome-is-the-problem-2dog</guid>
      <description>&lt;p&gt;Anyone who has been doing web development over the last decade or so has probably faced a situation like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I want to use this shiny new JS API/CSS feature, it looks cool!&lt;/p&gt;

&lt;p&gt;Wow, I tested it on Chrome and it looks great!&lt;/p&gt;

&lt;p&gt;Now I'll test it on the other browsers... And it doesn't work 😢&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I know I've been there, and you probably have too, in fact, these kind of browser compatibility problems are so common amongst web developers that they were ranked as the top frustration web developers and designers face in the recent &lt;a href="https://insights.developer.mozilla.org/" rel="noopener noreferrer"&gt;&lt;em&gt;Web DNA Report 2019&lt;/em&gt; by Mozilla&lt;/a&gt;. No matter the region, gender, years of experience, or anything else, it's just the top pain point of the current web ecosystem apparently.&lt;/p&gt;

&lt;p&gt;And, as of recent years, many times the Chromium team is the first one to implement the newest JS and CSS features and you end up having to drop a feature or include a polyfill due to other browsers not supporting it.&lt;/p&gt;

&lt;p&gt;However, as you can tell from the title of this article, that's not always the case, and I'm about to show you an example on how sometimes Chrome does work in weird ways.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Problem
&lt;/h1&gt;

&lt;p&gt;For a project I'm working on, the designers wanted to include a vertical progress bar divided in small segments with a gradient that went through all of them, basically something like this:&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fzcjtd9he4cydwrtwwa32.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fzcjtd9he4cydwrtwwa32.png" alt="Vertical Progress Bar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fortunately, they went for a different idea in the end, but when that was first proposed I was thinking on if there was a way to do this without relying on using images just with CSS.&lt;/p&gt;

&lt;p&gt;Eventually, I found out that by using a combination of &lt;code&gt;background-size: cover&lt;/code&gt;, &lt;code&gt;background-attachment: fixed&lt;/code&gt;, and &lt;code&gt;background-image: linear-gradient(params)&lt;/code&gt; in all of the colored segments I could achieve something really close to what I needed.&lt;/p&gt;

&lt;p&gt;I was really pleased, I started testing and ended up with the following code:&lt;/p&gt;


&lt;div class="glitch-embed-wrap"&gt;
  &lt;iframe src="https://glitch.com/embed/#!/embed/alangdm-chrome-problem?previewSize=100&amp;amp;path=index.html" alt="alangdm-chrome-problem on glitch"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;p&gt;And while testing this in the browsers I have access to I ended up with this sample&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcgqau0z9likebhldbyr0.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcgqau0z9likebhldbyr0.png" alt="Comparison Table"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Wait what!? 😵
&lt;/h1&gt;

&lt;p&gt;As you can see, for some reason only Chrome for Android can't display this as intended even when Chrome for Mac OS can.&lt;/p&gt;

&lt;p&gt;I found this really weird, I mean, for the most part Chrome for Android and Chrome for Desktop support the same features.&lt;/p&gt;

&lt;p&gt;The more I investigated the weirder it got, according to &lt;a href="https://caniuse.com/#feat=background-attachment" rel="noopener noreferrer"&gt;CanIUse&lt;/a&gt; Chrome for Android should display it properly while iOS Safari shouldn't, but the tests I did throw completely different results.&lt;/p&gt;

&lt;h1&gt;
  
  
  Finding the reason
&lt;/h1&gt;

&lt;p&gt;Then I stumbled upon this &lt;a href="https://stackoverflow.com/questions/23236158/how-to-replicate-background-attachment-fixed-on-ios" rel="noopener noreferrer"&gt;StackOverflow Question&lt;/a&gt;, according to the answer provided here, &lt;code&gt;background-attachment: fixed&lt;/code&gt; was actually supported for a while but ended up being dropped due to performance concerns.&lt;/p&gt;

&lt;p&gt;I can somewhat understand this, but it still baffled me that iOS Safari (iOS Chrome too since it's basically the same), Firefox for Android, and even IE11 support this while Chrome for Android doesn't.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusions
&lt;/h1&gt;

&lt;p&gt;In the end, I couldn't find another way to achieve this effect for all the browsers I was testing without including images or lots of JS code.&lt;/p&gt;

&lt;p&gt;Fortunately I didn't end up needing it, though, if you have other ideas please let me know, I'm curious.&lt;/p&gt;

&lt;p&gt;I just wanted to show that, while Chromium is an excellent browser engine and its team does some great work to try to advance what we can do in the web, in the end, they too can decide to just not support something that other browsers do.&lt;/p&gt;

&lt;p&gt;Of course, finding examples of this is much much rarer than say finding problems with IE, the old Edge, or Safari, but it still happens and I feel we should never forget about that.&lt;/p&gt;

&lt;p&gt;Feel free to post other similar examples in the comments, it's always good to know them.&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>todayilearned</category>
    </item>
    <item>
      <title>Differential Serving で必要なコードは2割以上削れる！</title>
      <dc:creator>Alan Dávalos</dc:creator>
      <pubDate>Wed, 18 Dec 2019 14:02:46 +0000</pubDate>
      <link>https://forem.com/alangdm/differential-serving-2-23eg</link>
      <guid>https://forem.com/alangdm/differential-serving-2-23eg</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Differential Serving と言う技術は実はもう２年ほど前から&lt;a href="https://philipwalton.com/articles/deploying-es2015-code-in-production-today/" rel="noopener noreferrer"&gt;Philip Walton さんの記事&lt;/a&gt;をきっかけに知る人ぞ知る JS のバンドルサイズを減らせるための技術なんですけど、検索しても、日本語でこのテーマについて話す記事はないので、とりあえずまとめ記事のつもりでこれを書きました、よろしくお願いします！&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  何のための技術ですか？
&lt;/h2&gt;

&lt;p&gt;今でも IE 11 のサポートを切れないアプリは多いと思います、そう言うアプリを作っている人はほとんど IE 11 を含めた全てのブラウザーにアプリがちゃんと起動できるように ES5 までにコードをコンパイルしていると思います。&lt;/p&gt;

&lt;p&gt;しかし、IE 11 のために追加する polyfills や ES5 でコードを書くとどうしても必要になって来る追加コードはビルドされたバンドルを重くします。&lt;/p&gt;

&lt;p&gt;どれぐらい重くなるかと言うのはコード次第ですが大体 20%から 30%までになります。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.smashingmagazine.com/2018/10/smart-bundling-legacy-code-browsers/" rel="noopener noreferrer"&gt;Shubham Kanodia さんがこの記事&lt;/a&gt;でいくつかのライブラリーをテストしました&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;しかも、ユーザー全体の&lt;a href="https://caniuse.com/#feat=es6-module" rel="noopener noreferrer"&gt;ほぼ 90%が&lt;/a&gt; ES Modules に対応しています!　つまり、10%のユーザーのために 90%のユーザーに送るコードの量が多くなっています。&lt;/p&gt;

&lt;p&gt;それでもその 10%のユーザーを切れないアプリは多いと思います、なんかこう都合良く ES Modules に対応しているユーザーだけにその小さめのコードを送れるためのフロントエンドコードはないのかな…&lt;/p&gt;

&lt;p&gt;実はあります、これからそれを紹介します。&lt;/p&gt;

&lt;h2&gt;
  
  
  もの凄く簡単に言うとこれです
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- 主にIE 11のためのJS --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;nomodule&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/app.legacy.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- 最新ブラウザーのためのJS --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/app.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;コンセプト的にはアプリのバンドルを二つ用意します。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;IE11 などの legacy ブラウザー用の ES5 にコンパイルされたバンドル。&lt;/li&gt;
&lt;li&gt;最新ブラウザー用の ES Modules にコンパイルされたバンドル。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;ここで重要なのは &lt;code&gt;nomodule&lt;/code&gt; と &lt;code&gt;type="module"&lt;/code&gt; です、これらを使ってユーザーのブラウザーにどのコードをロードするかの判断を任せます。&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;code&gt;nomodule&lt;/code&gt;と&lt;code&gt;type="module"&lt;/code&gt;って何ですか？　
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;nomodule&lt;/code&gt;は&lt;code&gt;script&lt;/code&gt;タグの属性で ES Modules に対応しているブラウザーにこのコードを無視するように示します。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;type="module"&lt;/code&gt;は逆にブラウザーにコードは ES Modules で書いてあることを示します。&lt;/p&gt;

&lt;p&gt;これらを合わせたサンプルはこれです。&lt;/p&gt;


&lt;div class="glitch-embed-wrap"&gt;
  &lt;iframe src="https://glitch.com/embed/#!/embed/differential-serving-sample?path=index.html" alt="differential-serving-sample on glitch"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;このコードを ES Modules に対応しているブラウザーで見るとこうなります。&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fdr7170403uk8p1f51yy7.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fdr7170403uk8p1f51yy7.png" alt="Modernブラウザーの例"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;見ての通り&lt;code&gt;type="module"&lt;/code&gt;になっているコードだけをダウンロードして実行します。&lt;/p&gt;

&lt;p&gt;そして、こちらのサンプルを IE 11 で見るとこうなります。&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fktdc26zg0cji2c2u7vwz.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fktdc26zg0cji2c2u7vwz.png" alt="Legacyブラウザーの例"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;見ての通り&lt;code&gt;nomodule&lt;/code&gt;になっているコードだけを実行するけど両方をダウンロードしていますね…&lt;/p&gt;

&lt;h2&gt;
  
  
  そこまで簡単には行かないんですよね
&lt;/h2&gt;

&lt;p&gt;先ほどの例もそうですけど、実は Safari 10 や Firefox 58 や IE 11 や Edge 15-18 などは両方のコードをダウンロードします。&lt;/p&gt;

&lt;p&gt;でもこれらはほとんど Wi-Fi でしか使わない PC ブラウザーだからそこまで問題にはならないと思われがちですがタチの悪いことに Safari 10 は両方をダウンロードするだけでなく両方を実行します…&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;John Stew さんは&lt;a href="https://github.com/johnstew/differential-serving" rel="noopener noreferrer"&gt;こちらでいくつかのテストを行ったので詳しくはこれを見てください&lt;/a&gt;。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Safari 10 のこの記事を書いている時点でのユーザーの割合は 1%以下ではありますができるだけ多くのユーザーに対応したいのでこれだけだとアウトなんですよね…&lt;/p&gt;

&lt;h2&gt;
  
  
  じゃもう手詰まり？
&lt;/h2&gt;

&lt;p&gt;実は上記のブラウザーの問題を解決できる方法はあります、しかも、それを都合良くまとめてくれる方法は色々な人気のツールにはすでに入っています。&lt;/p&gt;

&lt;h2&gt;
  
  
  ツールは何をしていますか？
&lt;/h2&gt;

&lt;p&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="c"&gt;&amp;lt;!-- これが実際にVue CLIを使うと出て来るコードとほぼ同じものです --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://example.com/app.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;check&lt;/span&gt; &lt;span class="o"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;script&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&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;noModule&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;onbeforeload&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;support&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&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;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;beforeload&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;support&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nomodule&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;support&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="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;.&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;.&lt;/span&gt;&lt;span class="dl"&gt;"&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="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&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="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script
  &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt;
  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://example.com/app.legacy.js"&lt;/span&gt;
  &lt;span class="na"&gt;nomodule&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;これは利用できる範囲の JS の feature の中で Safari 10 を見つけてその場合に module と nomodule の script が両方実行されないように働きかけます。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;詳しくは&lt;a href="https://gist.github.com/samthor/64b114e4a4f539915a95b91ffd340acc" rel="noopener noreferrer"&gt;こちらの gist&lt;/a&gt;を見てください。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;これはあくまで一つのやり方で、こちらではまだ legacy ブラウザーが両方ダウンロードすることになります、これから紹介するツールの中で、それすら解決するものもあるので、自分のプロジェクトに合うものもあると思います。&lt;/p&gt;
&lt;h3&gt;
  
  
  Vue CLI 3+の場合
&lt;/h3&gt;

&lt;p&gt;Vue CLI を使っているなら話はすごい簡単です、ビルド段階で&lt;a href="https://cli.vuejs.org/guide/browser-compatibility.html#modern-mode" rel="noopener noreferrer"&gt;フラグを一つ追加するだけで済みます&lt;/a&gt;。&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vue-cli-service build &lt;span class="nt"&gt;--modern&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  webpack の場合
&lt;/h3&gt;

&lt;p&gt;webpack を使っているならもう少し設定をいじる必要はあります。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;この 2 つのプラグインの内から 1 つをインストールします。

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/html-webpack-multi-build-plugin" rel="noopener noreferrer"&gt;html-webpack-multi-build-plugin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/webpack-module-nomodule-plugin" rel="noopener noreferrer"&gt;webpack-module-nomodule-plugin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;次に webpack で ES5 用の設定と ES Modules 用の設定を用意します。こちらの記事の「Generate two bundles」の部分にいい例があります。
&lt;div class="ltag__link"&gt;
  &lt;a href="/thejohnstew" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuser%2Fprofile_image%2F1202%2Fc8511bfb-23e7-4e1a-bfed-5b08053ca952.jpg" alt="thejohnstew"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/thejohnstew/differential-serving-3dkf" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Differential Serving&lt;/h2&gt;
      &lt;h3&gt;John Stewart ・ May 1 '19&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#performance&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;/li&gt;

&lt;li&gt;➁ でビルドしたバンドルを ➀ のプラグインに入れます&lt;/li&gt;

&lt;/ol&gt;

&lt;h3&gt;
  
  
  Rollup の場合
&lt;/h3&gt;

&lt;p&gt;Rollup では&lt;a href="https://www.npmjs.com/package/rollup-plugin-index-html" rel="noopener noreferrer"&gt;rollup-plugin-index-html&lt;/a&gt;を使えば簡単にできます。&lt;/p&gt;

&lt;p&gt;こちらは性能が良く、設定次第では両方がダウンロードされてしまう問題まで解決できるようになっています。&lt;/p&gt;

&lt;p&gt;使い方は先ほどの webpack の使い方に似ています。&lt;/p&gt;

&lt;p&gt;Web Components でプロジェクトを作っているなら、先ほどのプラグインを内部で使っている&lt;a href="https://open-wc.org/building/rollup-plugin-index-html.html#multi-legacy-and-modern-build" rel="noopener noreferrer"&gt;Open WC の設定&lt;/a&gt; がおすすめです。&lt;/p&gt;

&lt;p&gt;Web Components のプロジェクトでなくても上記の設定が参考になると思います。&lt;/p&gt;

&lt;h2&gt;
  
  
  最後に
&lt;/h2&gt;

&lt;p&gt;Differential Serving は個人的に誰もが知っておくべき技術だと思います、これを入れるとまだ legacy ブラウザーを使っているユーザーを犠牲にせず最新ブラウザーを使っているユーザーにもっといい体験をさせられます。いわゆる「Win Win」な話です。&lt;/p&gt;

&lt;h2&gt;
  
  
  もっと知りたい人には（全て英語の記事ですみません mm）
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://philipwalton.com/articles/deploying-es2015-code-in-production-today/" rel="noopener noreferrer"&gt;https://philipwalton.com/articles/deploying-es2015-code-in-production-today/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/johnstew/differential-serving" rel="noopener noreferrer"&gt;https://github.com/johnstew/differential-serving&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.smashingmagazine.com/2018/10/smart-bundling-legacy-code-browsers/" rel="noopener noreferrer"&gt;https://www.smashingmagazine.com/2018/10/smart-bundling-legacy-code-browsers/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://css-tricks.com/differential-serving/" rel="noopener noreferrer"&gt;https://css-tricks.com/differential-serving/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/thejohnstew/differential-serving-3dkf"&gt;https://dev.to/thejohnstew/differential-serving-3dkf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>japanese</category>
      <category>webperf</category>
    </item>
    <item>
      <title>How to use LitElement in a Vue CLI 3 project</title>
      <dc:creator>Alan Dávalos</dc:creator>
      <pubDate>Thu, 13 Jun 2019 13:18:38 +0000</pubDate>
      <link>https://forem.com/alangdm/how-to-use-litelement-in-a-vue-cli-3-project-164a</link>
      <guid>https://forem.com/alangdm/how-to-use-litelement-in-a-vue-cli-3-project-164a</guid>
      <description>&lt;p&gt;I'm a big fan of web components, I think they are awesome for many different reasons and they are basically what finally got me into liking web front-end development.&lt;/p&gt;

&lt;p&gt;However, I'm not here to start another post on how web components are or aren't good, how they will or won't substitute 'X' framework, or anything like that, plenty other people who know more about those topics than me have already discussed that deeply.&lt;/p&gt;

&lt;p&gt;I understand how frameworks can be great and how many people already use them successfully in production, but in my opinion the cool part about web components is that they &lt;a href="https://custom-elements-everywhere.com/"&gt;can be used in any framework&lt;/a&gt; or with no framework at all, and I'm here to show you a couple of ways a framework (in this case Vue) can coexist with web components (in this case based on LitElement).&lt;/p&gt;

&lt;h2&gt;
  
  
  Using web components installed from npm
&lt;/h2&gt;

&lt;p&gt;Web components installed from npm don't really need any extra configuration in Vue as long as you only need to support evergreen browsers, nice isn't it?&lt;/p&gt;

&lt;p&gt;Now, I know the world isn't all nice and not everyone uses the latest browsers so for info on how to configure the polyfills I would recommend you read &lt;a href="https://vaadin.com/tutorials/using-web-components-in-vue"&gt;this post from Vaadin&lt;/a&gt; (by the way, they have a great web components collection).&lt;/p&gt;

&lt;p&gt;The actual usage of the components in your Vue CLI 3 app would be something like this:&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;template&amp;gt;&lt;/span&gt;
  ...
  &lt;span class="nt"&gt;&amp;lt;awesome-component&lt;/span&gt; 
    &lt;span class="na"&gt;:attribute=&lt;/span&gt;&lt;span class="s"&gt;"attribute"&lt;/span&gt; 
    &lt;span class="na"&gt;:property-only.prop=&lt;/span&gt;&lt;span class="s"&gt;"property"&lt;/span&gt;
    &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;an-event=&lt;/span&gt;&lt;span class="s"&gt;"callback"&lt;/span&gt;
    &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"awesomeReference"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/awesome-component&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;script&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;awesome-component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{...};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating components based on LitElement in a Vue CLI 3 app
&lt;/h2&gt;

&lt;p&gt;I don't really know why you would actually want to do that to be honest but the cool thing is that you just can do it, all you need to do is to add the following to the &lt;code&gt;transpileDependencies&lt;/code&gt; property of your &lt;code&gt;vue.config.js&lt;/code&gt; after installing LitElement:&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;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;transpileDependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;/node_modules&lt;/span&gt;&lt;span class="se"&gt;(?:\/&lt;/span&gt;&lt;span class="sr"&gt;|&lt;/span&gt;&lt;span class="se"&gt;\\)&lt;/span&gt;&lt;span class="sr"&gt;lit-element|lit-html/&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 is to explicitly transpile LitElement and lit-html as they only provide es modules exports (for more information check the &lt;a href="https://cli.vuejs.org/config/#transpiledependencies"&gt;Vue CLI docs&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;And that's it, with that you can create LitElement components in your vue app to your heart's content (just remember, for the polyfills configuration check &lt;a href="https://vaadin.com/tutorials/using-web-components-in-vue"&gt;Vaadin's post out&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;On that, if you're using any other base class for web components, this configuration will also be useful, just change the &lt;code&gt;lit-element&lt;/code&gt; for your class of choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Sometimes as developers we can get so engrossed on proving our technology of choice is supreme that we may forget they can coexist with each other, this is just a reminder that there's no need to fight on whether web components are here to substitute frameworks or not, they're a standard web api that everyone can benefit from and I hope this post motivates more web developers to try them out.&lt;/p&gt;

&lt;p&gt;Thank you for reading, this is my first post here at dev so please be nice 😄&lt;/p&gt;

</description>
      <category>vue</category>
      <category>litelement</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
