<?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: Cat</title>
    <description>The latest articles on DEV Community by Cat (@cat_b6311d81e19dfa8).</description>
    <link>https://dev.to/cat_b6311d81e19dfa8</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4153082%2Ffeb156a9-405d-459a-80d8-57e4d3bb556d.png</url>
      <title>DEV Community: Cat</title>
      <link>https://dev.to/cat_b6311d81e19dfa8</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cat_b6311d81e19dfa8"/>
    <language>en</language>
    <item>
      <title>How to Follow Celebrity News Without Drowning in Headlines</title>
      <dc:creator>Cat</dc:creator>
      <pubDate>Thu, 08 Oct 2026 02:06:41 +0000</pubDate>
      <link>https://dev.to/cat_b6311d81e19dfa8/how-to-follow-celebrity-news-without-drowning-in-headlines-44cf</link>
      <guid>https://dev.to/cat_b6311d81e19dfa8/how-to-follow-celebrity-news-without-drowning-in-headlines-44cf</guid>
      <description>&lt;p&gt;Entertainment coverage never stops, and the volume can be exhausting. A few habits make it easier to keep up with what you care about and skip the rest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pick sections, not feeds
&lt;/h2&gt;

&lt;p&gt;Instead of scrolling one endless stream, use category pages. BuzzBeat organizes &lt;a href="https://buzzbeat.tv/category/celebrity" rel="noopener noreferrer"&gt;celebrity news&lt;/a&gt; into its own section, alongside separate pages for music, TV and film, reality TV, awards and royals. Bookmarking only the sections you enjoy cuts noise quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Follow shows, not just stars
&lt;/h2&gt;

&lt;p&gt;If you watch a particular series, a dedicated page beats hunting through general headlines. BuzzBeat lists a &lt;a href="https://buzzbeat.tv/category/reality-tv" rel="noopener noreferrer"&gt;reality TV&lt;/a&gt; category and topic hubs for subjects such as Love Island and the Kardashians, so fans of those shows have a single place to look.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep film and television together
&lt;/h2&gt;

&lt;p&gt;For release chatter, casting talk and episode reactions, the &lt;a href="https://buzzbeat.tv/category/tv-film" rel="noopener noreferrer"&gt;TV and film news&lt;/a&gt; section groups that coverage in one list. It is a handy starting point when you are deciding what to watch next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do not forget global scenes
&lt;/h2&gt;

&lt;p&gt;Pop culture is not only Hollywood. BuzzBeat also publishes a &lt;a href="https://buzzbeat.tv/category/kpop" rel="noopener noreferrer"&gt;K-Pop news&lt;/a&gt; section, plus Bollywood and Latino categories, which helps if your taste crosses borders.&lt;/p&gt;

&lt;h2&gt;
  
  
  A simple routine
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Choose three sections that match your interests.&lt;/li&gt;
&lt;li&gt;Check them once or twice a day instead of constantly.&lt;/li&gt;
&lt;li&gt;Read the editorial policy and corrections pages of any outlet you rely on, so you know how stories are handled.&lt;/li&gt;
&lt;li&gt;Treat unconfirmed reports as rumors until a second source backs them up.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Where to start
&lt;/h2&gt;

&lt;p&gt;The BuzzBeat homepage shows trending and just-in stories, and the site offers a free account for commenting and saving stories, plus a daily email newsletter. Start from &lt;a href="https://buzzbeat.tv" rel="noopener noreferrer"&gt;BuzzBeat&lt;/a&gt; and build your own short list of sections. A narrower feed is a calmer one, and you will enjoy the stories you actually opted into.&lt;/p&gt;

</description>
      <category>entertainment</category>
      <category>media</category>
      <category>news</category>
      <category>culture</category>
    </item>
    <item>
      <title>Public Wi-Fi Risks and How a WireGuard VPN Helps</title>
      <dc:creator>Cat</dc:creator>
      <pubDate>Thu, 08 Oct 2026 02:06:03 +0000</pubDate>
      <link>https://dev.to/cat_b6311d81e19dfa8/public-wi-fi-risks-and-how-a-wireguard-vpn-helps-303k</link>
      <guid>https://dev.to/cat_b6311d81e19dfa8/public-wi-fi-risks-and-how-a-wireguard-vpn-helps-303k</guid>
      <description>&lt;p&gt;Coffee shops, airports and hotels all offer free wireless, and most of us connect without a second thought. Here is a practical look at what changes when you add a tunnel.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a VPN does on shared networks
&lt;/h2&gt;

&lt;p&gt;A &lt;a href="https://hausvpn.com" rel="noopener noreferrer"&gt;VPN for public Wi-Fi&lt;/a&gt; encrypts traffic between your device and the VPN server, so other people on the same network cannot read it in transit. It does not make you anonymous, and HausVPN says so plainly on its own site: it does not hide your activity from services you sign in to.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the protocol matters
&lt;/h2&gt;

&lt;p&gt;HausVPN is built on WireGuard, a modern protocol known for a small codebase. A &lt;a href="https://hausvpn.com" rel="noopener noreferrer"&gt;no-logs WireGuard VPN&lt;/a&gt; pairs that protocol with a stated policy of keeping no browsing history, DNS records, connection timestamps or source IP. As with any claim, read the policy yourself before relying on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features that help when you roam
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Kill switch:&lt;/strong&gt; the site describes blocking internet access if the tunnel drops, instead of exposing traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-connect:&lt;/strong&gt; it can connect automatically when you join an untrusted Wi-Fi network.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Status panel:&lt;/strong&gt; you can see protocol, server and session details at a glance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A &lt;a href="https://hausvpn.com" rel="noopener noreferrer"&gt;VPN kill switch&lt;/a&gt; matters most when the connection is unstable, which is common on crowded public networks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server locations
&lt;/h2&gt;

&lt;p&gt;HausVPN lists New York as live, with Los Angeles, London, Frankfurt, Singapore and Toronto also shown on its locations section. Check the site for current availability, and note that the Android app is described as in preparation, with iOS to follow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Good habits that still apply
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Keep your operating system and apps updated.&lt;/li&gt;
&lt;li&gt;Turn on two-factor authentication.&lt;/li&gt;
&lt;li&gt;Avoid entering sensitive details on sites you do not recognize.&lt;/li&gt;
&lt;li&gt;Use a &lt;a href="https://hausvpn.com" rel="noopener noreferrer"&gt;VPN for travelers&lt;/a&gt; as one layer, not your only defense.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can read the full feature list at &lt;a href="https://hausvpn.com" rel="noopener noreferrer"&gt;HausVPN&lt;/a&gt; and compare it against what you need before you next board a flight or settle into a cafe.&lt;/p&gt;

</description>
      <category>privacy</category>
      <category>security</category>
      <category>wireguard</category>
      <category>networking</category>
    </item>
    <item>
      <title>What to Look For in a VPN for iPhone and iPad</title>
      <dc:creator>Cat</dc:creator>
      <pubDate>Thu, 08 Oct 2026 02:05:27 +0000</pubDate>
      <link>https://dev.to/cat_b6311d81e19dfa8/what-to-look-for-in-a-vpn-for-iphone-and-ipad-2jp2</link>
      <guid>https://dev.to/cat_b6311d81e19dfa8/what-to-look-for-in-a-vpn-for-iphone-and-ipad-2jp2</guid>
      <description>&lt;p&gt;Your iPhone follows you everywhere, which means your traffic does too. Before installing the first VPN you find in the App Store, it helps to know what actually matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the platform
&lt;/h2&gt;

&lt;p&gt;Many services treat Apple devices as an afterthought. A dedicated &lt;a href="https://deseovpn.com" rel="noopener noreferrer"&gt;VPN for iPhone&lt;/a&gt; is built around how iOS handles network extensions, background connections and battery use, rather than being a port of a desktop client. DESEO VPN states that it is built for iPhone and iPad.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read the privacy stance, not just the feature list
&lt;/h2&gt;

&lt;p&gt;A &lt;a href="https://deseovpn.com" rel="noopener noreferrer"&gt;privacy-focused VPN&lt;/a&gt; should be clear about what it does with your connection. Look for plain-language policies, a short list of permissions, and no pressure to hand over more data than needed. Note that DESEO VPN requires an account in order to connect, so factor that into your own threat model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions worth asking
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Which devices does the app officially support?&lt;/li&gt;
&lt;li&gt;What does the privacy policy say about connection data?&lt;/li&gt;
&lt;li&gt;Is account creation required, and what does it collect?&lt;/li&gt;
&lt;li&gt;Is the app transparent about what it does and does not protect?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A realistic expectation
&lt;/h2&gt;

&lt;p&gt;No VPN makes you invisible. It encrypts the path between your phone and the VPN server, which matters on shared networks, but it does not replace software updates, strong passwords or two-factor authentication. Treat it as one layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick checklist before you install
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Confirm the app lists iPhone and iPad support.&lt;/li&gt;
&lt;li&gt;Read how the provider describes privacy.&lt;/li&gt;
&lt;li&gt;Understand the sign-up requirement.&lt;/li&gt;
&lt;li&gt;Test it on your normal daily apps.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you want to see how one provider presents these points, visit &lt;a href="https://deseovpn.com" rel="noopener noreferrer"&gt;DESEO VPN&lt;/a&gt; and compare it with what you expect from a &lt;a href="https://deseovpn.com" rel="noopener noreferrer"&gt;privacy-focused VPN&lt;/a&gt; on iOS. Ask the same questions of every option you consider, and pick the one whose answers you can actually verify.&lt;/p&gt;

</description>
      <category>privacy</category>
      <category>ios</category>
      <category>security</category>
      <category>mobile</category>
    </item>
    <item>
      <title>A small icon is not necessarily a small click target</title>
      <dc:creator>Cat</dc:creator>
      <pubDate>Wed, 07 Oct 2026 06:10:54 +0000</pubDate>
      <link>https://dev.to/cat_b6311d81e19dfa8/a-small-icon-is-not-necessarily-a-small-click-target-56mb</link>
      <guid>https://dev.to/cat_b6311d81e19dfa8/a-small-icon-is-not-necessarily-a-small-click-target-56mb</guid>
      <description>&lt;p&gt;A small icon can be easy to see and still be hard to activate. The visible mark and the clickable area are different parts of a control. When a row of tiny actions sits close together, the question is not simply whether the icons look large enough in a screenshot. It is whether a person using a pointer can reliably activate the intended target.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measure the target, then inspect its neighbors
&lt;/h2&gt;

&lt;p&gt;WCAG 2.2 Target Size (Minimum) sets a 24 by 24 CSS pixel threshold for pointer targets, with specific exceptions. One exception concerns spacing around undersized targets. A design review therefore needs to inspect the actual clickable bounds and nearby controls, not just the dimensions of an SVG or PNG. A 16-pixel icon can sit inside a larger button; a 32-pixel icon can also be inside a smaller interactive region if the markup and CSS are wrong.&lt;/p&gt;

&lt;p&gt;Consider an actions column with edit, duplicate, and delete buttons. First identify the element receiving the click. Measure its target area in CSS pixels at the relevant viewport. Then check whether adjacent targets satisfy the spacing condition if any are undersized. Repeat on touch-sized layouts, where a desktop row may wrap or compress. Avoid increasing the icon alone when the actual button box remains unchanged.&lt;/p&gt;

&lt;h2&gt;
  
  
  Repair the interaction, not its screenshot
&lt;/h2&gt;

&lt;p&gt;The right change might be padding the control, separating neighboring buttons, or restructuring the row so each action has a distinct target. Make sure the focus indicator still fits and remains visible after a sizing change. A larger target should not cover or intercept an adjacent action. Test the result in the rendered page, including keyboard and pointer use.&lt;/p&gt;

&lt;p&gt;A &lt;a href="https://adafix.app/product" rel="noopener noreferrer"&gt;website accessibility target size repair&lt;/a&gt; is one example of a specific element-level change to review and verify. Automated checks can help locate candidates, but the final judgment depends on the real target geometry, spacing, exceptions, and behavior on the live interface.&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum.html" rel="noopener noreferrer"&gt;W3C Understanding Target Size (Minimum)&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>css</category>
      <category>ui</category>
      <category>ux</category>
    </item>
    <item>
      <title>An email field can have the right type and the wrong purpose</title>
      <dc:creator>Cat</dc:creator>
      <pubDate>Wed, 07 Oct 2026 05:42:32 +0000</pubDate>
      <link>https://dev.to/cat_b6311d81e19dfa8/an-email-field-can-have-the-right-type-and-the-wrong-purpose-41hb</link>
      <guid>https://dev.to/cat_b6311d81e19dfa8/an-email-field-can-have-the-right-type-and-the-wrong-purpose-41hb</guid>
      <description>&lt;p&gt;A contact form asks for a person's email address. Another field on the same page asks for the email address of a colleague to invite. Both fields might use &lt;code&gt;type="email"&lt;/code&gt;, but they do not collect the same information. The type describes the input format; it does not, by itself, say whose address belongs in the field.&lt;/p&gt;

&lt;p&gt;W3C's &lt;a href="https://www.w3.org/WAI/WCAG22/Understanding/identify-input-purpose.html" rel="noopener noreferrer"&gt;Identify Input Purpose guidance&lt;/a&gt; makes that distinction explicit. For listed fields collecting information about the user, the purpose must be programmatically determinable where the technology supports it. HTML's &lt;code&gt;autocomplete&lt;/code&gt; tokens can express a more specific purpose than the input type.&lt;/p&gt;

&lt;h2&gt;
  
  
  Map the purpose before changing markup
&lt;/h2&gt;

&lt;p&gt;For a form that asks for the user's own email address, a developer can review whether &lt;code&gt;autocomplete="email"&lt;/code&gt; represents that field. The colleague-invitation field needs separate consideration: assigning the user's email purpose to another person's address would misstate what the form asks for. Keep its visible label clear, but do not mechanically stamp the same autocomplete token onto every email-shaped field.&lt;/p&gt;

&lt;p&gt;The same check matters for a name field. &lt;code&gt;type="text"&lt;/code&gt; gives no indication whether the form expects a full name, given name, family name, or another person's name. W3C's fixed tokens include &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;given-name&lt;/code&gt;, and &lt;code&gt;family-name&lt;/code&gt; for different user-information purposes. A reviewer should identify the actual data the application stores before choosing one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test the resulting form
&lt;/h2&gt;

&lt;p&gt;Inspect the rendered field and its accessible name, then check the relevant HTML attribute. Try the form in a browser with saved profile data only in an appropriate test environment. Confirm that the browser does not offer the user's own information in a field meant for someone else. Repeat the check after a source change, since a template can render different fields from similar components.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://adafix.app/product" rel="noopener noreferrer"&gt;ADAFix website accessibility repairs&lt;/a&gt; describe a reviewed source-change and live-verification workflow. An input-purpose finding is a useful example of why the reviewer must connect the visible task to the exact field before approving a markup change. The final check is the live form's meaning and behavior, rather than a green scan result alone.&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>html</category>
      <category>webdev</category>
    </item>
    <item>
      <title>A modal can close cleanly and still leave keyboard focus lost</title>
      <dc:creator>Cat</dc:creator>
      <pubDate>Wed, 07 Oct 2026 05:35:41 +0000</pubDate>
      <link>https://dev.to/cat_b6311d81e19dfa8/a-modal-can-close-cleanly-and-still-leave-keyboard-focus-lost-443g</link>
      <guid>https://dev.to/cat_b6311d81e19dfa8/a-modal-can-close-cleanly-and-still-leave-keyboard-focus-lost-443g</guid>
      <description>&lt;p&gt;A dialog may look finished when its close button disappears, while the keyboard user is left at the top of the document. This is easiest to miss when a team tests the open dialog but stops before testing the return trip. The W3C Authoring Practices Guide describes both directions: move focus into a modal when it opens and, in the usual case, return it to the invoking control when it closes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check the whole interaction
&lt;/h2&gt;

&lt;p&gt;Start on the button that opens the dialog. Activate it with a keyboard, then inspect where focus lands. It should move to an element inside the dialog. Tab forward and backward: focus should remain within the active modal. Close it with the provided control, then repeat with Escape. After closing, find the visible focus indicator and continue tabbing. Can the user understand where they are without starting over?&lt;/p&gt;

&lt;p&gt;When the original trigger still exists, returning focus there usually keeps the workflow intact. When closing the dialog removes its trigger—for example, after deleting a row—the W3C guidance allows another logical destination. In that case, define and test the destination instead of sending focus to the page body.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat opening and closing as separate states
&lt;/h2&gt;

&lt;p&gt;A checklist limited to ARIA attributes will not prove that the focus path works. Test the initial focus, the forward and reverse Tab sequence, Escape, the close control, and the post-close destination. If the dialog has a long heading or several paragraphs, consider whether initial focus on static content helps users orient before reaching an action. W3C's dialog pattern explains why that choice depends on the content.&lt;/p&gt;

&lt;p&gt;A scan can help identify accessibility barriers, but this sequence also needs manual keyboard testing. &lt;a href="https://adafix.app/product" rel="noopener noreferrer"&gt;ADAFix website accessibility repairs&lt;/a&gt; can be part of a broader review and documented repair workflow; it does not replace checking the dialog's real behavior with a keyboard.&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/" rel="noopener noreferrer"&gt;W3C WAI modal dialog pattern&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>frontend</category>
      <category>testing</category>
      <category>ui</category>
    </item>
    <item>
      <title>A tiny DOM check for broken aria-describedby references</title>
      <dc:creator>Cat</dc:creator>
      <pubDate>Tue, 06 Oct 2026 22:17:00 +0000</pubDate>
      <link>https://dev.to/cat_b6311d81e19dfa8/a-tiny-dom-check-for-broken-aria-describedby-references-5f42</link>
      <guid>https://dev.to/cat_b6311d81e19dfa8/a-tiny-dom-check-for-broken-aria-describedby-references-5f42</guid>
      <description>&lt;p&gt;An input can have a visible hint and still fail to expose that hint as a programmatic description. One cause is a stale &lt;code&gt;aria-describedby&lt;/code&gt; ID: the attribute names an element that is no longer on the page. This can happen when a component changes its error state or a template duplicates a form.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.w3.org/WAI/tutorials/forms/instructions/" rel="noopener noreferrer"&gt;W3C forms tutorial&lt;/a&gt; shows &lt;code&gt;aria-describedby&lt;/code&gt; connecting a field to additional instructions. Its value is a space-separated list of IDs in the same document. That gives us a narrow check: every named ID should resolve to an element. It does &lt;strong&gt;not&lt;/strong&gt; tell us whether the text is helpful, whether the field has a proper label, or whether a screen reader announces the right thing.&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;function&lt;/span&gt; &lt;span class="nf"&gt;missingDescriptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;root&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="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="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[aria-describedby]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)].&lt;/span&gt;&lt;span class="nf"&gt;flatMap&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;control&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;control&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;aria-describedby&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="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+/&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;ids&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;control&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ownerDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;control&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;missingId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;id&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;missingDescriptions&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;control&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;missingId&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;control&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="nx"&gt;control&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;control&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tagName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nx"&gt;missingId&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;Run this in the browser console on a page with a form. Enter an invalid value and run it again. Some forms add an error description only after validation, so the initial page and error state deserve separate checks. Repeat after fixing the value: the description should still make sense when the state changes.&lt;/p&gt;

&lt;p&gt;Here is a simple, working relationship to compare against:&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;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Email address&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;aria-describedby=&lt;/span&gt;&lt;span class="s"&gt;"email-help"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email-help"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;We will send a receipt to this address.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a validation error appears, connect the field to a clear message and expose its invalid state. &lt;a href="https://www.w3.org/WAI/tutorials/forms/notifications/" rel="noopener noreferrer"&gt;W3C user-notification guidance&lt;/a&gt; demonstrates field-specific messages; its &lt;a href="https://www.w3.org/WAI/WCAG22/Techniques/aria/ARIA21" rel="noopener noreferrer"&gt;&lt;code&gt;aria-invalid&lt;/code&gt; technique&lt;/a&gt; describes the error state. The message must be available where the user needs it, not just rendered as red text elsewhere.&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;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Email address&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
       &lt;span class="na"&gt;aria-invalid=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; &lt;span class="na"&gt;aria-describedby=&lt;/span&gt;&lt;span class="s"&gt;"email-help email-error"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email-help"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;We will send a receipt to this address.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email-error"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Enter an email address in the name@example.com format.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This console check catches missing references only. It does not detect duplicate IDs, inaccessible hidden content, poor wording, or whether a validation message is announced at the right time. Inspect the accessibility tree, navigate with a keyboard, and test with assistive technology for the actual user experience. If JavaScript updates the form, test each meaningful state rather than only its first render.&lt;/p&gt;

&lt;p&gt;An automated scan can help collect initial findings, while manual state testing handles behavior the first render cannot show. &lt;a href="https://adafix.app/how-it-works" rel="noopener noreferrer"&gt;ADAFix’s accessibility review workflow&lt;/a&gt; is one option for starting that broader review; this small script is a focused developer check to run alongside it.&lt;/p&gt;

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