<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Responsive Web Design - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Responsive Web Design - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 15 May 2026 22:29:56 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/responsive-web-design/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Build Responsive and Accessible UI Designs with React and Semantic HTML ]]>
                </title>
                <description>
                    <![CDATA[ Building modern React applications requires more than just functionality. It also demands responsive layouts and accessible user experiences. By combining semantic HTML, responsive design techniques,  ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-responsive-accessible-ui-with-react-and-semantic-html/</link>
                <guid isPermaLink="false">69d539975da14bc70e76871d</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Accessibility ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Responsive Web Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ semantichtml ]]>
                    </category>
                
                    <category>
                        <![CDATA[ aria ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Gopinath Karunanithi ]]>
                </dc:creator>
                <pubDate>Tue, 07 Apr 2026 17:06:31 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/d2651d02-040d-4c4f-bbfe-ef92097edab4.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Building modern React applications requires more than just functionality. It also demands responsive layouts and accessible user experiences.</p>
<p>By combining semantic HTML, responsive design techniques, and accessibility best practices (like ARIA roles and keyboard navigation), developers can create interfaces that work across devices and for all users, including those with disabilities.</p>
<p>This article shows how to design scalable, inclusive React UIs using real-world patterns and code examples.</p>
<h2 id="heading-table-of-contents"><strong>Table of Contents</strong></h2>
<ul>
<li><p><a href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a href="#heading-overview">Overview</a></p>
</li>
<li><p><a href="#heading-why-accessibility-and-responsiveness-matter">Why Accessibility and Responsiveness Matter</a></p>
</li>
<li><p><a href="#heading-core-principles-of-accessible-and-responsive-design">Core Principles of Accessible and Responsive Design</a></p>
</li>
<li><p><a href="#heading-using-semantic-html-in-react">Using Semantic HTML in React</a></p>
</li>
<li><p><a href="#heading-structuring-a-page-with-semantic-elements">Structuring a Page with Semantic Elements</a></p>
</li>
<li><p><a href="#heading-building-responsive-layouts">Building Responsive Layouts</a></p>
</li>
<li><p><a href="#heading-accessibility-with-aria">Accessibility with ARIA</a></p>
</li>
<li><p><a href="#heading-keyboard-navigation">Keyboard Navigation</a></p>
</li>
<li><p><a href="#heading-focus-management">Focus Management</a></p>
</li>
<li><p><a href="#heading-forms-and-accessibility">Forms and Accessibility</a></p>
</li>
<li><p><a href="#heading-responsive-typography-and-images">Responsive Typography and Images</a></p>
</li>
<li><p><a href="#heading-building-a-fully-accessible-responsive-component-end-to-end-example">Building a Fully Accessible Responsive Component (End-to-End Example)</a></p>
</li>
<li><p><a href="#heading-testing-accessibility">Testing Accessibility</a></p>
</li>
<li><p><a href="#heading-best-practices">Best Practices</a></p>
</li>
<li><p><a href="#heading-when-not-to-overuse-accessibility-features">When NOT to Overuse Accessibility Features</a></p>
</li>
<li><p><a href="#heading-future-enhancements">Future Enhancements</a></p>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before following along, you should be familiar with:</p>
<ul>
<li><p>React fundamentals (components, hooks, JSX)</p>
</li>
<li><p>Basic HTML and CSS</p>
</li>
<li><p>JavaScript ES6 features</p>
</li>
<li><p>Basic understanding of accessibility concepts (helpful but not required)</p>
</li>
</ul>
<h2 id="heading-overview">Overview</h2>
<p>Modern web applications must serve a diverse audience across a wide range of devices, screen sizes, and accessibility needs. Users today expect seamless experiences whether they are browsing on a desktop, tablet, or mobile device – and they also expect interfaces that are usable regardless of physical or cognitive limitations.</p>
<p>Two essential principles help achieve this:</p>
<ul>
<li><p>Responsive design, which ensures layouts adapt to different screen sizes</p>
</li>
<li><p>Accessibility, which ensures applications are usable by people with disabilities</p>
</li>
</ul>
<p>In React applications, these principles are often implemented incorrectly or treated as afterthoughts. Developers may rely heavily on div-based layouts, ignore semantic HTML, or overlook accessibility features such as keyboard navigation and screen reader support.</p>
<p>This article will show you how to build responsive and accessible UI designs in React using semantic HTML. You'll learn how to:</p>
<ul>
<li><p>Structure components using semantic HTML elements</p>
</li>
<li><p>Build responsive layouts using modern CSS techniques</p>
</li>
<li><p>Improve accessibility with ARIA attributes and proper roles</p>
</li>
<li><p>Ensure keyboard navigation and screen reader compatibility</p>
</li>
<li><p>Apply best practices for scalable and inclusive UI design</p>
</li>
</ul>
<p>By the end of this guide, you'll be able to create React interfaces that are not only visually responsive but also accessible to all users.</p>
<h2 id="heading-why-accessibility-and-responsiveness-matter">Why Accessibility and Responsiveness Matter</h2>
<p>Responsive and accessible design isn't just about compliance. It directly impacts usability, performance, and reach.</p>
<p><strong>Accessibility benefits:</strong></p>
<ul>
<li><p>Supports users with visual, motor, or cognitive impairments</p>
</li>
<li><p>Improves SEO and content discoverability</p>
</li>
<li><p>Enhances usability for all users</p>
</li>
</ul>
<p><strong>Responsiveness benefits:</strong></p>
<ul>
<li><p>Ensures consistent UX across devices</p>
</li>
<li><p>Reduces bounce rates on mobile</p>
</li>
<li><p>Improves performance and scalability</p>
</li>
</ul>
<p>Ignoring these principles can result in broken layouts on smaller screens, poor screen reader compatibility, and limited reach and usability.</p>
<h2 id="heading-core-principles-of-accessible-and-responsive-design">Core Principles of Accessible and Responsive Design</h2>
<p>Before diving into the code, it’s important to understand the foundational principles.</p>
<h3 id="heading-1-semantic-html-first">1. Semantic HTML First</h3>
<p>Semantic HTML refers to using HTML elements that clearly describe their meaning and role in the interface, rather than relying on generic containers like <code>&lt;div&gt; or &lt;span&gt;.</code>These elements provide built-in accessibility, improve SEO, and make code more readable.</p>
<p>For example:</p>
<p><strong>Non-semantic:</strong></p>
<pre><code class="language-html">&lt;div onClick={handleClick}&gt;Submit&lt;/div&gt;
</code></pre>
<p><strong>Semantic:</strong></p>
<pre><code class="language-html">&lt;button type="button" onClick={handleClick}&gt;Submit&lt;/button&gt;
</code></pre>
<p>Another example:</p>
<p><strong>Non-semantic:</strong></p>
<pre><code class="language-html">&lt;div className="header"&gt;My App&lt;/div&gt;
</code></pre>
<p><strong>Semantic:</strong></p>
<pre><code class="language-html">&lt;header&gt;My App&lt;/header&gt;
</code></pre>
<p>Using semantic elements such as <code>&lt;header&gt;</code>, <code>&lt;nav&gt;</code>, <code>&lt;main&gt;</code>, <code>&lt;section&gt;</code>, <code>&lt;article&gt;</code>, and <code>&lt;button&gt;</code> helps browsers and assistive technologies (like screen readers) understand the structure and purpose of your UI without additional configuration.</p>
<p>Why this matters:</p>
<ul>
<li><p>Screen readers understand semantic elements automatically</p>
</li>
<li><p>It supports built-in accessibility (keyboard, focus, roles)</p>
</li>
<li><p>There's less need for ARIA attributes</p>
</li>
<li><p>It gives you better SEO and maintainability</p>
</li>
</ul>
<h3 id="heading-2-mobile-first-design">2. Mobile-First Design</h3>
<p>Mobile-first design means starting your UI design with the smallest screen sizes (typically mobile devices) and progressively enhancing the layout for larger screens such as tablets and desktops.</p>
<p>This approach makes sure that core content and functionality are prioritized, layouts remain simple and performant, and users on mobile devices get a fully usable experience.</p>
<p>In practice, mobile-first design involves:</p>
<ul>
<li><p>Using a single-column layout initially</p>
</li>
<li><p>Applying minimal styling and spacing</p>
</li>
<li><p>Avoiding complex UI patterns on small screens</p>
</li>
</ul>
<p>Then, you scale up using CSS media queries:</p>
<pre><code class="language-css">.container {
  display: flex;
  flex-direction: column;
}
@media (min-width: 768px) {
  .container {
    flex-direction: row;
  }
}
</code></pre>
<p>Here, the default layout is optimized for mobile, and enhancements are applied only when the screen size increases.</p>
<p><strong>Why this approach works:</strong></p>
<ul>
<li><p>Prioritizes essential content</p>
</li>
<li><p>Improves performance on mobile devices</p>
</li>
<li><p>Reduces layout bugs when scaling up</p>
</li>
<li><p>Aligns with how most users access web apps today</p>
</li>
</ul>
<h3 id="heading-3-progressive-enhancement">3. Progressive Enhancement</h3>
<p>Progressive enhancement is the practice of building a baseline user experience that works for all users (regardless of their device, browser capabilities, or network conditions) and then layering on advanced features for more capable environments.</p>
<p>This approach ensures that core functionality is always accessible, users on older devices or slow networks aren't blocked, and accessibility is preserved even when advanced features fail.</p>
<p>In practice, this means:</p>
<ul>
<li><p>Start with semantic HTML that delivers content and functionality</p>
</li>
<li><p>Add basic styling with CSS for layout and readability</p>
</li>
<li><p>Enhance interactivity using JavaScript (React) only where needed</p>
</li>
</ul>
<p>For example, a form should still be usable with plain HTML:</p>
<pre><code class="language-html">&lt;form&gt;
  &lt;label htmlFor="email"&gt;Email&lt;/label&gt;
  &lt;input id="email" type="email" /&gt;
  &lt;button type="submit"&gt;Submit&lt;/button&gt;
&lt;/form&gt;
</code></pre>
<p>Then, React can enhance it with validation, dynamic feedback, or animations.</p>
<p>By prioritizing functionality first and enhancements later, you ensure your application remains usable in a wide range of real-world scenarios.</p>
<h3 id="heading-4-keyboard-accessibility">4. Keyboard Accessibility</h3>
<p>Keyboard accessibility ensures that users can navigate and interact with your application using only a keyboard. This is critical for users with motor disabilities and also improves usability for power users.</p>
<p>Key aspects of keyboard accessibility include:</p>
<ul>
<li><p>Ensuring all interactive elements (buttons, links, inputs) are focusable</p>
</li>
<li><p>Maintaining a logical tab order across the page</p>
</li>
<li><p>Providing visible focus indicators (for example, outline styles)</p>
</li>
<li><p>Supporting keyboard events such as Enter and Space</p>
</li>
</ul>
<p><strong>Bad Example (Not Accessible)</strong></p>
<pre><code class="language-html">&lt;div onClick={handleClick}&gt;Submit&lt;/div&gt;
</code></pre>
<p>This element:</p>
<ul>
<li><p>Cannot be focused with a keyboard</p>
</li>
<li><p>Does not respond to Enter/Space</p>
</li>
<li><p>Is invisible to screen readers</p>
</li>
</ul>
<p><strong>Good Example</strong></p>
<pre><code class="language-html">&lt;button type="button" onClick={handleClick}&gt;Submit&lt;/button&gt;
</code></pre>
<p>This automatically supports:</p>
<ul>
<li><p>Keyboard interaction</p>
</li>
<li><p>Focus management</p>
</li>
<li><p>Screen reader announcements</p>
</li>
</ul>
<p><strong>Custom Component Example (if needed)</strong></p>
<pre><code class="language-html">&lt;div
  role="button"
  tabIndex={0}
  onClick={handleClick}
  onKeyDown={(e) =&gt; {
    if (e.key === 'Enter' || e.key === ' ') {
      e.preventDefault();
      handleClick();
    }
  }}
&gt;
  Submit
&lt;/div&gt;
</code></pre>
<p>But only use this when native elements aren't sufficient.</p>
<p>These principles form the foundation of accessible and responsive design:</p>
<ul>
<li><p>Use semantic HTML to communicate intent</p>
</li>
<li><p>Design for mobile first, then scale up</p>
</li>
<li><p>Enhance progressively for better compatibility</p>
</li>
<li><p>Ensure full keyboard accessibility</p>
</li>
</ul>
<p>Applying these early prevents major usability and accessibility issues later in development.</p>
<h2 id="heading-using-semantic-html-in-react">Using Semantic HTML in React</h2>
<p>As we briefly discussed above, semantic HTML plays a critical role in both accessibility (a11y) and code readability. Semantic elements clearly describe their purpose to both developers and browsers, which allows assistive technologies like screen readers to interpret and navigate the UI correctly.</p>
<p>For example, when you use a <code>&lt;button&gt;</code> element, browsers automatically provide keyboard support, focus behavior, and accessibility roles. In contrast, non-semantic elements like <code>&lt;div&gt;</code>require additional attributes and manual handling to achieve the same functionality.</p>
<p>From a readability perspective, semantic HTML makes your code easier to understand and maintain. Developers can quickly identify the structure and intent of a component without relying on class names or external documentation.</p>
<p><strong>Bad Example (Non-semantic)</strong></p>
<pre><code class="language-html">&lt;div onClick={handleClick}&gt;Submit&lt;/div&gt;
</code></pre>
<p>Why this is problematic:</p>
<ul>
<li><p>The <code>&lt;div&gt;</code>element has no inherent meaning or role</p>
</li>
<li><p>It is not focusable by default, so keyboard users can't access it</p>
</li>
<li><p>It does not respond to keyboard events like Enter or Space unless explicitly coded</p>
</li>
<li><p>Screen readers do not recognize it as an interactive element</p>
</li>
</ul>
<p>To make this accessible, you would need to add:</p>
<p><code>role="button"</code></p>
<p><code>tabIndex="0"</code></p>
<p><code>Keyboard event handlers</code></p>
<p><strong>Good Example (Semantic)</strong></p>
<pre><code class="language-html">&lt;button type="button" onClick={handleClick}&gt;Submit&lt;/button&gt;
</code></pre>
<p>Why this is better:</p>
<ul>
<li><p>The <code>&lt;button&gt;</code> element is inherently interactive</p>
</li>
<li><p>It is automatically focusable and keyboard accessible</p>
</li>
<li><p>It supports Enter and Space key activation by default</p>
</li>
<li><p>Screen readers correctly announce it as a button</p>
</li>
</ul>
<p>This reduces complexity while improving accessibility and usability.</p>
<h3 id="heading-why-all-this-matters">Why all this matters:</h3>
<p>There are many reasons to use semantic HTML.</p>
<p>First, semantic elements like <code>&lt;button&gt;, &lt;a&gt;,</code> and <code>&lt;form&gt;</code> come with default accessibility behaviors such as focus management and keyboard interaction</p>
<p>It also reduces complexity: you don’t need to manually implement roles, keyboard handlers, or tab navigation</p>
<p>They provide better screen reader support as well. Assistive technologies can correctly interpret the purpose of elements and announce them appropriately</p>
<p>Semantic HTML also improves maintainability and helps other developers quickly understand the intent of your code without reverse-engineering behavior from event handlers</p>
<p>Finally, you'll generally have fewer bugs in your code. Relying on native browser behavior reduces the risk of missing critical accessibility features</p>
<p>Here's another example:</p>
<p><strong>Non-semantic:</strong></p>
<pre><code class="language-html">&lt;div className="nav"&gt;
  &lt;div onClick={goHome}&gt;Home&lt;/div&gt;
&lt;/div&gt;
</code></pre>
<p><strong>Semantic:</strong></p>
<pre><code class="language-html">&lt;nav&gt;
  &lt;a href="/"&gt;Home&lt;/a&gt;
&lt;/nav&gt;
</code></pre>
<p>Here, <code>&lt;nav&gt;</code> clearly defines a navigation region, and <code>&lt;a&gt;</code> provides built-in link behavior, including keyboard navigation and proper screen reader announcements.</p>
<h2 id="heading-structuring-a-page-with-semantic-elements">Structuring a Page with Semantic Elements</h2>
<p>When building a React application, structuring your layout with semantic HTML elements helps define clear regions of your interface. Instead of relying on generic containers like <code>&lt;div&gt;</code>, semantic elements communicate the purpose of each section to both developers and assistive technologies.</p>
<p>In the example below, we're creating a basic page layout using commonly used semantic elements such as <code>&lt;header&gt;</code>, <code>&lt;nav&gt;</code>, <code>&lt;main&gt;</code>, <code>&lt;section&gt;</code>, and <code>&lt;footer&gt;</code>. Each of these elements represents a specific part of the UI and contributes to better accessibility and maintainability.</p>
<pre><code class="language-javascript">function Layout() {
  return (
    &lt;&gt;
      {/* Skip link for keyboard and screen reader users */}
      &lt;a href="#main-content" className="skip-link"&gt;
        Skip to main content
      &lt;/a&gt;

      &lt;header&gt;
        &lt;h1&gt;My App&lt;/h1&gt;
      &lt;/header&gt;

      &lt;nav&gt;
        &lt;ul&gt;
          &lt;li&gt;&lt;a href="/"&gt;Home&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/nav&gt;

      &lt;main id="main-content"&gt;
        &lt;section&gt;
          &lt;h2&gt;Dashboard&lt;/h2&gt;
        &lt;/section&gt;
      &lt;/main&gt;

      &lt;footer&gt;
        &lt;p&gt;© 2026&lt;/p&gt;
      &lt;/footer&gt;
    &lt;/&gt;
  );
}
</code></pre>
<p>Each element in this layout has a specific role:</p>
<ul>
<li><p>The skip link allows screen reader users to skip to the main content</p>
</li>
<li><p><code>&lt;header&gt;</code>: Represents introductory content or branding</p>
</li>
<li><p><code>&lt;nav&gt;</code>: Contains navigation links</p>
</li>
<li><p><code>&lt;main&gt;</code>: Holds the primary content of the page</p>
</li>
<li><p><code>&lt;section&gt;</code>: Groups related content within the page</p>
</li>
<li><p><code>&lt;footer&gt;</code>: Contains closing or supplementary information</p>
</li>
</ul>
<p>Using these elements correctly ensures your UI is both logically structured and accessible by default.</p>
<h3 id="heading-why-this-structure-is-important">Why this structure is important:</h3>
<p>Properly structuring a page like this brings with it many benefits.</p>
<p>For example, it gives you Improved screen reader navigation. This is because semantic elements allow screen readers to identify different regions of the page (for example, navigation, main content, footer). Users can quickly jump between these sections instead of reading the page linearly</p>
<p>It also gives you better document structure. Elements like <code>&lt;main&gt;</code> and <code>&lt;section&gt;</code> define a logical hierarchy, making content easier to parse for both browsers and assistive technologies</p>
<p>Search engines also use semantic structure to better understand page content and prioritize important sections, resulting in better SEO.</p>
<p>It also makes your code more readable, so other devs can immediately understand the layout and purpose of each section without relying on class names or comments</p>
<p>And it provides built-in accessibility landmarks using elements like <code>&lt;nav&gt;</code> and <code>&lt;main&gt;</code>, allowing assistive technologies to provide shortcuts for users.</p>
<h2 id="heading-building-responsive-layouts">Building Responsive Layouts</h2>
<p>Responsive layouts ensure that your UI adapts smoothly across different screen sizes, from mobile devices to large desktop displays. Instead of building separate layouts for each device, modern CSS techniques like Flexbox, Grid, and media queries allow you to create flexible, fluid designs.</p>
<p>In this section, we’ll look at how layout behavior changes based on screen size, starting with a mobile-first approach and progressively enhancing the layout for larger screens.</p>
<p><strong>Using CSS Flexbox:</strong></p>
<pre><code class="language-css">.container {
  display: flex;
  flex-direction: column;
}

@media (min-width: 768px) {
  .container {
    flex-direction: row;
  }
}
</code></pre>
<p>On smaller screens (mobile), elements are stacked vertically using <code>flex-direction: column</code>, making content easier to read and scroll.</p>
<p>On larger screens (768px and above), the layout switches to a horizontal row, utilizing available screen space more efficiently.</p>
<p><strong>Why this helps:</strong></p>
<ul>
<li><p>Ensures content is readable on small devices without horizontal scrolling</p>
</li>
<li><p>Improves layout efficiency on larger screens</p>
</li>
<li><p>Supports a mobile-first design strategy by defining the default layout for smaller screens first and enhancing it progressively</p>
</li>
</ul>
<p><strong>Using CSS Grid:</strong></p>
<pre><code class="language-css">.grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

@media (min-width: 768px) {
  .grid {
    grid-template-columns: repeat(3, 1fr);
  }
}
</code></pre>
<p>On mobile devices, content is displayed in a single-column layout (<code>1fr</code>), ensuring each item takes full width.</p>
<p>On larger screens, the layout shifts to three equal columns using <code>repeat(3, 1fr)</code>, creating a grid structure.</p>
<p><strong>Why this helps:</strong></p>
<ul>
<li><p>Provides a clean and consistent way to manage complex layouts</p>
</li>
<li><p>Makes it easy to scale from simple to multi-column designs</p>
</li>
<li><p>Improves visual balance and spacing across different screen sizes</p>
</li>
</ul>
<p><strong>React Example:</strong></p>
<pre><code class="language-javascript">function CardGrid() {
  return (
    &lt;div className="grid"&gt;
      &lt;div className="card"&gt;Item 1&lt;/div&gt;
      &lt;div className="card"&gt;Item 2&lt;/div&gt;
      &lt;div className="card"&gt;Item 3&lt;/div&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p>The React component uses the .grid class to apply responsive Grid behavior. Each card automatically adjusts its position based on screen size.</p>
<p><strong>Why this is effective:</strong></p>
<ul>
<li><p>Separates structure (React JSX) from layout (CSS)</p>
</li>
<li><p>Allows you to reuse the same component across different screen sizes without modification</p>
</li>
<li><p>Ensures consistent responsiveness across your application with minimal code</p>
</li>
</ul>
<p>By combining Flexbox for one-dimensional layouts and Grid for two-dimensional layouts, you can build highly adaptable interfaces that respond efficiently to different devices and screen sizes.</p>
<h2 id="heading-accessibility-with-aria">Accessibility with ARIA</h2>
<p>ARIA (Accessible Rich Internet Applications) is a set of attributes that enhance the accessibility of web content, especially when building custom UI components that cannot be fully implemented using native HTML elements.</p>
<p>ARIA works by providing additional semantic information to assistive technologies such as screen readers. It does this through:</p>
<ul>
<li><p>Roles, which define what an element is (for example, button, dialog, menu)</p>
</li>
<li><p>States and properties, which describe the current condition or behavior of an element (for example, expanded, hidden, live updates)</p>
</li>
</ul>
<p>For example, when you create a custom dropdown using <code>&lt;div&gt;</code> elements, browsers don't inherently understand its purpose. By applying ARIA roles and attributes, you can communicate that this structure behaves like a menu and ensure it is interpreted correctly.</p>
<p>Just make sure you use ARIA carefully. Incorrect or unnecessary usage can reduce accessibility. Here's a key rule to follow: use native HTML first. Only use ARIA when necessary.</p>
<p>ARIA is especially useful for:</p>
<ul>
<li><p>Custom UI components (modals, tabs, dropdowns)</p>
</li>
<li><p>Dynamic content updates</p>
</li>
<li><p>Complex interactions not covered by standard HTML</p>
</li>
</ul>
<p>Something to note before we get into the examples here: real-world accessibility is complex. For production apps, you should typically prefer well-tested libraries like react-aria, Radix UI, or Headless UI. These examples are primarily for educational purposes and aren't production-ready.</p>
<p><strong>Example: Accessible Modal</strong></p>
<pre><code class="language-javascript">function Modal({ isOpen, onClose }) {
  const dialogRef = React.useRef();

  React.useEffect(() =&gt; {
    if (isOpen) {
      dialogRef.current?.focus();
    }
  }, [isOpen]);

  if (!isOpen) return null;

  return (
    &lt;div
      role="dialog"
      aria-modal="true"
      aria-labelledby="modal-title"
      tabIndex={-1}
      ref={dialogRef}
      onKeyDown={(e) =&gt; {
        if (e.key === 'Escape') onClose();
      }}
    &gt;
      &lt;h2 id="modal-title"&gt;Modal Title&lt;/h2&gt;
      &lt;button type="button" onClick={onClose}&gt;Close&lt;/button&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p><strong>How this works:</strong></p>
<ul>
<li><p><code>role="dialog"</code> identifies the element as a modal dialog</p>
</li>
<li><p><code>aria-modal="true"</code> indicates that background content is inactive</p>
</li>
<li><p><code>aria-labelledby</code> connects the dialog to its visible title for screen readers</p>
</li>
<li><p><code>tabIndex={-1}</code> allows the dialog container to receive focus programmatically</p>
</li>
<li><p>Focus is moved to the dialog when it opens</p>
</li>
<li><p>Pressing Escape closes the modal, which is a standard accessibility expectation</p>
</li>
</ul>
<p>This ensures that users can understand, navigate, and exit the modal using both keyboard and assistive technologies.</p>
<h3 id="heading-key-aria-attributes">Key ARIA Attributes</h3>
<h4 id="heading-1-role">1. role</h4>
<p>Defines the type of element and its purpose. For example, <code>role="dialog"</code> tells assistive technologies that the element behaves like a modal dialog.</p>
<h4 id="heading-2-aria-label">2. aria-label</h4>
<p>Provides an accessible name for an element when visible text is not sufficient. Screen readers use this label to describe the element to users.</p>
<h4 id="heading-3-aria-hidden">3. aria-hidden</h4>
<p>Indicates whether an element should be ignored by assistive technologies. For example, <code>aria-hidden="true"</code> hides decorative elements from screen readers.</p>
<h4 id="heading-4-aria-live">4. aria-live</h4>
<p>Used for dynamic content updates. It tells screen readers to announce changes automatically without requiring user interaction (for example, form validation messages or notifications).</p>
<p><strong>Example: Accessible Dropdown (Custom Component)</strong></p>
<pre><code class="language-javascript">function Dropdown({ isOpen, toggle }) {
  return (
    &lt;div&gt;
      &lt;button
        type="button"
        aria-expanded={isOpen}
        aria-controls="dropdown-menu"
        onClick={toggle}
      &gt;
        Menu
      &lt;/button&gt;

      {isOpen &amp;&amp; (
        &lt;ul id="dropdown-menu"&gt;
          &lt;li&gt;
            &lt;button type="button" onClick={() =&gt; console.log('Item 1')}&gt;
              Item 1
            &lt;/button&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;button type="button" onClick={() =&gt; console.log('Item 2')}&gt;
              Item 2
            &lt;/button&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      )}
    &lt;/div&gt;
  );
}
</code></pre>
<p><strong>How this works:</strong></p>
<ul>
<li><p><code>aria-expanded</code> indicates whether the dropdown is open or closed</p>
</li>
<li><p><code>aria-controls</code> links the button to the dropdown content via its id</p>
</li>
<li><p>The <code>&lt;button&gt;</code> element acts as the trigger and is fully keyboard accessible</p>
</li>
<li><p>The <code>&lt;ul&gt;</code> and <code>&lt;li&gt;</code> elements provide a natural list structure</p>
</li>
<li><p>Using <code>&lt;a&gt;</code> elements ensures proper navigation behavior and accessibility</p>
</li>
</ul>
<p>Why this approach is correct:</p>
<ul>
<li><p>It follows standard web patterns instead of application-style menus</p>
</li>
<li><p>It avoids misusing ARIA roles like role="menu", which require complex keyboard handling</p>
</li>
<li><p>Screen readers can correctly interpret the structure without additional roles</p>
</li>
<li><p>It keeps the implementation simple, accessible, and maintainable</p>
</li>
</ul>
<p>If you need advanced menu behavior (like arrow key navigation), then ARIA menu roles may be appropriate –&nbsp;but only when fully implemented according to the ARIA Authoring Practices.</p>
<p>Note: Most dropdowns in web applications are not true "menus" in the ARIA sense. Avoid using role="menu" unless you are implementing full keyboard navigation (arrow keys, focus management, and so on).</p>
<h2 id="heading-keyboard-navigation">Keyboard Navigation</h2>
<p>Keyboard navigation ensures that users can fully interact with your application using only a keyboard, without relying on a mouse. This is essential for users with motor disabilities, but it also benefits power users and developers who prefer keyboard-based workflows.</p>
<p>In a well-designed interface, users should be able to:</p>
<ul>
<li><p>Navigate through interactive elements using the Tab key</p>
</li>
<li><p>Activate buttons and links using Enter or Space</p>
</li>
<li><p>Clearly see which element is currently focused</p>
</li>
</ul>
<p>In the example below, we’ll look at common mistakes in keyboard handling and why relying on native HTML elements is usually the better approach.</p>
<p><strong>Example:</strong></p>
<p>Avoid adding custom keyboard handlers to native elements like <code>&lt;button&gt;</code>, as they already support keyboard interaction by default.</p>
<p>For example, this is all you need:</p>
<pre><code class="language-html">&lt;button type="button" onClick={handleClick}&gt;Submit&lt;/button&gt;
</code></pre>
<p>This automatically supports:</p>
<ul>
<li><p>Enter and Space key activation</p>
</li>
<li><p>Focus management</p>
</li>
<li><p>Screen reader announcements</p>
</li>
</ul>
<p>Adding manual keyboard event handlers here is unnecessary and can introduce bugs or inconsistent behavior.</p>
<p><strong>What this example shows:</strong></p>
<p>Avoid manually handling keyboard events for native interactive elements like <code>&lt;button&gt;</code>. These elements already provide built-in keyboard support and accessibility features.</p>
<p>For example:</p>
<pre><code class="language-html">&lt;button type="button" onClick={handleClick}&gt;Submit&lt;/button&gt;
</code></pre>
<p>Why this works:</p>
<ul>
<li><p>Supports both Enter and Space key activation by default</p>
</li>
<li><p>Is focusable and participates in natural tab order</p>
</li>
<li><p>Provides built-in accessibility roles and screen reader announcements</p>
</li>
<li><p>Reduces the need for additional logic or ARIA attributes</p>
</li>
</ul>
<p>Adding custom keyboard handlers (like onKeyDown) to native elements is unnecessary and can introduce bugs or inconsistent behavior. Always prefer native HTML elements for interactivity whenever possible.</p>
<h3 id="heading-avoiding-common-keyboard-traps">Avoiding Common Keyboard Traps</h3>
<p>One of the most common keyboard accessibility issues is “trapping users inside interactive components”, such as modals or custom dropdowns. This happens when focus is moved into a component but can't escape using Tab, Shift+Tab, or other keyboard controls. Users relying on keyboards may become stuck, unable to navigate to other parts of the page.</p>
<p>In the example below, you'll see a simple modal that tries to set focus, but doesn’t manage Tab behavior properly.</p>
<pre><code class="language-javascript">function Modal({ isOpen }) {
  const ref = React.useRef();

  React.useEffect(() =&gt; {
    if (isOpen) ref.current?.focus();
  }, [isOpen]);

  return (
    &lt;div role="dialog"&gt;
      &lt;button type="button" ref={ref}&gt;Close&lt;/button&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p>What this code shows:</p>
<ul>
<li><p>When the modal opens, focus is moved to the Close button using <code>ref.current.focus()</code></p>
</li>
<li><p>The modal uses <code>role="dialog"</code> to communicate its purpose</p>
</li>
</ul>
<p>There are some issues with this code that you should be aware of. First, tabbing inside the modal may allow focus to move outside the modal if additional focusable elements exist.</p>
<p>Users may also become trapped if no mechanism returns focus to the triggering element when the modal closes.</p>
<p>There's also no handling of Shift+Tab or cycling focus is present.</p>
<p>This demonstrates a <strong>partial focus management</strong>, but it’s not fully accessible yet.</p>
<p>To improve focus management, you can trap focus within the modal by ensuring that Tab and Shift+Tab cycle only through elements inside the modal.</p>
<p>You can also return focus to the trigger: when the modal closes, return focus to the element that opened it.</p>
<p><strong>Example improvement (conceptual):</strong></p>
<pre><code class="language-javascript">function Modal({ isOpen, onClose, triggerRef }) {
  const modalRef = React.useRef();

  React.useEffect(() =&gt; {
    if (isOpen) {
      modalref.current?.focus();
      // Add focus trap logic here
    } else {
      triggerref.current?.focus();
    }
  }, [isOpen]);

  return (
    &lt;div role="dialog" ref={modalRef} tabIndex={-1}&gt;
      &lt;button type="button" onClick={onClose}&gt;Close&lt;/button&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p>Remember that this modal is not fully accessible without focus trapping. In production, use a library like <code>focus-trap-react</code>, <code>react-aria</code>, or Radix UI.</p>
<p><strong>Key points:</strong></p>
<ul>
<li><p><code>tabIndex={-1}</code> allows the div to receive programmatic focus</p>
</li>
<li><p>Focus trap ensures users cannot tab out unintentionally</p>
</li>
<li><p>Returning focus preserves context, so users can continue where they left off</p>
</li>
</ul>
<p><strong>Best practices:</strong></p>
<ul>
<li><p>Always move focus into modals</p>
</li>
<li><p>Return focus to the trigger element when closed</p>
</li>
<li><p>Ensure Tab cycles correctly</p>
</li>
</ul>
<p>As a general rule, always prefer native HTML elements for interactivity. Only implement custom keyboard handling when building advanced components that cannot be achieved with standard elements.</p>
<h2 id="heading-focus-management">Focus Management</h2>
<p>Focus management is the practice of controlling where keyboard focus goes when users interact with components such as modals, forms, or interactive widgets. Proper focus management ensures that:</p>
<ul>
<li><p>Users relying on keyboards or assistive technologies can navigate seamlessly</p>
</li>
<li><p>Focus does not get lost or trapped in unexpected places</p>
</li>
<li><p>Users maintain context when content updates dynamically</p>
</li>
</ul>
<p>The example below shows a common approach that only partially handles focus:</p>
<p><strong>Bad Example:</strong></p>
<pre><code class="language-javascript">// Bad Example: Automatically focusing input without context
const ref = React.useRef();
React.useEffect(() =&gt; {
  ref.current?.focus();
}, []);
&lt;input ref={ref} placeholder="Name" /&gt;
</code></pre>
<p>In the above code, the input receives focus as soon as the component mounts, but there’s no handling for returning focus when the user navigates away.</p>
<p>If this input is inside a modal or dynamic content, users may get lost or trapped. There aren't any focus indicators or context for assistive technologies.</p>
<p>This is a minimal solution that can cause confusion in real applications.</p>
<p><strong>Improved Example:</strong></p>
<pre><code class="language-javascript">// Improved Example: Managing focus in a modal context
function Modal({ isOpen, onClose, triggerRef }) {  
const dialogRef = React.useRef();

  React.useEffect(() =&gt; {
    if (isOpen) {
      dialogRef.current?.focus();
    } else if (triggerRef?.current) {
      triggerref.current?.focus();
    }
  }, [isOpen]);

  React.useEffect(() =&gt; {
    function handleKeyDown(e) {
      if (e.key === 'Escape') {
        onClose();
      }
    }

    if (isOpen) {
      document.addEventListener('keydown', handleKeyDown);
    }

    return () =&gt; {
      document.removeEventListener('keydown', handleKeyDown);
    };
  }, [isOpen, onClose]);

  if (!isOpen) return null;

  return (
    &lt;div
      role="dialog"
      aria-modal="true"
      aria-labelledby="modal-title"
      tabIndex={-1}
      ref={dialogRef}
    &gt;
      &lt;h2 id="modal-title"&gt;Modal Title&lt;/h2&gt;
      &lt;button type="button" onClick={onClose}&gt;Close&lt;/button&gt;
      &lt;input type="text" placeholder="Name" /&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p><strong>Explanation:</strong></p>
<ul>
<li><p><code>tabIndex={-1}</code> enables the dialog container to receive focus</p>
</li>
<li><p>Focus is moved to the modal when it opens, ensuring keyboard users start in the correct context</p>
</li>
<li><p>Focus is returned to the trigger element when the modal closes, preserving user flow</p>
</li>
<li><p><code>aria-labelledby</code> provides an accessible name for the dialog</p>
</li>
<li><p>Escape key handling allows users to close the modal without a mouse</p>
</li>
</ul>
<p>Note: For full accessibility, you should also implement focus trapping so users cannot tab outside the modal while it is open.</p>
<p>Tip: In production applications, use libraries like react-aria, focus-trap-react, or Radix UI to handle focus trapping and accessibility edge cases reliably.</p>
<p>Also, keep in mind here that the document-level keydown listener is global, which affects the entire page and can conflict with other components.</p>
<pre><code class="language-javascript">document.addEventListener('keydown', handleKeyDown);
</code></pre>
<p>A safer alternative is to scope it to the modal:</p>
<pre><code class="language-javascript">&lt;div
  onKeyDown={(e) =&gt; {
    if (e.key === 'Escape') onClose();
  }}
&gt;
</code></pre>
<p>For simple cases, attach <code>onKeyDown</code> to the dialog instead of the document.</p>
<h4 id="heading-best-practice">Best Practice:</h4>
<p>For complex components, use libraries like <code>focus-trap-react</code> or <code>react-aria</code> to manage focus reliably, especially for modals, dropdowns, and popovers.</p>
<h2 id="heading-forms-and-accessibility">Forms and Accessibility</h2>
<p>Forms are critical points of interaction in web applications, and proper accessibility ensures that all users – including those using screen readers or other assistive technologies – can understand and interact with them effectively.</p>
<p>Proper labeling means that every input field, checkbox, radio button, or select element has an associated label that clearly describes its purpose. This allows screen readers to announce the input meaningfully and helps keyboard-only users understand what information is expected.</p>
<p>In addition to labeling, form accessibility includes:</p>
<ul>
<li><p>Providing clear error messages when input is invalid</p>
</li>
<li><p>Ensuring error messages are announced to assistive technologies</p>
</li>
<li><p>Maintaining logical focus order so users can navigate inputs easily</p>
</li>
</ul>
<p><strong>Bad Example:</strong></p>
<pre><code class="language-html">&lt;input type="text" placeholder="Name" /&gt;
</code></pre>
<p>Why this isn't good:</p>
<ul>
<li><p>This input relies only on a placeholder for context</p>
</li>
<li><p>Screen readers may not announce the purpose of the field clearly</p>
</li>
<li><p>Once a user starts typing, the placeholder disappears, leaving no guidance</p>
</li>
<li><p>Keyboard-only users may not have enough context to know what to enter</p>
</li>
</ul>
<p><strong>Good Example:</strong></p>
<pre><code class="language-html">&lt;label htmlFor="name"&gt;Name&lt;/label&gt;
&lt;input id="name" type="text" /&gt;
</code></pre>
<p>Why this is better:</p>
<ul>
<li><p>The <code>&lt;label&gt;</code> is explicitly associated with the input via <code>htmlFor / id</code></p>
</li>
<li><p>Screen readers announce "Name" before the input, providing clear context</p>
</li>
<li><p>Users navigating with Tab understand the field’s purpose</p>
</li>
<li><p>The label persists even when the user types, unlike a placeholder</p>
</li>
</ul>
<p><strong>Error Handling:</strong></p>
<pre><code class="language-html">&lt;label htmlFor="name"&gt;Name&lt;/label&gt;
&lt;input
  id="name"
  type="text"
  aria-describedby="name-error"
  aria-invalid="true"
/&gt;

&lt;p id="name-error" role="alert"&gt;
  Name is required
&lt;/p&gt;
</code></pre>
<p><strong>Explanation</strong></p>
<ul>
<li><p><code>aria-describedby</code> links the input to the error message using the element’s id</p>
</li>
<li><p>Screen readers announce the error message when the input is focused</p>
</li>
<li><p><code>aria-invalid="true"</code> indicates that the field currently contains an error</p>
</li>
<li><p><code>role="alert"</code> ensures the error message is announced immediately when it appears</p>
</li>
</ul>
<p>This creates a clear relationship between the input and its validation message, improving usability for screen reader users.</p>
<p>Tip: Only apply aria-invalid and error messages when validation fails. Avoid marking fields as invalid before user interaction.</p>
<h2 id="heading-responsive-typography-and-images">Responsive Typography and Images</h2>
<p>Responsive typography and images ensure that your content remains readable and visually appealing across a wide range of devices, from small smartphones to large desktop monitors.</p>
<p>This is important, because text should scale naturally so it remains legible on all screens, and images should adjust to container sizes to avoid layout issues or overflow. Both contribute to a better user experience and accessibility</p>
<p>In this section, we’ll cover practical ways to implement responsive typography and images in React and CSS.</p>
<pre><code class="language-css">h1 {
  font-size: clamp(1.5rem, 2vw, 3rem);
}
</code></pre>
<p>In this code:</p>
<ul>
<li><p>The <code>clamp()</code> function allows text to scale fluidly:</p>
</li>
<li><p>The first value (1.5rem) is the “minimum font size”</p>
</li>
<li><p>The second value (2vw) is the “preferred size based on viewport width”</p>
</li>
<li><p>The third value (3rem) is the “maximum font size”</p>
</li>
<li><p>This ensures headings are “readable on small screens” without becoming too large on desktops</p>
</li>
</ul>
<p>Alternative methods include using <code>media queries</code> to adjust font sizes at different breakpoints</p>
<p><strong>Responsive Images:</strong></p>
<pre><code class="language-html">&lt;img src="image.jpg" alt="Description" loading="lazy" /&gt;
</code></pre>
<p>In this code, responsive images adapt to different screen sizes and resolutions to prevent layout issues or slow loading times. Key techniques include:</p>
<h3 id="heading-1-fluid-images-using-css">1. Fluid images using CSS:</h3>
<pre><code class="language-css">img {
     max-width: 100%;
     height: auto;
   }
</code></pre>
<p>This makes sure that images never overflow their container and maintains aspect ratio automatically.</p>
<h3 id="heading-2-using-srcset-for-multiple-resolutions">2. Using <code>srcset</code> for multiple resolutions:</h3>
<pre><code class="language-html">&lt;img src="image-small.jpg"
     srcset="image-small.jpg 480w,
             image-medium.jpg 1024w,
             image-large.jpg 1920w"
     sizes="(max-width: 600px) 480px,
            (max-width: 1200px) 1024px,
            1920px"
     alt="Description"&gt;
</code></pre>
<p>This provides different image files depending on screen size or resolution and reduces loading times and improves performance on smaller devices.</p>
<h3 id="heading-3-always-include-descriptive-alt-text">3. Always include descriptive alt text</h3>
<p>This is critical for screen readers and accessibility. It also helps users understand the image if it cannot be loaded.</p>
<p>Tip: Combine responsive typography, images, and flexible layout containers (like CSS Grid or Flexbox) to create interfaces that scale gracefully across all devices and maintain accessibility.</p>
<h3 id="heading-4-ensure-sufficient-color-contrast">4. Ensure Sufficient Color Contrast</h3>
<p>Low contrast text can make content unreadable for many users.</p>
<pre><code class="language-css">.bad-text {
  color: #aaa;
}

.good-text {
  color: #222;
}
</code></pre>
<p>Use tools like WebAIM Contrast Checker and Chrome DevTools Accessibility panel to check your color contrasts. Also note that WCAG AA requires 4.5:1 contrast ratio for normal text.</p>
<h2 id="heading-building-a-fully-accessible-responsive-component-end-to-end-example">Building a Fully Accessible Responsive Component (End-to-End Example)</h2>
<p>To understand how responsiveness and accessibility work together in practice, let’s build a reusable accessible card component that adapts to screen size and supports keyboard and screen reader users.</p>
<h3 id="heading-step-1-component-structure-semantic-html">Step 1: Component Structure (Semantic HTML)</h3>
<pre><code class="language-javascript">function ProductCard({ title, description, onAction }) {
  return (
    &lt;article className="card"&gt;
      &lt;h3&gt;{title}&lt;/h3&gt;
      &lt;p&gt;{description}&lt;/p&gt;
      &lt;button type="button" onClick={onAction}&gt;
        View Details
      &lt;/button&gt;
    &lt;/article&gt;
  );
}
</code></pre>
<p><strong>Why This Works</strong></p>
<ul>
<li><p><code>&lt;article&gt;</code> provides semantic meaning for standalone content</p>
</li>
<li><p><code>&lt;h3&gt;</code> establishes a proper heading hierarchy</p>
</li>
<li><p><code>&lt;button&gt;</code> ensures built-in keyboard and accessibility support</p>
</li>
</ul>
<h3 id="heading-step-2-responsive-styling">Step 2: Responsive Styling</h3>
<pre><code class="language-css">.card {
  padding: 16px;
  border: 1px solid #ddd;
  border-radius: 8px;
}

@media (min-width: 768px) {
  .card {
    padding: 24px;
  }
}
</code></pre>
<p>This ensures comfortable spacing on mobile and improved readability on larger screens.</p>
<h3 id="heading-step-3-accessibility-enhancements">Step 3: Accessibility Enhancements</h3>
<pre><code class="language-html">&lt;button type="button" onClick={onAction}&gt;
  View Details
&lt;/button&gt;
</code></pre>
<p>The visible button text provides a clear and accessible label, so no additional ARIA attributes are needed.</p>
<h3 id="heading-step-4-keyboard-focus-styling">Step 4: Keyboard Focus Styling</h3>
<pre><code class="language-css">button:focus {
  outline: 2px solid blue;
  outline-offset: 2px;
}
</code></pre>
<p>Focus indicators are essential for keyboard users.</p>
<h3 id="heading-step-5-using-the-component">Step 5: Using the Component</h3>
<pre><code class="language-javascript">function App() {
  return (
    &lt;div className="grid"&gt;
      &lt;ProductCard
        title="Product 1"
        description="Accessible and responsive"
        onAction={() =&gt; alert('Clicked')}
      /&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p><strong>Key Takeaways</strong></p>
<p>This simple component demonstrates:</p>
<ul>
<li><p>Semantic HTML structure</p>
</li>
<li><p>Responsive design</p>
</li>
<li><p>Built-in accessibility via native elements</p>
</li>
<li><p>Minimal ARIA usage</p>
</li>
</ul>
<p>In real-world applications, this pattern scales into entire design systems.</p>
<h2 id="heading-testing-accessibility">Testing Accessibility</h2>
<p>Accessibility should be validated continuously, not just at the end of development. There are various automated tools you can use to help you with this process:</p>
<ul>
<li><p>Lighthouse (built into Chrome DevTools)</p>
</li>
<li><p>axe DevTools for detailed audits</p>
</li>
<li><p>ESLint plugins for accessibility rules</p>
</li>
</ul>
<h3 id="heading-manual-testing">Manual Testing</h3>
<p>But automated tools cannot catch everything. Manual testing is essential to make sure users can navigate using only the keyboard and use a screen reader (NVDA or VoiceOver. You should also test zoom levels (up to 200%) and check the color contrast manually.</p>
<p><strong>Example: ESLint Accessibility Plugin</strong></p>
<pre><code class="language-shell">npm install eslint-plugin-jsx-a11y --save-dev
</code></pre>
<p>This helps catch accessibility issues during development.</p>
<h2 id="heading-best-practices">Best Practices</h2>
<ul>
<li><p>Use semantic HTML first</p>
</li>
<li><p>Avoid unnecessary ARIA</p>
</li>
<li><p>Test keyboard navigation</p>
</li>
<li><p>Design mobile-first</p>
</li>
<li><p>Ensure color contrast</p>
</li>
<li><p>Use consistent spacing</p>
</li>
</ul>
<h2 id="heading-when-not-to-overuse-accessibility-features">When NOT to Overuse Accessibility Features</h2>
<ul>
<li><p>Avoid adding ARIA when native HTML works</p>
</li>
<li><p>Do not override browser defaults unnecessarily</p>
</li>
<li><p>Avoid complex custom components without accessibility support</p>
</li>
</ul>
<h2 id="heading-future-enhancements">Future Enhancements</h2>
<ul>
<li><p>Design systems with accessibility built-in</p>
</li>
<li><p>Automated accessibility testing in CI/CD</p>
</li>
<li><p>Advanced focus management libraries</p>
</li>
<li><p>Accessibility-first component libraries</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Building responsive and accessible React applications is not a one-time effort—it is a continuous design and engineering practice. Instead of treating accessibility as a checklist, developers should integrate it into the core of their component design process.</p>
<p>If you are starting out, focus on using semantic HTML and mobile-first layouts. These two practices alone solve a large percentage of accessibility and responsiveness issues. As your application grows, introduce ARIA enhancements, keyboard navigation, and automated accessibility testing.</p>
<p>The key is to build interfaces that work for everyone by default. When responsiveness and accessibility are treated as first-class concerns, your React applications become more usable, scalable, and future-proof.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ freeCodeCamp's New Responsive Web Design Certification is Now Live ]]>
                </title>
                <description>
                    <![CDATA[ The freeCodeCamp community just published our new Responsive Web Design certification. You can now sit for the exam to earn the free verified certification, which you can add to your résumé, CV, or LinkedIn profile. Each certification is filled with ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/freecodecamps-new-responsive-web-design-certification-is-now-live/</link>
                <guid isPermaLink="false">692f044a17ed56d5a1781fb1</guid>
                
                    <category>
                        <![CDATA[ freeCodeCamp.org ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Responsive Web Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Certification ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jessica Wilkins ]]>
                </dc:creator>
                <pubDate>Tue, 02 Dec 2025 15:22:50 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1763760123080/749604bf-3620-40ad-bd5f-488bd8faa251.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The freeCodeCamp community just published our new <a target="_blank" href="https://www.freecodecamp.org/learn/responsive-web-design-v9/">Responsive Web Design certification</a>. You can now sit for the exam to earn the free verified certification, which you can add to your résumé, CV, or LinkedIn profile.</p>
<p>Each certification is filled with hundreds of hours worth of interactive lessons, workshops, labs, and quizzes.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763400265601/61789182-1638-47a1-b0c4-3a6113bc657c.png" alt="List of HTML modules in the new Responsive Web Design certification" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-does-the-new-rwd-certification-work">How Does the New RWD Certification Work?</h2>
<p>The Responsive Web Design certification will teach you core concepts including semantic HTML, working with forms, the importance of accessibility, CSS Flexbox, responsive design, CSS Grid, and more.</p>
<p>The certification is broken down into several modules that include lessons, workshops, labs, review pages and quizzes to ensure that you truly understand the material before moving onto the next module.</p>
<p>The lessons are your first exposure to new concepts. They provide crucial theory and context for how things work in the software development industry.</p>
<p>These lessons include our new interactive editor so you can see previews of the code. You can also play around with the examples for deeper understanding and comprehension.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763400733720/9e5e1406-5b2d-448b-a69f-2f0330627516.png" alt="Example of using the interactive editor to explain how linear gradients works." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>At the end of each lesson, there will be three comprehension check questions to test your understanding of the material from the lesson.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763400413902/e2ebeb1b-977d-4db1-a608-1bcce571d03b.png" alt="Example question from the working with forms quiz in the Responsive Web Design certification" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>After these lessons, you’ll head over to the workshops. These workshops are guided step-based projects that provide you with an opportunity to practice what you have learned in the lessons.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763400520984/630b4928-7023-4b0a-b86e-a69794f1d687.png" alt="Example step from the Build a City Skyline workshop" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>After the workshops, you’ll complete a lab which will help you review what you have learned so far. This will give you the chance to start building projects on your own, which is a crucial skill for a developer. You’ll be presented with a list of user stories and will need to pass the tests to complete the lab.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763401095507/5ac9ba2e-5efe-4de0-b71a-6d6f06eade71.png" alt="Example user stories from the Build a Product Landing Page lab" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>At the end of each module, there is a review page containing a list of all of the concepts covered. You can use these review pages to help you study for the quizzes.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763401166897/a3d050d4-1e84-46c8-aa9e-9d5ef4f7eb46.png" alt="Portion of the review content from the CSS attribute selectors review page" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>The last portion of the module is the quiz. This is a 20 question multiple choice quiz designed to test your understanding from the material covered in the module. You’ll need to get 18 out of 20 correct to pass.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763401270586/0b6f5c74-bf29-4103-ade7-6c872ca3a043.png" alt="Example question from the CSS Grid Quiz" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Throughout the certification, there will be five certification projects you’ll need to complete in order to qualify for the exam.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763401326863/5b35b3d3-7e15-427a-b37c-023b3b259648.png" alt="[Alt Text: List of HTML certification projects in the new Responsive Web Design certification]" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Once you’ve completed all 5 certification projects, you’ll be able to take the 50 question exam using our new open source exam environment. The freeCodeCamp community designed this exam environment tool with two goals: respecting your privacy while also making it harder for people to cheat.</p>
<p>Once you download the app to your laptop or desktop, you can take the exam.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762447991874/674b982c-0f3d-4e93-ab11-13bba384f52e.png" alt="Screenshot from the Responsive Web Design Certification Exam page" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h1 id="heading-frequently-asked-questions">Frequently Asked Questions</h1>
<h2 id="heading-is-all-of-this-really-free">Is all of this really free?</h2>
<p>Yes. freeCodeCamp has always been free, and we’ve now offered free verified certifications for more than a decade. These exams are just the latest expansion to our community’s free learning resources.</p>
<h2 id="heading-what-prevents-people-from-just-cheating-on-the-exams">What prevents people from just cheating on the exams?</h2>
<p>Our goal is to strike a balance between preventing cheating and respecting people's right to privacy.</p>
<p>We've implemented a number of reliable, yet non-invasive, measures to help prevent people from cheating on freeCodeCamp's exams:</p>
<ol>
<li><p>For each exam, we have a massive bank of questions and potential answers to those questions. Each time a person attempts an exam, they'll see only a small, randomized sampling of these questions.</p>
</li>
<li><p>We only allow people to attempt an exam one time per week. This reduces their ability to "brute force" the exam.</p>
</li>
<li><p>We have security in place to validate exam submissions and prevent man-in-the-middle attacks or manipulation of the exam environment.</p>
</li>
<li><p>We manually review each passing exam for evidence of cheating. Our exam environment produces tons of metrics for us to draw from.</p>
</li>
</ol>
<p>We take cheating, and any form of academic dishonesty, seriously. We will act decisively.</p>
<p>This said, no one's exam results will be thrown out without human review, and no one's account will be banned without warning based on a single suspicious exam result.</p>
<h2 id="heading-are-these-exams-open-book-or-closed-book">Are these exams “open book” or “closed book”?</h2>
<p>All of freeCodeCamp’s exams are “closed book”, meaning you must rely only on your mind and not outside resources.</p>
<p>Of course, in the real world you’ll be able to look things up. And in the real world, we encourage you to do so.</p>
<p>But that is not what these exams are evaluating. These exams are instead designed to test your memory of details and your comprehension of concepts.</p>
<p>So when taking these exams, do not use outside assistance in the form of books, notes, AI tools, or other people. Use of any of these will be considered academic dishonesty.</p>
<h2 id="heading-do-you-record-my-webcam-microphone-or-require-me-to-upload-a-photo-of-my-personal-id">Do you record my webcam, microphone, or require me to upload a photo of my personal ID?</h2>
<p>No. We considered adding these as additional test-taking security measures. But we have less privacy-invading methods of detecting most forms of academic dishonesty.</p>
<h2 id="heading-if-the-environment-is-open-source-doesnt-that-make-it-less-secure">If the environment is open source, doesn't that make it less secure?</h2>
<p>"Given enough eyeballs, all bugs are shallow." – Linus’s Law, formulated by Eric S. Raymond in his book <em>The Cathedral and the Bazaar</em></p>
<p>Open source software projects are often more secure than their closed source equivalents. This is because a lot more people are scrutinizing the code. And a lot more people can potentially help identify bugs and other deficiencies, then fix them.</p>
<p>We feel confident that open source is the way to go for this exam environment system.</p>
<h2 id="heading-how-can-i-contribute-to-the-exam-environment-codebase">How can I contribute to the Exam Environment codebase?</h2>
<p>It's fully open source, and we'd welcome your code contributions. Please read our general <a target="_blank" href="https://contribute.freecodecamp.org/intro/">contributor onboarding documentation</a>.</p>
<p>Then check out the <a target="_blank" href="https://github.com/freeCodeCamp/exam-env">GitHub repo</a>.</p>
<p>You can help by creating issues to report bugs or request features.</p>
<p>You can also browse open <code>help wanted</code> issues and attempt to open pull requests addressing them.</p>
<h2 id="heading-are-the-exam-questions-themselves-open-source">Are the exam questions themselves open source?</h2>
<p>For obvious exam security reasons, the exam question banks themselves are not publicly accessible. :)</p>
<p>These are built and maintained by freeCodeCamp's staff instructional designers.</p>
<h2 id="heading-what-happens-if-i-have-internet-connectivity-issues-mid-exam">What happens if I have internet connectivity issues mid-exam?</h2>
<p>If you have internet connectivity issues mid exam, the next time you try submit an answer, you’ll be told there are connectivity issues. The system will keep prompting you to retry submitting until the connection succeeds.</p>
<h2 id="heading-what-if-my-computer-crashes-mid-exam">What if my computer crashes mid-exam?</h2>
<p>If your computer crashes mid exam, you’ll be able to re-open the Exam Environment. Then, if you still have time left for your exam attempt, you’ll be able to continue from where you left off.</p>
<h2 id="heading-can-i-take-exams-in-languages-other-than-english">Can I take exams in languages other than English?</h2>
<p>Not yet. We’re working to add multi-lingual support in the future.</p>
<h2 id="heading-i-have-completed-my-exam-why-cant-i-see-my-results-yet">I have completed my exam. Why can't I see my results yet?</h2>
<p>All exam attempts are reviewed by freeCodeCamp staff before we release the results. We do this to ensure the integrity of the exam process and to prevent cheating. Once your attempt has been reviewed, you'll be notified of your results the next time you log in to freeCodeCamp.org.</p>
<h2 id="heading-i-am-deaf-or-hard-of-hearing-can-i-still-take-the-exams">I am Deaf or hard of hearing. Can I still take the exams?</h2>
<p>Yes! While some exams may include audio components, we do make written transcripts available for reading.</p>
<h2 id="heading-i-am-blind-or-have-limited-vision-and-use-a-screen-reader-can-i-still-take-the-exams">I am blind or have limited vision, and use a screen reader. Can I still take the exams?</h2>
<p>We’re working on it. Our curriculum is fully screen reader accessible. We're still refining our screen reader usability for the Exam Environment app. This is a high priority for us.</p>
<h2 id="heading-i-use-a-keyboard-instead-of-a-mouse-can-i-navigate-the-exams-using-just-a-keyboard">I use a keyboard instead of a mouse. Can I navigate the exams using just a keyboard?</h2>
<p>This is a high priority for us. We hope to add keyboard navigation to the Exam Environment app soon.</p>
<h2 id="heading-are-exams-timed">Are exams timed?</h2>
<p>Yes, exams are timed. We err on the side of giving plenty of time to take the exam, to account for people who are non-native English speakers, or who have ADHD and other learning differences that can make timed exams more challenging.</p>
<p>If you have a condition that usually qualifies you for extra time on standardized exams, please email support@freecodecamp.org. We’ll review your request and see whether we can find a reasonable solution.</p>
<h2 id="heading-what-happens-if-i-fail-the-exam-can-i-retake-it">What happens if I fail the exam? Can I retake it?</h2>
<p>Yes. You get one exam attempt per week. After you attempt an exam, there is a one-week (exactly 168 hour) “cool-down” period where you cannot take any freeCodeCamp exams. This is to encourage you to study and to pace yourself.</p>
<p>There is no limit to the number of times you can take an exam. So if you fail, study more, practice your skills more, then try again the following week.</p>
<h2 id="heading-do-i-need-to-redo-the-projects-if-i-fail-the-exam">Do I need to redo the projects if I fail the exam?</h2>
<p>No. Once you’ve submitted a certification project, you do not need to ever submit it again.</p>
<p>You can re-do projects for practice, but we recommend that you instead build some of our many practice projects in freeCodeCamp’s developer interview job search section.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764629117812/35c0c09a-3131-4c01-8b97-d5c101912f9e.png" alt="A screenshot of the &quot;Prepare for the developer interview job search&quot; section with lots of coding projects" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-what-happens-if-i-already-have-the-old-legacy-responsive-web-design-certification-should-i-claim-the-new-one">What happens if I already have the old Legacy Responsive Web Design certification? Should I claim the new one?</h2>
<p>The new certification has more theory and practice as well as an exam. So if you’re looking to brush up on your skills, then you can go through the new version of this certification.</p>
<h2 id="heading-what-will-happen-to-my-existing-coursework-progress-on-the-full-stack-certification-does-it-transfer-over-to-the-responsive-web-design-course">What will happen to my existing coursework progress on the Full Stack Certification? Does it transfer over to the Responsive Web Design course?</h2>
<p>If you’ve already started the <a target="_blank" href="https://www.freecodecamp.org/learn/full-stack-developer-v9/">Certified Full Stack Developer Curriculum</a>, all of your previously completed work should already be saved there.</p>
<p>To be clear, we’ve copied over all of the coursework from the full stack certification to this newer certification.</p>
<h2 id="heading-can-i-still-continue-with-the-current-full-stack-developer-certification-and-just-not-do-the-new-certification">Can I still continue with the current Full Stack Developer Certification and just not do the new certification?</h2>
<p>We’ve moved the coursework for the <a target="_blank" href="https://www.freecodecamp.org/learn/full-stack-developer-v9/">Full Stack Developer Certification</a> over and broken it up into smaller certifications. Currently there are seven courses available for you to go through. Here is the complete list:</p>
<ul>
<li><p><a target="_blank" href="https://www.freecodecamp.org/learn/responsive-web-design-v9/">Responsive Web Design Certification</a></p>
</li>
<li><p><a target="_blank" href="https://www.freecodecamp.org/learn/javascript-v9/">JavaScript Certification</a></p>
</li>
<li><p><a target="_blank" href="https://www.freecodecamp.org/learn/front-end-development-libraries-v9/">Frontend Libraries Certification</a></p>
</li>
<li><p><a target="_blank" href="https://www.freecodecamp.org/learn/python-v9/">Python Certification</a></p>
</li>
<li><p><a target="_blank" href="https://www.freecodecamp.org/learn/relational-databases-v9/">Relational Databases Certification</a></p>
</li>
<li><p><a target="_blank" href="https://www.freecodecamp.org/learn/back-end-development-and-apis-v9/">Backend JavaScript Certification</a></p>
</li>
<li><p><a target="_blank" href="https://www.freecodecamp.org/learn/full-stack-developer-v9/">Certified Full Stack Developer Certification</a></p>
</li>
</ul>
<p>The Certified Full Stack Developer Certification button will remain on the learn page for a short time to give people the opportunity to switch over to the new certifications. Over the next few months, though, this option will disappear.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763050732251/0276ffab-bd3f-46fe-bac0-a654ddfafcb5.png" alt="List of all certifications on the freeCodeCamp learn page." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-will-my-legacy-certifications-become-invalid">Will my legacy certifications become invalid?</h2>
<p>No. Once you claim a certification, it’s yours to keep.</p>
<p>Also note that we previously announced that freeCodeCamp certifications would have an expiration date and require recertification. We don’t plan to implement this anytime soon. And if we do decide to, we will give everyone at least a year’s notice.</p>
<h2 id="heading-will-the-exam-be-available-to-take-on-my-phone">Will the exam be available to take on my phone?</h2>
<p>At this time, no. You’ll need to use a laptop or desktop to download the exam environment and take the exam. We hope to eventually offer these certification exams on iPhone and Android.</p>
<h2 id="heading-i-have-a-disability-or-health-condition-that-is-not-covered-here-how-can-i-request-accommodations"><strong>I have a disability or health condition that is not covered here. How can I request accommodations?</strong></h2>
<p>If you need specific accommodations for the exam (for example extra time, breaks, or alternative formats), please email support@freecodecamp.org. We’ll review your request and see whether we can find a reasonable solution.</p>
<h2 id="heading-anything-else">Anything else?</h2>
<p>Good luck working through freeCodeCamp’s coursework, building projects, and preparing for these exams.</p>
<p>Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use the CSS text-wrap Property to Create Balanced Text Layouts on Your Websites ]]>
                </title>
                <description>
                    <![CDATA[ An inconsistent text layout can really ruin the look of your website’s design. Maybe a heading has an extra word that wraps to another line, or in a paragraph some lines are longer than others. This can leave the whole thing looking messy and hard to... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-css-text-wrap-property/</link>
                <guid isPermaLink="false">67fd1442fd23722b0a451053</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Responsive Web Design ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Azubuike Duru ]]>
                </dc:creator>
                <pubDate>Mon, 14 Apr 2025 13:57:22 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1744638131989/38357168-abda-4f7b-8c4f-568f64b586df.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>An inconsistent text layout can really ruin the look of your website’s design. Maybe a heading has an extra word that wraps to another line, or in a paragraph some lines are longer than others. This can leave the whole thing looking messy and hard to read.</p>
<p>Before now, developers used tags like <code>&lt;br&gt;</code> or <code>&lt;span&gt;</code> to manually adjust word spacing. But what happens in cases where you also need to consider the responsiveness of the website? Well, the new <code>text-wrap: balance</code> property in CSS can now automatically calculate and divide the lines in such a way that every word looks organized and even. Like this:</p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4C8BE890CB3AB8AD50C286E15DBA884FF164212E142B1E75C767C0221DB183E7_1743742346617_Desktop+-+1-3.png" alt="Heading before and after applying 'text-wrap: balance' for improved wrapping." width="600" height="400" loading="lazy"></p>
<p>In this article, you’ll learn how the <code>text-wrap</code> property works and how to use it in your code. You’ll also see a few examples along the way.</p>
<p>Without wasting time, let's get right into it.</p>
<h3 id="heading-table-of-contents">Table of Contents</h3>
<ul>
<li><p><a class="post-section-overview" href="#heading-understanding-the-problems">Understanding the Problems</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-introducing-text-wrap">Introducing text-wrap</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-text-wrap">What is text-wrap?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-basic-syntax-of-text-wrap">Basic Syntax of text-wrap</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-text-wrap-vs-max-width-when-to-use-each">text-wrap vs. max-width : When to Use Each</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-when-to-use-max-width-vs-text-wrap">When to Use max-width vs text-wrap</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-browser-support-and-considerations">Browser Support and Considerations</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-practical-implementation-step-by-step-guide">Practical Implementation: Step-by-Step Guide</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-understanding-the-problems">Understanding the Problems</h2>
<p>Apart from making words harder to read when your text is unevenly displayed, there are other issues uneven or poorly displayed text can cause on your website as a whole. Some of these are:</p>
<ul>
<li><p><strong>Responsive Design</strong>: We wouldn't have any issues if we could manually design for every screen size and carefully place and space the lines of our text exactly as we wanted users to read them. Unfortunately, we can't do this, which is why making designs responsive is always crucial. When text adjusts from one screen size to another, lines break, and what looks good on a desktop may look terrible on a tablet view.</p>
</li>
<li><p><strong>Headings and Short Paragraphs</strong>: Since paragraphs and small blocks of text have many words, there is a high probability of words ending in a very unbalanced way. Often, we see a heading line ending with just one word, forming an awkward shape in the overall design.</p>
</li>
<li><p><strong>Dynamic Content</strong>: If your website contains dynamic content (such as cards of various sizes, product descriptions, or blog posts), having no <code>text-wrap</code> might make your layout break or appear unpredictable.</p>
</li>
</ul>
<h2 id="heading-introducing-text-wrap">Introducing <code>text-wrap</code></h2>
<p>In the last section, we looked at the problems attributed to uneven text distribution. In this section, you’ll see how <code>text-wrap</code> is a game changer in how you organize your text.</p>
<p>Before <code>text-wrap</code>, developers relied heavily on <code>max-width</code>, <code>text-align</code>, or <code>&lt;br&gt;</code> to control text lines. The new <code>text-wrap</code> CSS property was created to help break text naturally across lines without making it look out of place, preventing the need for trial and error in checking if text fits.</p>
<h3 id="heading-what-is-text-wrap">What is <code>text-wrap</code>?</h3>
<p><code>text-wrap</code> is a CSS property that can help you adjust and space text automatically, break lines evenly without using the rigid <code>&lt;br&gt;</code> tag, and not have to rely on <code>text-align</code>, which didn't work on all screen sizes.</p>
<p>With <code>text-wrap</code>, your headings and paragraphs are sure to look good. Instead of having some lines that look longer than others, <code>text-wrap</code> neatly arranges everything to appear visually appealing.</p>
<h3 id="heading-basic-syntax-of-text-wrap">Basic Syntax of <code>text-wrap</code></h3>
<p>There are two major ways to apply text-wrap to your text. These values are:</p>
<p><code>text-wrap: balance</code><strong>: (The Smart Heading Balancer)</strong></p>
<p>This is the smart way of telling the browser to adjust the text evenly, regardless of the screen size.</p>
<p>Code snippet:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">h1</span> {
  <span class="hljs-attribute">text-wrap</span>: balance;
}
</code></pre>
<p>In this code, the heading text lines will split naturally without any weird short lines.</p>
<p><code>text-wrap: pretty;</code> <strong>(The Smart Paragraph Balancer)</strong></p>
<p>Just as <code>text-wrap: balance</code> works best for headings, <code>text-wrap: pretty</code> is the best for styling long paragraphs.</p>
<p>Code snippet:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">p</span>{
  <span class="hljs-attribute">text-wrap</span>: pretty;
}
</code></pre>
<p>The <code>p</code> in this code will make sure the paragraphs maintain natural readability.</p>
<p><strong>Other values include:</strong></p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Value</strong></td><td><strong>Description</strong></td></tr>
</thead>
<tbody>
<tr>
<td><code>wrap</code></td><td>Default state</td></tr>
<tr>
<td><code>nowrap</code></td><td>Prevents text from wrapping to the next line</td></tr>
<tr>
<td><code>stable</code></td><td>Ensures things are kept in place until the content changes itself</td></tr>
</tbody>
</table>
</div><h2 id="heading-text-wrap-vs-max-width-when-to-use-each"><code>text-wrap</code> vs. <code>max-width</code> : When to Use Each</h2>
<p><code>max-width</code> was always the go-to option for developers in the past. While this method works in most cases, it won’t stop uneven text distribution. Let's compare it with the new <code>text-wrap</code> CSS property so you can know when to use each one.</p>
<p><strong>Using</strong> <code>max-width</code>:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">h1</span> {
  <span class="hljs-attribute">max-width</span>: <span class="hljs-number">400px</span>;
}
</code></pre>
<p>The <code>max-width</code> here forces the heading not to exceed a 400px width. This can be good for controlling short body paragraphs but can cause unevenness for headings when dealing with multiple screen sizes.</p>
<p><strong>Using</strong> <code>text-wrap</code>:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">h1</span> {
  <span class="hljs-attribute">text-wrap</span>: balance;
}
</code></pre>
<p>Here, the browser dynamically breaks the heading text in a balanced way, preventing any weird-looking single lines.</p>
<h3 id="heading-when-to-use-max-width-vs-text-wrap">When to Use <code>max-width</code> vs <code>text-wrap</code></h3>
<p>Use <code>text-wrap: balance</code> when you want a more natural text read without any weird line breaks.</p>
<p>Use <code>max-width</code> when you need to control the text width and don't necessarily care how the lines break.</p>
<p>Use both if you want a more natural read within a confined width limit.</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">h1</span> {
  <span class="hljs-attribute">max-width</span>: <span class="hljs-number">500px</span>;
  <span class="hljs-attribute">text-wrap</span>: balance;
}
</code></pre>
<p>This ensures the heading stays within a 500px limit while maintaining an even text distribution.</p>
<h3 id="heading-browser-support-and-considerations">Browser Support and Considerations</h3>
<p>Currently, Chrome and Edge are the only main browsers that support the new <code>text-wrap</code> property. If you are building a project that should work on browsers like Safari and Firefox, you will need to use traditional text formatting methods like <code>text-align</code>, <code>&lt;br&gt;</code>, or <code>max-width</code> instead.</p>
<p>Fallback snippet:</p>
<pre><code class="lang-css"><span class="hljs-keyword">@supports</span> (<span class="hljs-attribute">text-wrap:</span> balance) {
  <span class="hljs-selector-tag">h1</span> {
    <span class="hljs-attribute">text-wrap</span>: balance;
  }
}
</code></pre>
<p>The <code>@support</code> is a pro tip to apply this style to only supported browsers.</p>
<h2 id="heading-practical-implementation-step-by-step-guide">Practical Implementation: Step-by-Step Guide</h2>
<p>Now that you’ve seen how important <code>text-wrap</code> can be and how to use it, let’s put that knowledge into practise and see real examples, compare the before and after screens of using it (and not), and check how it reacts in responsive designs as well.</p>
<h3 id="heading-1-applying-text-wrap-balance-to-headings">1. Applying <code>text-wrap: balance</code> to Headings</h3>
<p>In this section, we will see how the heading lines in the topic <strong>"How to Use CSS Text Balance: A Simple Trick for Smoother, Cleaner Designs"</strong> will break across different sizes and how it looks when <code>text-wrap: balance</code> is applied.</p>
<p><strong>Without</strong> <code>text-wrap: balance</code>:</p>
<p>HTML</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"title"</span>&gt;</span>How to Use CSS Text Balance: A Simple Trick for Smoother, Cleaner Designs<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
</code></pre>
<p>CSS</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.title</span> {
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">2.5rem</span>;
  <span class="hljs-attribute">font-weight</span>: bold;
}
</code></pre>
<p>Without any special application to the headings, it will just adjust freely.</p>
<p>Result:</p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4C8BE890CB3AB8AD50C286E15DBA884FF164212E142B1E75C767C0221DB183E7_1743740541468_Screenshot+2025-04-04+at+5.21.36AM+1.png" alt="Heading without 'text-wrap: balance', showing uneven wrapping." width="600" height="400" loading="lazy"></p>
<p><strong>With</strong> <code>text-wrap: balance</code>:</p>
<p>CSS</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.title</span> {
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">2.5rem</span>;
  <span class="hljs-attribute">font-weight</span>: bold;
  <span class="hljs-attribute">text-wrap</span>: balance;
}
</code></pre>
<p>Now, the browser automatically adjusts the line breaks to ensure a more even distribution.</p>
<p>Result:</p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4C8BE890CB3AB8AD50C286E15DBA884FF164212E142B1E75C767C0221DB183E7_1743740708025_Screenshot+2025-04-04+at+5.24.26AM.png" alt="Heading with 'text-wrap: balance', showing smart readable behavior and wrapping" width="600" height="400" loading="lazy"></p>
<h3 id="heading-2-using-text-wrap-pretty-on-short-paragraphs">2. Using <code>text-wrap: pretty</code> on Short Paragraphs</h3>
<p>You’ve now seen how <code>text-wrap: balance</code> handles headings, so lets also take a look at how it breaks the lines evenly in your text paragraphs. As I mentioned above, the value <code>pretty</code> is mostly used for paragraphs or short block of words. Here’s how it works and appears on a block of text.</p>
<p><strong>Without</strong> <code>text-wrap: pretty</code>:</p>
<p>HTML</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"subText"</span>&gt;</span> Do you know that inconsistent text layout can ruin the look of your website design? Maybe a heading has an extra word that takes up another line or in a paragraph some lines are longer than others whereby leaving the whole thing looking messed up and hard to read.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<p>CSS</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.subText</span> {
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1.2rem</span>;
  <span class="hljs-attribute">line-height</span>: <span class="hljs-number">1.5</span>;
}
</code></pre>
<p>In this code, text adjustment will behave normally without any smart contraints.</p>
<p>Result:</p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4C8BE890CB3AB8AD50C286E15DBA884FF164212E142B1E75C767C0221DB183E7_1743739991569_Screenshot+2025-04-04+at+5.11.08AM.png" alt="Paragraph without 'text-wrap: pretty', showing uneven wrapping." width="600" height="400" loading="lazy"></p>
<p><strong>With</strong> <code>text-wrap: pretty</code>:</p>
<p>CSS</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.subText</span> {
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1.2rem</span>;
  <span class="hljs-attribute">line-height</span>: <span class="hljs-number">1.5</span>;
  <span class="hljs-attribute">text-wrap</span>: pretty;
}
</code></pre>
<p>The code above makes the line breaks evenly in a way that it will be easier for someone to read through.</p>
<p>Result:</p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4C8BE890CB3AB8AD50C286E15DBA884FF164212E142B1E75C767C0221DB183E7_1743739834917_Screenshot+2025-04-04+at+5.09.49AM.png" alt="Paragraph with 'text-wrap: pretty', showing smart readable behavior and wrapping" width="600" height="400" loading="lazy"></p>
<h3 id="heading-how-text-wrap-works-in-responsive-design">How <code>text-wrap</code> Works in Responsive Design</h3>
<p>When you use <code>text-wrap</code> on your text, you need not to worry how it is going to appear on various screen sizes. The below video shows you what I mean by that:</p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_4C8BE890CB3AB8AD50C286E15DBA884FF164212E142B1E75C767C0221DB183E7_1743738297774_ScreenRecording2025-04-04at4.37.18AM-ezgif.com-video-to-gif-converter.gif" alt="A gif showing how 'text-wrap' smoothly adjusts on a responsive screen " width="600" height="400" loading="lazy"></p>
<h3 id="heading-using-media-queries-for-extra-control">Using Media Queries for Extra Control</h3>
<p>Combine <code>media-queries</code> and <code>text-wrap</code> to have a great special kind of control on how your text appears on various screens.</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">h1</span> {
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">2.5rem</span>;
  <span class="hljs-attribute">text-wrap</span>: balance;
}

<span class="hljs-comment">/* On smaller screens, reduce font size and apply text-balancing */</span>
<span class="hljs-keyword">@media</span> (<span class="hljs-attribute">max-width:</span> <span class="hljs-number">600px</span>) {
  <span class="hljs-selector-tag">h1</span> {
    <span class="hljs-attribute">font-size</span>: <span class="hljs-number">2rem</span>;
    <span class="hljs-attribute">text-wrap</span>: balance;
  }
}
</code></pre>
<p>This code ensures your heading text adapts and remains clean across multiple device sizes.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>How text displays is something every good developer should pay attention to. It plays a big role in user experience. By using <code>text-wrap</code>, you can ensure that your website layouts don't look messy or difficult to read.</p>
<p>One of the best things about using <code>text-wrap</code> in your text formatting is that it just works every time. You don’t need to bother with <code>&lt;br&gt;</code> tags, tweak <code>max-width</code>, or fight with text alignment.</p>
<p>Even though it's not yet supported by all browsers, adding it to your next project will future-proof your design so it’s always intact and good-looking.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Build a Responsive Website with HTML and CSS - Course in Spanish ]]>
                </title>
                <description>
                    <![CDATA[ Building websites that look great on any device – like a phone, tablet, or computer screen – is what responsive web development is all about. In this course, you will learn how to build a responsive website step by step in Spanish using HTML and CSS.... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-responsive-website-with-html-and-css-full-course-in-spanish/</link>
                <guid isPermaLink="false">662926efccfe31d419712ddf</guid>
                
                    <category>
                        <![CDATA[ Responsive Web Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ español ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Estefania Cassingena Navone ]]>
                </dc:creator>
                <pubDate>Wed, 24 Apr 2024 15:36:15 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1713808669840/d79f8ee5-b159-4a71-a0be-4ff3b52b3f5d.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Building websites that look great on any device – like a phone, tablet, or computer screen – is what responsive web development is all about. In this course, you will learn how to build a responsive website step by step in Spanish using HTML and CSS.</p>
<p>We just published a course on the <a target="_blank" href="https://www.youtube.com/freecodecampespanol">freeCodeCamp.org Spanish YouTube channel</a> that will teach you Responsive Web Development by building a website step by step. You will use the core concepts that you need to understand in order to master responsive web development. By the end of the course, you will be able to design and implement responsive websites using HTML and CSS.</p>
<p>If you have Spanish-speaking friends, you are welcome to share the <a target="_blank" href="https://www.freecodecamp.org/espanol/news/crea-una-pagina-web-responsive-con-html-y-css"><strong>Spanish version of this article</strong></a> with them.</p>
<p>This course was created by David Choi. David is a Software Developer who loves coding and sharing his knowledge with everyone who wants to dive into the world of programming and computer science.</p>
<p>David will teach you how to create and implement modern and responsive web designs step by step with HTML and CSS (without frameworks or libraries).</p>
<p>If your goal is to design and create modern websites, you definitely need to learn how to make them responsive. Before you start learning responsive web development with David's course, let's have a quick introduction.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/frame-4.png" alt="The first sections of the responsive website that you will be building step by step." width="600" height="400" loading="lazy"></p>
<h2 id="heading-what-is-responsive-web-development">What is Responsive Web Development?</h2>
<p>A responsive website is a website that adapts its layout and content to fit the size of the screen. It should look and work correctly on desktops, laptops, tablets, smartphones, and other devices.</p>
<p>Responsive web development is the approach used by developers to create these websites that adapt to devices of different sizes. This results in a much better user experience because the user will have access to the content in a layout that has been specifically adapted to their device. Search engines also reward sites that offer a good user experience for all devices.</p>
<p>You can develop responsive websites with HTML and CSS. This is where CSS Flexbox comes to the rescue. You will practice your CSS Flexbox skills during the course. Let's see what it is all about.</p>
<h3 id="heading-what-is-flexbox">What is Flexbox?</h3>
<p>Flexbox is a CSS layout model for arranging elements in a single dimension. With Flexbox, you can place elements horizontally or vertically, distribute space evenly to resize the layout based on screen size, and even control the order of the elements.</p>
<p>💡 <strong>Tip:</strong> If you need to refresh your HTML, CSS, and Flexbox skills, you can take courses on these topics on our Spanish YouTube channel before diving into the project.</p>
<ul>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=XqFR2lqBYPs">Aprende HTML y CSS - Curso Desde Cero</a></p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=iwFEc6I8wSA">Aprende CSS Flexbox - Curso desde Cero</a></p>
</li>
</ul>
<h2 id="heading-responsive-website-project-in-spanish"><strong>Responsive Website Project in Spanish</strong></h2>
<p>During the course, you will:</p>
<ul>
<li><p>Analyze the website design and translate it into HTML.</p>
</li>
<li><p>Prepare your development environment.</p>
</li>
<li><p>Install Visual Studio Code.</p>
</li>
<li><p>Create the structure of the website in HTML.</p>
</li>
<li><p>Define and assign CSS styles for the mobile version.</p>
</li>
<li><p>Define and assign CSS styles for the desktop version.</p>
</li>
</ul>
<p>You will combine basic CSS with Flexbox to assign styles that adapt to the current size of the screen.</p>
<p>Here we have some course screenshots to give you an idea of the awesome project that you will be building with David:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/frame-2.png" alt="The desktop version of the responsive website." width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/frame-3.png" alt="The mobile version of the responsive website." width="600" height="400" loading="lazy"></p>
<p>If you are ready to start building this project, check out the course in Spanish on the <a target="_blank" href="https://www.youtube.com/freecodecampespanol">freeCodeCamp.org Spanish YouTube channel</a>:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/VgHproadDD8" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>✍️ Course created by David Choi.</p>
<ul>
<li><p>YouTube: <a target="_blank" href="https://www.youtube.com/@deivchoi">@deivchoi</a></p>
</li>
<li><p>GitHub: <a target="_blank" href="https://github.com/choidavid4">@choidavid4</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
