<?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: Nick Gulev</title>
    <description>The latest articles on Forem by Nick Gulev (@nick_fe_nick).</description>
    <link>https://forem.com/nick_fe_nick</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%2F1110100%2F5c516002-317a-414f-8540-136ee488a80a.jpeg</url>
      <title>Forem: Nick Gulev</title>
      <link>https://forem.com/nick_fe_nick</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nick_fe_nick"/>
    <language>en</language>
    <item>
      <title>Making dynamic UIs accessible with ARIA live regions</title>
      <dc:creator>Nick Gulev</dc:creator>
      <pubDate>Fri, 21 Nov 2025 01:42:50 +0000</pubDate>
      <link>https://forem.com/nick_fe_nick/making-dynamic-uis-accessible-with-aria-live-regions-531d</link>
      <guid>https://forem.com/nick_fe_nick/making-dynamic-uis-accessible-with-aria-live-regions-531d</guid>
      <description>&lt;p&gt;If your UI updates content dynamically — form errors, loading states, search results, “saved!” messages — screen reader users won’t automatically know that something changed. Unless you tell them.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;ARIA Live Regions&lt;/strong&gt; come in.&lt;/p&gt;

&lt;h2&gt;
  
  
  What ARIA Live Regions actually do**
&lt;/h2&gt;

&lt;p&gt;A live region is an invisible area in the DOM that screen readers monitor.&lt;br&gt;
When the text inside it changes, it gets announced automatically.&lt;/p&gt;

&lt;p&gt;The two attributes you’ll use most often:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;aria-live="polite"&lt;/code&gt; — announce when the screen reader has a moment&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;aria-live="assertive"&lt;/code&gt; — interrupt everything and announce immediately&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Optionally:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;aria-atomic="true"&lt;/code&gt; — read the whole region instead of only the changed part&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div aria-live="polite"&amp;gt;Form saved successfully.&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why you shouldn’t implement it from scratch**
&lt;/h2&gt;

&lt;p&gt;Manually wiring live regions seems easy… until it isn’t.&lt;br&gt;
Framework render cycles don’t always line up with how screen readers detect changes. Sometimes nothing gets announced at all. Sometimes it announces twice. Sometimes not at all until the user focuses something.&lt;/p&gt;

&lt;p&gt;To avoid these weird edge cases, it’s much better to use a small, dedicated helper library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Libraries for each framework
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;React&lt;/strong&gt;&lt;br&gt;
react-aria-live&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/react-aria-live" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/react-aria-live&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vue&lt;/strong&gt;&lt;br&gt;
vue-announce&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/vue-announce" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/vue-announce&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Svelte&lt;/strong&gt;&lt;br&gt;
svelte-aria-live&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/svelte-aria-live" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/svelte-aria-live&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Screen reader users actually hear what your UI is doing&lt;/li&gt;
&lt;li&gt;It satisfies WCAG 2.1 – Status Messages&lt;/li&gt;
&lt;li&gt;Forms, async actions, and background processes become understandable without guessing&lt;/li&gt;
&lt;li&gt;It’s one of the easiest accessibility wins you can ship today&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>a11y</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Under‑the‑Radar CSS Tricks You Should Try</title>
      <dc:creator>Nick Gulev</dc:creator>
      <pubDate>Tue, 15 Jul 2025 01:59:03 +0000</pubDate>
      <link>https://forem.com/nick_fe_nick/under-the-radar-css-tricks-you-should-try-38og</link>
      <guid>https://forem.com/nick_fe_nick/under-the-radar-css-tricks-you-should-try-38og</guid>
      <description>&lt;h2&gt;
  
  
  Organize Cascade Chaos with @layer
&lt;/h2&gt;

&lt;p&gt;CSS Layers let you scope the cascade—author styles, component libraries, and third‑party widgets no longer have to fight for specificity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@layer reset, theme, components;

@layer reset {
  *, *::before, *::after { box-sizing: border-box; margin: 0; }
}

@layer theme {
  :root { --brand: #0066ee; }
}

@layer components {
  .button { background: var(--brand); color: white; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://codepen.io/nickbrit-the-scripter/pen/EajJEra" rel="noopener noreferrer"&gt;Codepen&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Select Parents with &lt;code&gt;:has()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The long‑awaited relational selector lets you style an element if it contains something—effectively giving us a parent selector.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.card:has(input[type="checkbox"]:checked) {
  border: 2px solid limegreen;
  box-shadow: 0 0 0 3px color-mix(in srgb, limegreen 40%, transparent);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://codepen.io/nickbrit-the-scripter/pen/emNoMxw" rel="noopener noreferrer"&gt;Codepen&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  One‑Line Form Theming with &lt;code&gt;accent-color&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Bored of default checkboxes and progress bars? This single property tints a host of form controls without custom markup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:root { accent-color: rebeccapurple; }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Works on &lt;code&gt;&amp;lt;input type="checkbox|radio|range"&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;progress&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;meter&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codepen.io/nickbrit-the-scripter/pen/vEOMRMm" rel="noopener noreferrer"&gt;Codepen&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Container Queries
&lt;/h2&gt;

&lt;p&gt;Media queries look at the viewport; container queries look at any element’s own size. Combine &lt;code&gt;container-type: inline-size&lt;/code&gt; with @container to build truly modular components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.card {
  container-type: inline-size; /* establish a query container */
}

@container (width &amp;gt; 40rem) {
  .card {
    display: grid;
    grid-template-columns: 1fr 2fr;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No more &lt;code&gt;.wide&lt;/code&gt; modifier hacks when the sidebar collapses.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codepen.io/nickbrit-the-scripter/pen/ogjXBde" rel="noopener noreferrer"&gt;Codepen&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Snap Scroll Any Axis
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;scroll-snap-type&lt;/code&gt;, &lt;code&gt;scroll-snap-align&lt;/code&gt;, and friends give you native carousels and step‑through storytelling without JS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.gallery {
  scroll-snap-type: x mandatory;
  display: flex;
  overflow-x: auto;
}
.slide {
  scroll-snap-align: center; /* or start / end */
  flex: 0 0 100%;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add scroll-padding to fine‑tune where the snap lands. Be mindful of prefers‑reduced‑motion for accessibility.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codepen.io/nickbrit-the-scripter/pen/EaVjZGZ" rel="noopener noreferrer"&gt;Codepen&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Calculated Color with &lt;code&gt;color-mix()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Stop hard‑coding tints: blend any two colors directly in CSS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.button {
  background: color-mix(in srgb, var(--brand) 75%, white);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pair it with custom properties to build dark‑mode palettes (mix with black instead of white in &lt;code&gt;@media (prefers-color-scheme: dark)&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codepen.io/nickbrit-the-scripter/pen/JoYdEzy" rel="noopener noreferrer"&gt;Codepen&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
    </item>
    <item>
      <title>Accessibility as a core principle</title>
      <dc:creator>Nick Gulev</dc:creator>
      <pubDate>Thu, 20 Mar 2025 02:48:09 +0000</pubDate>
      <link>https://forem.com/nick_fe_nick/accessibility-as-a-core-principle-2f90</link>
      <guid>https://forem.com/nick_fe_nick/accessibility-as-a-core-principle-2f90</guid>
      <description>&lt;p&gt;Accessibility is one of those things that often gets pushed to "later" (which usually means never). When you're working on a side project or racing to meet a deadline, it’s easy to skip it.&lt;/p&gt;

&lt;p&gt;But here’s the problem: ignoring accessibility now is like planting landmines in your own codebase. As your project grows, those “quick hacks” turn into a nightmare. Users start running into issues, fixing them becomes way harder than it should be.&lt;/p&gt;

&lt;p&gt;And look, accessibility isn’t just about compliance. It’s about building stuff that actually works for real people—including those with disabilities.&lt;/p&gt;

&lt;p&gt;There are small, practical things you can remember that’ll have a huge impact. Let’s dig into them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do not use &lt;code&gt;href="#"&lt;/code&gt; in &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;.
&lt;/h2&gt;

&lt;p&gt;Users who rely on screen readers or keyboard navigation expect links to go somewhere. If href="#" is used without proper handling, the screen reader might announce it as a link, but it doesn’t actually navigate anywhere, which can be confusing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; instead of &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; for interactive elements.
&lt;/h2&gt;

&lt;p&gt;Buttons are focusable, keyboard-accessible, and provide built-in semantics for assistive technologies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use proper heading structures (&lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; to &lt;code&gt;&amp;lt;h6&amp;gt;&lt;/code&gt;) in the correct order.
&lt;/h2&gt;

&lt;p&gt;Headings help screen readers and users quickly understand page structure and navigate efficiently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use  for form inputs to provide clear context.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;label for="username"&amp;gt;Username:&amp;lt;/label&amp;gt;
&amp;lt;input type="text" id="username" name="username"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Color contrast.
&lt;/h2&gt;

&lt;p&gt;Low contrast text is difficult to read for users with visual impairments. (&lt;em&gt;Checking contrast is easy in DevTools&lt;/em&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Keyboard navigation matters.
&lt;/h2&gt;

&lt;p&gt;Not all users rely on a mouse—some navigate solely using the keyboard. Your site should be fully accessible via the &lt;code&gt;Tab&lt;/code&gt; key.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure all interactive elements can be focused with Tab.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;:focus&lt;/code&gt; styles to highlight active elements.&lt;/li&gt;
&lt;li&gt;Avoid &lt;code&gt;tabindex="-1"&lt;/code&gt; unless necessary.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Provide alternative text for images
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;img src="graph.png" alt="Bar graph showing sales trends from 2020 to 2023."&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use ARIA wisely
&lt;/h2&gt;

&lt;p&gt;ARIA (Accessible Rich Internet Applications) helps with accessibility but can be tricky to use correctly. Use native HTML whenever possible and keep ARIA simple.&lt;/p&gt;




&lt;p&gt;Accessibility isn’t an all-or-nothing deal. Even small improvements can make a big difference. The earlier you integrate accessibility into your workflow, the better experience you’ll create for everyone.&lt;/p&gt;

&lt;p&gt;Let’s not wait until it’s a problem. Let’s build accessible web experiences from day one.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>html</category>
      <category>a11y</category>
    </item>
  </channel>
</rss>
