<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rob Dodson</title>
    <description>The latest articles on DEV Community by Rob Dodson (@robdodson).</description>
    <link>https://dev.to/robdodson</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%2F73447%2F2be13838-9513-40c2-bd4d-82d7d43ae4b9.jpeg</url>
      <title>DEV Community: Rob Dodson</title>
      <link>https://dev.to/robdodson</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/robdodson"/>
    <language>en</language>
    <item>
      <title>Which elements support shadow DOM?</title>
      <dc:creator>Rob Dodson</dc:creator>
      <pubDate>Sun, 13 Jan 2019 16:56:36 +0000</pubDate>
      <link>https://dev.to/chromiumdev/which-elements-support-shadow-dom-lm9</link>
      <guid>https://dev.to/chromiumdev/which-elements-support-shadow-dom-lm9</guid>
      <description>

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RmJRsPhc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/146bzbec2vu47jvvtf92.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RmJRsPhc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/146bzbec2vu47jvvtf92.jpeg" alt="A dark building with several windows"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/Oliver41618769/status/1084275850441355265"&gt;Oliver on twitter asked&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is there a list somewhere of which HTML elements can and can’t have a shadow DOM?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As it turns out, there is! (Big thanks to &lt;a href="https://annevankesteren.nl/"&gt;Anne van Kesteren&lt;/a&gt; for &lt;a href="https://twitter.com/annevk/status/1084426928965238787?s=19"&gt;showing us the way&lt;/a&gt;).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If&lt;/em&gt; &lt;a href="https://dom.spec.whatwg.org/#context-object"&gt;&lt;em&gt;context object&lt;/em&gt;&lt;/a&gt;&lt;em&gt;’s&lt;/em&gt; &lt;a href="https://dom.spec.whatwg.org/#concept-element-local-name"&gt;&lt;em&gt;local name&lt;/em&gt;&lt;/a&gt; &lt;em&gt;is&lt;/em&gt; not &lt;em&gt;a&lt;/em&gt; &lt;a href="https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name"&gt;&lt;em&gt;valid custom element name&lt;/em&gt;&lt;/a&gt;&lt;em&gt;,&lt;/em&gt; &lt;em&gt;article,&lt;/em&gt; &lt;em&gt;aside,&lt;/em&gt; &lt;em&gt;blockquote,&lt;/em&gt; &lt;em&gt;body,&lt;/em&gt; &lt;em&gt;div,&lt;/em&gt; &lt;em&gt;footer,&lt;/em&gt; &lt;em&gt;h1,&lt;/em&gt; &lt;em&gt;h2,&lt;/em&gt; &lt;em&gt;h3,&lt;/em&gt; &lt;em&gt;h4,&lt;/em&gt; &lt;em&gt;h5,&lt;/em&gt; &lt;em&gt;h6,&lt;/em&gt; &lt;em&gt;header,&lt;/em&gt; &lt;em&gt;main,&lt;/em&gt; &lt;em&gt;nav,&lt;/em&gt; &lt;em&gt;p,&lt;/em&gt; &lt;em&gt;section, or&lt;/em&gt; &lt;em&gt;span, then&lt;/em&gt; &lt;a href="https://heycam.github.io/webidl/#dfn-throw"&gt;&lt;em&gt;throw&lt;/em&gt;&lt;/a&gt; &lt;em&gt;a&lt;/em&gt; &lt;em&gt;NotSupportedError&lt;/em&gt; &lt;em&gt;DOMException.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here’s a quick example using div:&lt;/p&gt;


&lt;div class="glitch-embed-wrap"&gt; &lt;iframe src="https://glitch.com/embed/#!/embed/shadow-dom-elements?path=script.js" alt="shadow-dom-elements on glitch"&gt;&lt;/iframe&gt; &lt;/div&gt;

&lt;h3&gt;
  
  
  Exceptions
&lt;/h3&gt;

&lt;p&gt;It’s worth calling out that button, input, select, img, and a are not on this list and will throw an error if you try to attach a shadow root to them. If you need to use them you'll probably need to look into either wrapping these elements or using &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#High-level_view"&gt;a type extension&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://robdodson.me/which-elements-support-shadow-dom/"&gt;&lt;em&gt;robdodson.me&lt;/em&gt;&lt;/a&gt; &lt;em&gt;on January 13, 2019.&lt;/em&gt;&lt;/p&gt;


</description>
      <category>webdev</category>
      <category>webcomponents</category>
      <category>shadowdom</category>
    </item>
    <item>
      <title>Managing focus for accessibility</title>
      <dc:creator>Rob Dodson</dc:creator>
      <pubDate>Tue, 22 May 2018 02:19:26 +0000</pubDate>
      <link>https://dev.to/robdodson/managing-focus-64l</link>
      <guid>https://dev.to/robdodson/managing-focus-64l</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;If I'm building a single page web app, what should happen to &lt;code&gt;focus&lt;/code&gt; when the user clicks some navigation?&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;This is a video I shot a while back, but the question comes up so often I wanted to re-share here on dev.to—plus it's a good excuse to write my first post 😁&lt;/p&gt;

&lt;p&gt;Typically in a single page app you'll have a structure that looks &lt;em&gt;roughly&lt;/em&gt; 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;nav&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/cart"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Shopping Cart&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/settings"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Settings&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- some content --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because it's a single page app, clicking on a link won't do a hard refresh. Instead, it will trigger a route change which usually uses a bit of AJAX to fetch some more data and populate the &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt; content area.&lt;/p&gt;

&lt;p&gt;For a sighted user this is all good—but what if I'm a non-sighted user navigating with a screen reader? I may not know that the new content has been added to the page (maybe I was expecting a hard refresh) and there's no indication that I should navigate back to the &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt; area.&lt;/p&gt;

&lt;p&gt;One easy way to improve this experience is to find a good heading in the newly loaded content and direct &lt;code&gt;focus&lt;/code&gt; to it. The easiest way to pull this off is to give the heading a &lt;code&gt;tabindex&lt;/code&gt; of -1 and call its &lt;code&gt;focus()&lt;/code&gt; method.&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;main&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;tabindex=&lt;/span&gt;&lt;span class="s"&gt;"-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Welcome to your shopping cart&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="c1"&gt;// Assuming this gets called every time new content loads...&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;onNewPage&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;heading&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;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;focus&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// You can also update the page title :)&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;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A screen reader will then announce the new heading, as well as the &lt;code&gt;main&lt;/code&gt; landmark area that it's contained within. Note that you probably don't want to do this focus management when a user first arrives at your site—you would only want to do it for subsequent navigation, like when they click a link. &lt;/p&gt;

&lt;p&gt;Hope you enjoyed this post! It's an easy trick that could make a big difference for some of your users. And if you're interested in more a11y screencasts check out &lt;a href="https://www.youtube.com/playlist?list=PLNYkxOF6rcICWx0C9LVWWVqvHlYJyqw7g"&gt;my playlist over on the YouTubes&lt;/a&gt; 📺&lt;/p&gt;

&lt;p&gt;✌️&lt;/p&gt;

</description>
      <category>a11y</category>
    </item>
  </channel>
</rss>
