<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Drbr's Dev Blog]]></title><description><![CDATA[Drbr's Dev Blog]]></description><link>https://drbr.dev</link><generator>RSS for Node</generator><lastBuildDate>Thu, 09 Apr 2026 14:11:34 GMT</lastBuildDate><atom:link href="https://drbr.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Drbr’s A11Y Resources]]></title><description><![CDATA[Accessibility == Usability. From MDN:

Accessibility is the practice of making your websites usable by as many people as possible. We traditionally think of this as being about people with disabilities, but the practice of making sites accessible als...]]></description><link>https://drbr.dev/drbrs-a11y-resources</link><guid isPermaLink="true">https://drbr.dev/drbrs-a11y-resources</guid><category><![CDATA[Accessibility]]></category><category><![CDATA[webdev]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[user experience]]></category><dc:creator><![CDATA[Andrew Brandon]]></dc:creator><pubDate>Wed, 31 Aug 2022 23:09:04 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/Zyx1bK9mqmA/upload/v1661987232084/hjbWbrXWr.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Accessibility == Usability. From <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/Accessibility/What_is_accessibility">MDN</a>:</p>
<blockquote>
<p>Accessibility is the practice of making your websites usable by as many people as possible. We traditionally think of this as being about people with disabilities, but the practice of making sites accessible also benefits other groups such as those using mobile devices, or those with slow network connections.</p>
</blockquote>
<p>Making an accessible website is not just checking requirements to comply to a standard, it’s a natural extension of UX design: we must design our software in a way that works for everyone.</p>
<p>Although official standards are well-documented, best-practice design patterns are much less standardized, hence many useful resources have been authored by individuals.</p>
<h1 id="heading-standards-specs">Standards / specs</h1>
<p>The <a target="_blank" href="https://www.w3.org/WAI/">W3C Web Accessibility Initiative (WAI)</a> is the de facto standards body for web accessibility. Their website contains loads of resources: tutorials, guides, articles, specs, and more about the how/what/why of accessibility.</p>
<ul>
<li><p><a target="_blank" href="https://www.w3.org/WAI/standards-guidelines/wcag/"><strong>Web Content Accessibility Guidelines</strong></a> <strong>(WCAG)</strong><br />  These are the criteria that accessible web apps are expected to meet.</p>
<ul>
<li><p><a target="_blank" href="https://www.w3.org/TR/WCAG22/"><strong>WCAG 2.2 Spec</strong></a></p>
</li>
<li><p><a target="_blank" href="https://www.w3.org/WAI/WCAG21/quickref/"><strong>WCAG Quick Reference</strong></a><br />  Condensed list of all criteria (filter by level A, AA, or AAA)</p>
</li>
</ul>
</li>
<li><p><a target="_blank" href="https://www.w3.org/WAI/standards-guidelines/aria/"><strong>Accessible Rich Internet Applications</strong></a> <strong>(WAI-ARIA)</strong><br />  A set of HTML roles and attributes to improve accessibility.</p>
<ul>
<li><p><a target="_blank" href="https://www.w3.org/TR/wai-aria-1.2/"><strong>WAI-ARIA 1.2 Spec</strong></a></p>
</li>
<li><p><a target="_blank" href="https://www.w3.org/WAI/ARIA/apg/"><strong>WAI-ARIA Authoring Practices Guide</strong></a> <strong>(APG)</strong><br />  Explains how to implement various components and design patterns, with reference implementations.</p>
<ul>
<li><a target="_blank" href="https://w3c.github.io/aria-practices/">ARIA APG raw text</a><br />  Same info as above but formatted as a single-page spec, rather than a multi-page website. This version is harder to read but easier to search through.</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><a target="_blank" href="https://www.webaccessibility.com/resource-library/platform/?platform=1"><strong>Web Accessibility best practices</strong></a> by Level Access<br />Checklist for an accessibility audit, which includes all WCAG 2.1 criteria.</p>
<h1 id="heading-general-guides-resources">General guides / resources</h1>
<ul>
<li><p><strong>MDN</strong> <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/Accessibility"><strong>Accessibility Reference</strong></a> <strong>and</strong> <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/Accessibility"><strong>Accessibility Guide</strong></a><br />  Comprehensive technical info about all the web technologies.</p>
</li>
<li><p><a target="_blank" href="https://web.dev/accessible/"><strong>Accessible to all</strong></a> <strong>by web.dev</strong></p>
</li>
<li><p><a target="_blank" href="https://www.microsoft.com/design/inclusive/"><strong>Microsoft Inclusive Design</strong></a><br />  Resources aimed at designers, with a lot of background and examples about how inclusive thinking benefits different people.</p>
</li>
<li><p><a target="_blank" href="https://www.a11yproject.com/">The a11y project</a><br />  An independent organization with lots of blog posts and other resources, aggregated from around the web. They also have an email newsletter, which is a good way to be fed a small amount of info on a regular basis</p>
</li>
<li><p><a target="_blank" href="https://a11y-style-guide.com/style-guide/"><strong>A11y Style Guide by Carie Fisher</strong></a><br />  Easy-to-read overview, with <em>lots</em> of resources linked.</p>
</li>
</ul>
<h1 id="heading-how-to-self-audit">How to self-audit</h1>
<p>Interacting with your application in different ways as you develop it will help uncover usability issues. Here are some easy checks that anyone can do without special training:</p>
<ul>
<li><p>Try using the site with only the keyboard. You should be able to access all the same information and perform the same actions that a mouse user can.</p>
</li>
<li><p>Inspect the semantics of the <a target="_blank" href="https://web.dev/the-accessibility-tree/">Accessibility Tree</a> (AT) in the <a target="_blank" href="https://developer.chrome.com/docs/devtools/accessibility/reference/">Chrome devtools</a>. Screen readers and other assistive technologies view the site via the information in the AT. The contents of this tree should make sense semantically.</p>
</li>
<li><p>Try navigating the site using a free screen reader (VoiceOver on Mac or NVDA on Windows). It should convey all the same information as what's on the screen.</p>
</li>
<li><p>Run an automated checker such as axe, which is available as a <a target="_blank" href="https://www.deque.com/axe/browser-extensions/">browser extension</a>, via the <a target="_blank" href="https://developer.chrome.com/docs/devtools/accessibility/reference/#audits">Lighthouse audit in the Chrome devtools</a>, or as an <a target="_blank" href="https://www.npmjs.com/package/axe-core">NPM package</a>.</p>
</li>
<li><p>Increase the text size to 200% using the browser's built-in zoom function. The layout should still be usable.</p>
</li>
</ul>
<p>The following articles explain these (and other easy checks) in more depth:</p>
<ul>
<li><p><a target="_blank" href="https://www.w3.org/WAI/test-evaluate/preliminary/">https://www.w3.org/WAI/test-evaluate/preliminary/</a></p>
</li>
<li><p><a target="_blank" href="https://web.dev/how-to-review/">https://web.dev/how-to-review/</a></p>
</li>
</ul>
<h1 id="heading-courses-trainings">Courses / Trainings</h1>
<ul>
<li><p><a target="_blank" href="https://web.dev/learn/accessibility/">Learn Accessibility</a> by web.dev (Google)<br />  20-chapter series of articles (a.k.a. "self-paced course"), written by Carie Fisher.</p>
</li>
<li><p><a target="_blank" href="https://www.udacity.com/course/web-accessibility--ud891">Web Accessibility</a> on Udacity (by Google)<br />  Free online course. Summarized in <a target="_blank" href="https://web.dev/accessibility/">this article</a>.</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/playlist?list=PLNYkxOF6rcICWx0C9LVWWVqvHlYJyqw7g">A11ycasts</a> by Rob Dodson<br />  30-part YouTube playlist. Most of the videos are between 5 and 15 minutes long.</p>
</li>
<li><p><a target="_blank" href="https://testingaccessibility.com/">Testing Accessibility</a> by Marcy Sutton<br />  Paid 6-part course on building accessible web apps through the entire lifecycle: design, build, test, ship.</p>
</li>
<li><p><a target="_blank" href="https://practical-accessibility.today/">Practical Accessibility</a> by Sara Soueidan<br />  Paid video course. Looks to be more focused on the technical nuts-and-bolts than Marcy Sutton's course.</p>
</li>
</ul>
<h1 id="heading-conferences-meetups">Conferences / Meetups</h1>
<ul>
<li><p><a target="_blank" href="https://a11ytalks.com/"><strong>A11y Talks</strong></a><br />  A “virtual meetup” consisting of over 60 recorded talks. Hard to browse via their site; easier via their <a target="_blank" href="https://www.youtube.com/c/AccessibilityTalks">YouTube channel</a>.</p>
</li>
<li><p><a target="_blank" href="https://www.deque.com/axe-con/"><strong>axe-con</strong></a><br />  A free conference run by Deque Systems (accessibility consultancy and makers of axe).</p>
<ul>
<li><p>Despite being an advertisement for Deque’s products, the conference contains lots of useful talks.</p>
</li>
<li><p>Recordings of past years can be watched for free, if you register.</p>
</li>
</ul>
</li>
<li><p><a target="_blank" href="https://accessibility.day/"><strong>Global Accessibility Awareness Day</strong></a><br />  3rd Thursday in May each year - Miscellaneous events are held around the world</p>
</li>
</ul>
<h1 id="heading-component-libraries">Component libraries</h1>
<p>These component libraries claim to conform to WCAG standards; they could act as good reference implementations.</p>
<p><a target="_blank" href="https://www.digitala11y.com/accessible-ui-component-libraries-roundup/">https://www.digitala11y.com/accessible-ui-component-libraries-roundup/</a></p>
<h1 id="heading-influencers">Influencers</h1>
<p>Lots of helpful information about accessibility is written by independent people who have figured stuff out and shared their knowledge on personal blogs. These people have good things to say.</p>
<ul>
<li><p>Carie Fisher (<a target="_blank" href="https://cariefisher.com/">website</a>) (<a target="_blank" href="https://twitter.com/cariefisher">twitter</a>)</p>
<ul>
<li><p>A11y writer/speaker</p>
</li>
<li><p>Creator of A11y Style Guide and A11y Talks virtual meetup</p>
</li>
</ul>
</li>
<li><p>Marcy Sutton (<a target="_blank" href="https://marcysutton.com/">website</a>) (<a target="_blank" href="https://twitter.com/marcysutton">twitter</a>) (<a target="_blank" href="https://testingaccessibility.com/articles">”Testing Accessibility” blog</a>)</p>
<ul>
<li><p>Freelance a11y specialist</p>
</li>
<li><p>Free email list with interesting weekly mini-articles (which are informative, but are also ads for her workshops)</p>
</li>
<li><p>Conducts regular online workshops (see “Services” tab or <a target="_blank" href="https://testingaccessibility.com/workshops">https://testingaccessibility.com/workshops</a>)</p>
</li>
</ul>
</li>
<li><p>Ben Myers (<a target="_blank" href="https://benmyers.dev/">website</a>) (<a target="_blank" href="https://twitter.com/BenDMyers">twitter</a>)</p>
<ul>
<li>Accessibility advocate with a weekly livestream, and also a blog</li>
</ul>
</li>
<li><p>Scott O’Hara (<a target="_blank" href="https://www.scottohara.me/">website</a>) (<a target="_blank" href="https://twitter.com/scottohara">twitter</a>)</p>
<ul>
<li>Accessibility developer at Microsoft</li>
</ul>
</li>
<li><p>Adrian Roselli (<a target="_blank" href="https://adrianroselli.com/">website</a>)</p>
<ul>
<li>Consultant with lots of deep-dive blog articles about specific topics and pitfalls</li>
</ul>
</li>
<li><p>Sara Soueidan (<a target="_blank" href="https://www.sarasoueidan.com/">website</a>) (<a target="_blank" href="https://twitter.com/SaraSoueidan">twitter</a>)</p>
<ul>
<li>She’s developing a paid online course, set to debut in early 2023</li>
</ul>
</li>
<li><p>Sarah Higley (<a target="_blank" href="https://sarahmhigley.com/">website</a>)</p>
</li>
<li><p>Ashlee M Boyer (<a target="_blank" href="https://ashleemboyer.com/">website</a>)</p>
</li>
</ul>
<h1 id="heading-miscellaneous-articles">Miscellaneous Articles</h1>
<p>Various one-off pieces I found especially useful.</p>
<ul>
<li><p><a target="_blank" href="https://www.sarasoueidan.com/blog/focus-indicators/">https://www.sarasoueidan.com/blog/focus-indicators/</a></p>
</li>
<li><p><a target="_blank" href="https://cariefisher.com/a11y-start/">https://cariefisher.com/a11y-start/</a></p>
</li>
<li><p><a target="_blank" href="https://mikemai.net/blog/2022/12/04/24-semantic-terms-web-pros-should-know.html">https://mikemai.net/blog/2022/12/04/24-semantic-terms-web-pros-should-know.html</a></p>
</li>
<li><p><a target="_blank" href="https://css-tricks.com/inclusively-hidden/">https://css-tricks.com/inclusively-hidden/</a></p>
</li>
<li><p><a target="_blank" href="https://css-tricks.com/making-disabled-buttons-more-inclusive/">https://css-tricks.com/making-disabled-buttons-more-inclusive/</a></p>
</li>
<li><p><a target="_blank" href="https://www.tpgi.com/using-the-html-title-attribute-updated/">https://www.tpgi.com/using-the-html-title-attribute-updated/</a></p>
</li>
<li><p><a target="_blank" href="https://medium.com/salesforce-ux/7-things-every-designer-needs-to-know-about-accessibility-64f105f0881b">https://medium.com/salesforce-ux/7-things-every-designer-needs-to-know-about-accessibility-64f105f0881b</a></p>
</li>
</ul>
<h1 id="heading-consultancies">Consultancies</h1>
<p>These companies can be hired to do accessibility audits for your software. Their websites also contain lots of educational material about how to conform to the various standards.</p>
<ul>
<li><p><a target="_blank" href="https://axesslab.com/">https://axesslab.com/</a><br />  They have a nice blog too!</p>
</li>
<li><p><a target="_blank" href="https://www.levelaccess.com/">https://www.levelaccess.com/</a></p>
</li>
<li><p><a target="_blank" href="https://www.deque.com/">https://www.deque.com/</a></p>
</li>
</ul>
<h1 id="heading-advice-threads-aggregations-of-resources">Advice threads / aggregations of resources</h1>
<p>Dropping these links here so I can find them in the future; likely some interesting resources in these threads that could be listed above.</p>
<ul>
<li><p><a target="_blank" href="https://twitter.com/codeability/status/1504608001877020676?s=21">https://twitter.com/codeability/status/1504608001877020676?s=21</a></p>
</li>
<li><p><a target="_blank" href="https://a11y-style-guide.com/style-guide/section-resources.html">https://a11y-style-guide.com/style-guide/section-resources.html</a></p>
</li>
<li><p><a target="_blank" href="https://twitter.com/kathryngrayson/status/1565401468714323971">https://twitter.com/kathryngrayson/status/1565401468714323971</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[How to remove circular dependencies from a fast-moving codebase]]></title><description><![CDATA[This is not a tutorial. This is more like "here's a technique I used in the past and I'm writing it down so someone could do it again." Implementing this will require custom coding that I did not write for you. If you have ideas about how to do this ...]]></description><link>https://drbr.dev/how-to-remove-circular-dependencies-from-a-fast-moving-codebase</link><guid isPermaLink="true">https://drbr.dev/how-to-remove-circular-dependencies-from-a-fast-moving-codebase</guid><dc:creator><![CDATA[Andrew Brandon]]></dc:creator><pubDate>Wed, 20 Jul 2022 20:26:36 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/Cawp7im-QMY/upload/v1658278954083/VjFYD68mq.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is not a tutorial. This is more like "here's a technique I used in the past and I'm writing it down so someone could do it again." Implementing this will require custom coding that I did not write for you. If you have ideas about how to do this concretely (or differently), please leave a comment!</p>
<p>The subject of this article is a TypeScript codebase, but the same ideas could apply to projects written in any language.</p>
<h1 id="heading-the-problem">The Problem</h1>
<p>Once upon a time, I worked on a large single-page React app written in TypeScript. When the app got big enough, we started getting frequent runtime crashes due to circular imports <em>(for example, if A imports B and B imports A, A doesn't yet exist when B gets loaded)</em>. We'd fix one cycle but then it would soon happen somewhere else. We had to do something to keep this problem from impeding us.</p>
<p>There are a lot of reasons one might want to remove circular dependencies, but it's clear to me that keeping a codebase void of cycles is beneficial. Here are what I see as the two main advantages:</p>
<ul>
<li>Prevent some runtime errors when the app is being loaded (the problem we had above);</li>
<li>Enable smaller compilation units, which sets the stage for all sorts of great stuff like incremental builds/tests, code splitting, and more.</li>
</ul>
<h1 id="heading-a-solution">A Solution</h1>
<p>Our codebase was big, so one person couldn't just go in at once and remove cycles. Without a way to track them, it was far too easy for people to unknowingly introduce new cycles in the course of their normal work, and also easy for a person removing a cycle to accidentally add a different one. We needed to make sure that we could remove them one by one, over time, without slipping back.</p>
<p>My solution looked like this:</p>
<ol>
<li>Add a local shell command that generates a list of all the import cycles in the codebase.</li>
<li>That list gets checked in to source control so we can easily compare the cycles in our locally-changed codebase to whatever was there before.</li>
<li>As part of every build (local and on the CI), the same command gets run to generate a list of all the cycles in the codebase. If the newly-generated file and the checked-in file are not an exact match, print the differences and fail the build. If a developer was changing cycles intentionally, they could first manually generate the file (by running the command) and check it in along with their changes.</li>
</ol>
<p>This model was successful in keeping the number of cycles on a mostly-downward trajectory over time. By forcing the developer to manually "lock in" their changes every time they added or removed cycles (and supplying helpful error messages at build time), developers were able to understand the consequences of their changes and refactor their code accordingly to make sure cycles were being removed, not added.</p>
<h2 id="heading-how-to-detect-the-cycles">How to detect the cycles</h2>
<p>There are many ways to do this, but ideally it needs to be <em>fast</em>.</p>
<p>I used the Webpack <a target="_blank" href="https://www.npmjs.com/package/circular-dependency-plugin">circular-dependency-plugin</a>, which has a big disadvantage in that it only detects runtime imports. TypeScript type-only imports are stripped out by the time Webpack runs. This is not terribly slow, but it's not terribly fast either. I'm pretty sure we could do better.</p>
<p>There's also <a target="_blank" href="https://www.npmjs.com/package/eslint-plugin-import">https://www.npmjs.com/package/eslint-plugin-import</a>, but it will run <em>very slowly</em> on large codebases, because the linter (by design) analyzes each file in isolation, so it's duplicating a lot of work when traversing the dependency graph.</p>
<p>If I were to do this again, in lieu of finding an existing tool that's fast enough, I'd consider writing a custom standalone tool. We should be able to get the imports from each file using the TypeScript compiler API and analyze the cycles using an O(n) algorithm such as <a target="_blank" href="https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm">Tarjan's strongly connected components algorithm</a>. The downside here is that we wouldn't get in-IDE feedback (like we would with ESLint) when a cycle exists.</p>
<h2 id="heading-file-format">File format</h2>
<p>As for the file generated by the tool, I used a JSON format so it could be easily parsed by scripts but also read by humans. Importantly, this file must be normalized, so that the cycles will be reported the same even if some code has moved around in minor ways. I normalized the raw results by sorting them three times:</p>
<ol>
<li>Sort cycles by length, descending. That makes it easy to find the biggest ones to refactor first.</li>
<li>Rotate each cycle so that its first-alphabetical filename is at the start. So, <code>B-&gt;C-&gt;A</code> and <code>C-&gt;A-&gt;B</code> would both be reported as <code>A-&gt;B-&gt;C</code>.</li>
<li>Within each length and after rotating, remove duplicates and sort alphabetically.</li>
</ol>
<p>Also in the output file, I included a JSON object that mapped each file name to the number of cycles in which it appeared (sorted in descending order by count). This also proved to be a helpful tool in deciding which file to break down next.</p>
<h2 id="heading-build-output-and-manual-inspection">Build output and manual inspection</h2>
<p>The command line tool would have two modes (specified via args): one to generate the file in memory (run by the build script), and another to actually write it to disk (run by developers). The role of doing this in the build script is to make sure that cycles aren't being added, but also to make sure that if cycles are removed, a new version of the tracking file gets checked in. In my solution, the build generated the cycle list in memory and compared it to the one on disk. Depending on the result, one of the following could happen:</p>
<ul>
<li>If the files were an exact match, quietly succeed/continue the build.</li>
<li>If the files were not a match, compare the array of normalized cycles to figure out which were added and which were removed. Display this information to the user.<ul>
<li>If only removals were found, invite the user to manually regenerate the file and build again. With the regenerated file, subsequent builds would pass.</li>
<li>If there were additions (or a mixture of removals and additions), invite the user to manually inspect the list and decide what to do (either check in the new file anyway, or change their code to avoid adding cycles).</li>
</ul>
</li>
</ul>
<p>Because the file is normalized and checked in to source control, easily-inspectable diffs would show up on pull requests so everyone is aware of the cycles being changed. And, of course, the CI build would fail unless the checked-in file matched the freshly-calculated result.</p>
<h1 id="heading-conclusion-and-next-steps">Conclusion and next steps</h1>
<p>A technique like this can help a team remove cycles over time on a large codebase, if you're willing to write some custom build steps. This system would remain in place to track the cycles until it gets down to zero, at which point it could be replaced with a much simpler build step that simply fails if any cycles are detected (no need for the tracking file).</p>
<p>Please comment if you know of another good cycle-detection tool that could work with this system!</p>
]]></content:encoded></item><item><title><![CDATA[Test post]]></title><description><![CDATA[This is my first blog post, does it even work? Just checking out the platform.
It should be able to support Markdown, like lists:

Come
See
Conquer

But the markdown looks weird because I'm not typing it in a monospaced font, even though it renders w...]]></description><link>https://drbr.dev/test-post</link><guid isPermaLink="true">https://drbr.dev/test-post</guid><dc:creator><![CDATA[Andrew Brandon]]></dc:creator><pubDate>Tue, 15 Feb 2022 09:25:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/NodtnCsLdTE/upload/v1644916985896/cmsdp3bpf.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is my first blog post, does it even work? Just checking out the platform.</p>
<p>It should be able to support Markdown, like lists:</p>
<ol>
<li>Come</li>
<li>See</li>
<li>Conquer</li>
</ol>
<p>But the markdown looks <em>weird</em> because I'm not typing it in a <code>monospaced font</code>, even though it renders with all the same markup.</p>
<p>Can I do links? Go check out my <a target="_blank" href="https://www.pepperandoliveoil.com/">recipe blog</a>!</p>
]]></content:encoded></item></channel></rss>