<?xml version="1.0" encoding="UTF-8" ?>
    <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/layout/content/">
    <channel>
      <title>Lionel Péramo&#039;s Blog (en)</title>
      <link>https://lionel-peramo.com/</link>
      <description>A blog about web development and technology.</description>
      <language>en</language>
      <atom:link href="https://lionel-peramo.com/rss.xml" rel="self" type="application/rss+xml" />
      <item>
            <title>CompressionStream API: Optimize Your Data Transfers Natively</title>
            <link>https://lionel-peramo.com/posts/compression-stream-api-native-performance/</link>
            <guid>https://lionel-peramo.com/posts/compression-stream-api-native-performance/</guid>
            <pubDate>Sun, 08 Mar 2026 18:10:00 +0000</pubDate>
            <description>Learn how to reduce data weight without bloating your code. A complete guide to the native compression API for faster web applications.</description>
            <content:encoded><![CDATA[
              <p>⏱️ Reading time: 8 min</p>
              
<p>On the modern web, speed is a priority. Every byte sent between a server and a user impacts loading time. Heavier data
makes applications feel slow, especially on mobile devices or poor connections.</p>
<p>Until recently, client-side data compression required importing massive third-party libraries
like <a href="https://github.com/nodeca/pako">pako</a> or <a href="https://github.com/nodejs/node/blob/main/lib/zlib.js">zlib.js</a>. These
tools add weight to your application before it even starts working. Today, a built-in solution exists: the
<strong>CompressionStream API</strong>.</p>
<h2>Why compress data on the client side?</h2>
<p>Most developers think compression is a task reserved for the server. This is often true for downloading pages. However,
in data-rich applications, the client (the browser) often needs to send large amounts of information to the server.</p>
<p>Here are some situations where native compression is useful:</p>
<ol>
<li><strong>Sending logs:</strong> If your application sends detailed error reports.</li>
<li><strong>Saving documents:</strong> For online text or drawing editors.</li>
<li><strong>Local storage:</strong> To save more information in the browser database (IndexedDB) without saturating the user’s disk
space.</li>
</ol>
<h2>What is the CompressionStream API?</h2>
<p>This programming interface (API) allows you to compress and decompress data streams natively. “Native” means the code is
already present in the browser. You do not need to download anything extra.</p>
<p>It uses streams. A stream is a way to process data bit by bit, like water flowing through a pipe, rather than waiting
for the entire bucket to be full. This prevents using too much memory (RAM) on the user’s device.</p>
<h2>Available algorithms</h2>
<p>The API offers three main formats to transform your data:</p>
<ul>
<li><strong>GZIP</strong>: The most common format on the Internet. It offers an excellent balance between final file size and
calculation speed.</li>
<li><strong>DEFLATE</strong>: A very fast basic algorithm.</li>
<li><strong>DEFLATE-RAW</strong>: A version of Deflate without header information, used for specific technical needs.</li>
</ul>
<h2>Practical application: compressing data</h2>
<p>To use this API, we create a compression stream. Here is how to transform simple text into compressed data.</p>
<pre><code class="language-js">/**
 * Compresses a string into GZIP
 * @param {string} inputData
 * @returns {Promise&lt;Uint8Array&gt;}
 */
async function compressData(inputData)
{
  const
    encoder = new TextEncoder(),
    rawData = encoder.encode(inputData),

    // Create a stream from raw data
    stream = new Blob([rawData]).stream(),
    compressionStream = new CompressionStream('gzip'),

    // Pass data through the compressor
    compressedStream = stream.pipeThrough(compressionStream),

    response = new Response(compressedStream),
    buffer = await response.arrayBuffer();

  return new Uint8Array(buffer);
}
</code></pre>
<h2>Doing the opposite: decompression</h2>
<p>If you receive compressed data from the server or your local database, you must make it readable again.</p>
<pre><code class="language-js">/**
 * Decompresses GZIP data to get text
 * @param {Uint8Array} compressedData
 * @returns {Promise&lt;string&gt;}
 */
async function decompressData(compressedData)
{
  const
    decompressionStream = new DecompressionStream('gzip'),

    // Create a readable stream for the decompressor
    stream = new ReadableStream(
      {
        start(controller)
        {
          controller.enqueue(compressedData);
          controller.close();
        }
      }),

    decompressedStream = stream.pipeThrough(decompressionStream),
    response = new Response(decompressedStream);

  return await response.text();
}
</code></pre>
<h2>The importance of streaming</h2>
<p>The strength of this API lies in its ability to process huge files without freezing the computer. If you try to compress
a 1 GB file all at once, the browser might close the tab due to lack of memory.</p>
<p>With the <code>pipeThrough</code> system, data flows in small segments. This is called backpressure management. The system
automatically adapts to the processing speed of the device.</p>
<h2>Design optimization and accessibility</h2>
<p>Technical performance is not enough. The user must understand what is happening. If compression takes time, a fluid
progress bar should be displayed.</p>
<p>Let’s use modern CSS to create an indicator that adapts to all screen sizes using fluid properties.</p>
<pre><code class="language-css">.progress-container {
  /* Use clamp for fluid and responsive width without media queries */
  inline-size      : clamp(15rem, 50vw + 2rem, 100%);
  background-color : #f0f0f0;
  border-radius    : .5rem;
  padding          : .25rem;
}

.progress-bar {
  block-size       : 1rem;
  background-color : #007bff;
  border-radius    : .25rem;
  /* Optimization: Only apply transition if the user doesn't prefer reduced motion */
  transition       : width .2s ease-in-out;
}

/* Use :not to avoid CSS overrides and keep the code clean */
@media (prefers-reduced-motion : reduce) {
  .progress-bar:not(.static) {
    transition : none;
  }
}
</code></pre>
<h2>Impact on SEO</h2>
<p>Google and other search engines use robots to analyze your site. These robots reward sites that are lightweight and
resource-efficient.</p>
<ol>
<li><strong>Reduction in total weight</strong>: Less JavaScript code to download means a better “Core Web Vitals” score.</li>
<li><strong>Interaction speed</strong>: By compressing outgoing data, you free up the user’s bandwidth faster, making the application
more responsive.</li>
<li><strong>Mobile experience</strong>: A site that saves its users’ mobile data is better ranked and more appreciated.</li>
</ol>
<h2>When to avoid using this API?</h2>
<p>There are cases where compression is useless or even counterproductive:</p>
<ul>
<li><strong>Already compressed files</strong>: Images (JPG, PNG), videos (MP4), and PDF files are already compressed. Trying to
compress them again with GZIP can sometimes make the file larger.</li>
<li><strong>Small data</strong>: If your text is less than 100 bytes, compression will add structure information that will make the
final result larger than the original.</li>
</ul>
<h2>Browser compatibility</h2>
<p>The CompressionStream API is available on almost all recent browsers (Chrome, Firefox, Safari, Edge). However, for older
systems, it is important to check if the tool exists before using it.</p>
<pre><code class="language-js">console.log(
  ('CompressionStream' in window)
    ? 'Native compression is available!'
    : 'Using a slower alternative method.'
);
</code></pre>
<h2>Conclusion: a step towards a cleaner web</h2>
<p>Using the CompressionStream API is a smart decision for any performance-conscious developer. It allows for removing
unnecessary dependencies, reducing memory consumption, and improving the overall user experience.</p>
<p>In 2026, the quality of an application is not only measured by its features, but by its ability to be lightweight and
respectful of the user’s resources. Native compression is one of the best tools to achieve this goal.</p>
<hr>
<h3>Frequently Asked Questions (FAQ)</h3>
<details>
<summary>Does compression slow down the user's CPU?</summary>
Any compression requires effort from the processor. However, the native API is optimized by browser creators. It is much faster and more battery-efficient than old libraries manually written in JavaScript.
</details>
<details>
<summary>Can I compress multiple files into one?</summary>
No, the CompressionStream API compresses one data stream at a time. To create an archive containing multiple files (like a .zip), you will need to use an additional data structure to organize your files before compressing them.
</details>
<details>
<summary>Is GZIP the best format?</summary>
It is the most compatible. If you send data to a standard web server, GZIP is often automatically recognized. It is therefore the safest choice for most projects.
</details>

            ]]></content:encoded>
        </item><item>
            <title>OKLCH: The Ultimate Guide to Mastering Perceptual Colors in CSS</title>
            <link>https://lionel-peramo.com/posts/oklch-css-ultimate-guide-perceptual-colors/</link>
            <guid>https://lionel-peramo.com/posts/oklch-css-ultimate-guide-perceptual-colors/</guid>
            <pubDate>Wed, 04 Mar 2026 22:30:00 +0000</pubDate>
            <description>HSL is dead, long live OKLCH. Learn why this format changes everything for accessibility, performance, and modern web interface design.</description>
            <content:encoded><![CDATA[
              <p>⏱️ Reading time: 8 min</p>
              
<p>Web development is a quest for precision. We optimize our scripts. We reduce image weight. Yet, we often use obsolete
color tools. The RGB format dates back to the first tube monitors. The HSL format was created to simplify mathematical
calculations. None of these formats understand how your eyes work.</p>
<p><strong>OKLCH</strong> changes everything. It is not just a new syntax. It is a new way to calculate light in the browser. In this
guide, we will explore in depth why you must adopt it today.</p>
<h2>Why HSL Has Always Fooled Us</h2>
<p>You might think that changing lightness in HSL is enough. This is a common mistake. In HSL, the ‘Lightness’ (L) value is
relative to the mix of primary colors. It does not account for the sensitivity of the human retina.</p>
<h3>The Yellow and Blue Experiment</h3>
<p>Let us perform a simple test. Take a pure yellow (<code>hsl(60, 100%, 50%)</code>). Take a pure blue (<code>hsl(240, 100%, 50%)</code>). Both
have a lightness of 50%. However, if you turn this image into black and white, the yellow will look almost white. The
blue will look almost black.</p>
<p>Why? Because the human eye perceives yellow as naturally brighter than blue. If you create an interface with these two
colors in HSL, your contrasts will be wrong. You will have to correct each color by hand. This is a huge waste of time
for a developer.</p>
<h2>The Solution: OKLCH and Human Perception</h2>
<p>The OKLCH color space is ‘perceptually uniform’. This means the numbers match what you see. If two colors have an ‘L’
(Lightness) of ‘0.7’, they will have exactly the same clarity to a human.</p>
<h3>Understanding the Three Components</h3>
<ol>
<li><strong>L (Lightness):</strong> The clarity. It goes from ‘0’ (total black) to ‘1’ (pure white). Unlike HSL, ‘0.5’ in OKLCH is
always perceived as a perfect medium gray.</li>
<li><strong>C (Chroma):</strong> The strength of the color. It starts at ‘0’. The higher the number, the more vivid the color. It is
more precise than saturation because it does not depend on lightness.</li>
<li><strong>H (Hue):</strong> The tint. It is the angle on the color wheel from ‘0’ to ‘360’.</li>
</ol>
<pre><code class="language-css">/* Using variables for optimal performance */
:root {
  --hue-brand   : 260;
  --chroma-main : .12;

  /* We define lightness fluidly based on screen size */
  --light-fluid : clamp(.4, 2vw + .1, .8);
}

.main-container *:not(footer) {
  background-color : oklch(var(--light-fluid) var(--chroma-main) var(--hue-brand));
}
</code></pre>
<h2>Performance and Code Optimization</h2>
<p>In a high-performance context, CSS structure is vital. OKLCH allows writing less code to achieve more results.</p>
<h3>Automatic and Predictable Dark Mode</h3>
<p>In HSL, switching to dark mode is a headache. You change the ‘L’, but the color often becomes too saturated or shifts
hue visually. In OKLCH, you simply lower the ‘L’. The hue and purity remain strictly identical.</p>
<pre><code class="language-css">[data-theme='dark'] {
  /* We halve the lightness without altering the color */
  --light-fluid : .2;
}

.article-content {
  color : oklch(var(--light-fluid) var(--chroma-main) var(--hue-brand));
}
</code></pre>
<h3>Optimizing Color Animation Fluidity</h3>
<p>The browser calculates OKLCH colors natively. By using CSS Variables with OKLCH, you avoid heavy recalculations. The GPU
can interpolate these values very quickly during transitions. This ensures a 60 frames per second (FPS) rendering.</p>
<h2>Impact on SEO and Accessibility</h2>
<p>Google uses algorithms to check if your text is readable. If your contrasts are poor, your SEO score drops.</p>
<h3>Towards the WCAG 3 Standard (APCA)</h3>
<p>Future accessibility standards (APCA) will favor models like OKLCH. Why? Because they are closer to physical reality. By
using OKLCH today, you prepare your site for tomorrow’s standards.</p>
<h3>Simplified Contrast Algorithm</h3>
<p>With OKLCH, you no longer need complex tools to check your colors. You can define a simple rule for your team: ‘The text
must always have an L that differs by 0.5 from the background’. This rule will work for ALL colors in the spectrum. This
is a major productivity gain.</p>
<pre><code class="language-css">.badge {
  /* Light background */
  background-color : oklch(.9 .05 var(--hue-brand));

  /* Dark text guaranteed readable on 0.9 background */
  color            : oklch(.2 .05 var(--hue-brand));
}
</code></pre>
<h2>The P3 Gamut: Pushing Screen Limits</h2>
<p>Most developers remain stuck in ‘sRGB’. It is an old, limited color space. Recent screens (OLED, Retina) support *
<em>Display P3</em>*.</p>
<p>OKLCH is the bridge to this universe. It allows you to declare colors that do not exist in RGB or HSL. These colors are
more vibrant and deeper. They draw the eye to your Call to Action (CTA) buttons.</p>
<h3>A Risk-Free Transition</h3>
<p>If the user has an old screen, the browser performs the calculation. It finds the closest possible color. This is called
progressive enhancement. You offer the best to modern users without breaking the experience for others.</p>
<h2>Methodology: How to Migrate an Existing Project?</h2>
<p>Switching to OKLCH requires a rigorous method to maintain performance.</p>
<ol>
<li><strong>Identify Hues:</strong> List your current colors (Hex or HSL).</li>
<li><strong>Convert:</strong> Use converters to find the OKLCH equivalent.</li>
<li><strong>Parameterize:</strong> Create variables for Hue (H) and Chroma (C).</li>
<li><strong>Adjust:</strong> Use Lightness (L) to create your shades (hover, active, focus).</li>
</ol>
<pre><code class="language-css">.button-action {
  /* Avoid media queries with clamp */
  --btn-width      : clamp(6.25rem, 15vw, 16.25rem);

  width            : var(--btn-width);
  background-color : oklch(.6 .2 150);
}

.button-action:hover {
  /* Simple and clean clarity increase */
  background-color : oklch(.7 .2 150);
}
</code></pre>
<h2>Conclusion: Modern Code Craftsmanship</h2>
<p>OKLCH is not an option. It is a necessity for any developer who cares about software quality. It provides:</p>
<ul>
<li>Mathematical and reliable <strong>accessibility</strong>.</li>
<li>Optimal rendering <strong>performance</strong>.</li>
<li>Increased <strong>maintainability</strong> through logical variables.</li>
<li>Strengthened <strong>SEO</strong> via perfect contrasts.</li>
</ul>
<p>In 2026, the web must be inclusive and fast. By mastering OKLCH, you regain total control over the light in your
interfaces. Your sites will not just be more beautiful. They will be more accurate.</p>
<hr>
<h3>Frequently Asked Questions (FAQ)</h3>
<details>
<summary>Does OKLCH completely replace the HEX format?</summary>
Yes. The HEX format is a relic of the past. It is hard for a human to read and does not support transparency natively in
a simple way. OKLCH is superior in every way for modern development.
</details>
<details>
<summary>Why is Chroma (C) sometimes a small number like 0.1?</summary>
Chroma is not a percentage. It is a measure of intensity. For most web interfaces, a value between 0.01 and 0.3 is more
than enough. Beyond 0.4, you enter extremely vivid colors that may not display on all screens.
</details>
<details>
<summary>How to handle support for old browsers?</summary>
Support is excellent (90%+ of users). For remaining browsers, you can use an automatic fallback via PostCSS or write a
simple rule: <code>color: rgb(0, 100, 0); color: oklch(0.5 0.2 150);</code>. The browser will ignore the second line if
it does not understand it.
</details>
<details>
<summary>Can OKLCH be used with gradients?</summary>
Absolutely. OKLCH gradients are magnificent. They do not pass through the 'dead gray' in the middle of the gradient like
RGB gradients do. The transition is organic and vibrant.
</details>

            ]]></content:encoded>
        </item><item>
            <title>Web Compatibility and Accessibility: The Guide to 5 Technical Tools</title>
            <link>https://lionel-peramo.com/posts/web-compatibility-accessibility-tools/</link>
            <guid>https://lionel-peramo.com/posts/web-compatibility-accessibility-tools/</guid>
            <pubDate>Tue, 03 Mar 2026 19:00:00 +0000</pubDate>
            <description>Learn how to use CanIUse, CanIEmail, A11y Support, CanInclude, and Can I PHP. This guide helps you code without errors on all platforms.</description>
            <content:encoded><![CDATA[
              <p>⏱️ Reading time: 7 min</p>
              
<p>Web development is a complex job. Creating a site is not enough. Your code must work everywhere. It must work on all
screens. It must work for all users.</p>
<p>There are many different browsers. There are many email applications. Some servers use old technologies. These
differences create errors. We call these compatibility problems.</p>
<p>A technical error drives your customers away. It also blocks people with disabilities. It prevents search engines from
reading your site.</p>
<p>To succeed, you must check your code. Here are 5 tools to code with precision.</p>
<h2>1. CanIUse: Checking Web Browsers</h2>
<p><strong>Link:</strong> <a href="https://caniuse.com/">https://caniuse.com/</a></p>
<p>CanIUse is a huge database. It lists web features. It shows which browsers accept your code. It covers Chrome, Firefox,
Safari, and Edge.</p>
<h3>Why Use This Tool?</h3>
<p>Browsers do not evolve at the same speed. A feature might work on Chrome but not on Safari. CanIUse displays color
tables.</p>
<ul>
<li><strong>Green:</strong> The code works well.</li>
<li><strong>Red:</strong> The code does not work.</li>
<li><strong>Yellow:</strong> The code works sometimes.</li>
</ul>
<h3>Technical CSS Code Example</h3>
<p>Modern CSS allows you to write fewer lines. We use mathematical functions for element sizes. We also use selectors to
exclude objects.</p>
<p>Here is a very high-performance code example:</p>
<pre><code class="language-css">/* Container with fluid width */
.main-wrapper {
  width         : min(100% - 2rem, 75rem);
  margin-inline : auto;
}

/* Text size adapts to the screen */
.main-title {
  font-size : clamp(1.25rem, 4vw + 1rem, 2.5rem);
}

/* Style only elements that are not disabled */
.action-link:not(.is-disabled) {
  color           : '#05f';
  text-decoration : underline;
}
</code></pre>
<p>Before copying this code, go to CanIUse. Type <code>min</code>, <code>clamp</code>, or <code>:not</code>. The tool gives you the percentage of compatible
users. If the score is high, you can code. If the score is low, you must change your method. This avoids breaking the
display for your customers.</p>
<h2>2. CanIEmail: Email Compatibility</h2>
<p><strong>Link:</strong> <a href="https://www.caniemail.com/">https://www.caniemail.com/</a></p>
<p>Sending an HTML email is very difficult. Email applications are old. They do not read code like a browser. Outlook is
the most difficult application. It uses the Microsoft Word engine to display emails.</p>
<h3>The Dangers of Code in Emails</h3>
<p>Many CSS properties are forbidden in emails. CanIEmail tests over 50 applications. It also tests over 170 features.</p>
<p>If you use bad code, the email will be unreadable. The user will delete your message. CanIEmail saves you time. It shows
you what is safe. Often, you must use HTML tables for the structure. It is an old but very solid technique. The tool
helps you choose between design and compatibility.</p>
<h2>3. A11y Support: The Accessibility Tool</h2>
<p><strong>Link:</strong> <a href="https://a11ysupport.io/">https://a11ysupport.io/</a></p>
<p>Web accessibility allows disabled people to use the internet. Blind people use screen readers. This software reads the
code aloud. But not all screen readers read the same thing.</p>
<h3>Why Check A11y Support?</h3>
<p>A code can be correct for the W3C. Yet, software might not understand it. A11y Support lists these problems. It compares
browsers and screen readers.</p>
<p>The tool tests ARIA attributes. It also tests HTML roles.</p>
<ul>
<li>It prevents making a site invisible to a blind person.</li>
<li>It ensures your buttons are usable with a keyboard.</li>
<li>It makes your site truly inclusive.</li>
</ul>
<p>Always check your interactive components on this tool. It is a mandatory step for quality.</p>
<h2>4. CanInclude: Validating HTML Structure</h2>
<p><strong>Link:</strong> <a href="https://caninclude.glitch.me/">https://caninclude.glitch.me/</a></p>
<p>The HTML language has precise rules. We call this semantics. Some tags cannot go inside other tags. CanInclude checks
these rules for you.</p>
<h3>The Risks of a Bad Structure</h3>
<p>Nesting your tags incorrectly creates bugs. The browser must make efforts to fix your errors. This slows down the page
display.</p>
<p>A bad structure also loses Google robots. Google uses HTML to understand your topic. If the HTML is wrong, your SEO
drops. CanInclude is very simple. You provide the parent tag. You provide the child tag. The tool answers ‘Yes’ or ‘No’.
It is fast and efficient.</p>
<h2>5. Can I PHP: Server Compatibility</h2>
<p><strong>Link:</strong> <a href="https://caniphp.com/">https://caniphp.com/</a></p>
<p>PHP code runs on the server. PHP changes versions often. Each version brings new functions. If your server is old, your
recent code will crash.</p>
<h3>Securing Your Backend</h3>
<p>A PHP error stops the entire site. The user sees a white page. We call this a fatal error. This is very bad for your
business.</p>
<p>Can I PHP gives you the minimum version for each function. Here is an example of modern PHP code:</p>
<pre><code class="language-php">&lt;?php

/* Check a string with a modern function in PHP
 * This requires PHP 8.0 or higher */
function check_user_access(string $role)
{
  if (str_contains($role, 'admin'))
    return 'Access granted';

  return 'Access denied';
}
</code></pre>
<p>Go to Can I PHP. Type <code>str_contains</code>. The tool will tell you: ‘PHP 8.0’. If your server uses PHP 7.4, the code will
break. You will have to use an old function like <code>strpos</code>. This tool protects your server against crashes.</p>
<h2>Conclusion</h2>
<p>Performance depends on compatibility. A good developer always checks their tools.</p>
<ul>
<li><strong>CanIUse</strong> secures your styles and scripts.</li>
<li><strong>CanIEmail</strong> makes your emails readable everywhere.</li>
<li><strong>A11y Support</strong> opens your site to everyone.</li>
<li><strong>CanInclude</strong> validates your HTML structure.</li>
<li><strong>Can I PHP</strong> protects your server from errors.</li>
</ul>
<p>Use these tools every day. Your code will be stronger. Your users will be happier. Your site will be faster.</p>
<hr>
<h3>Frequently Asked Questions (FAQ)</h3>
<details>
<summary>Are these tools free?</summary>
Yes. All these tools are free. they are maintained by volunteer experts.
</details>
<details>
<summary>Which tool is the most important?</summary>
All are important. But CanIUse is the one used most often. It is the base of the developer profession.
</details>
<details>
<summary>Why test accessibility?</summary>
It is a legal obligation in many countries. It is also an ethical choice to leave no one behind.
</details>
<details>
<summary>Can I use these tools on mobile?</summary>
Yes. All these sites work on smartphones. You can check a function anywhere.
</details>

            ]]></content:encoded>
        </item><item>
            <title>PHP on the Desktop: Mastering BosonPHP for Ultra-High Performance Native Applications</title>
            <link>https://lionel-peramo.com/posts/php-desktop-native-applications-bosonphp/</link>
            <guid>https://lionel-peramo.com/posts/php-desktop-native-applications-bosonphp/</guid>
            <pubDate>Thu, 26 Feb 2026 15:00:00 +0000</pubDate>
            <description>BosonPHP (v0.19.5) turns PHP into a formidable alternative to Electron. Explore the FFI architecture, framework integration via Bridges, and memory management to build native desktop apps.</description>
            <content:encoded><![CDATA[
              <p>⏱️ Reading time: 10 min</p>
              
<p>For over twenty years, PHP has reigned supreme over the web backend. Its execution model was immutable: an HTTP request
comes in, a process is born, generates a response, and then dies. But those days are over. The introduction and
maturation of the <strong>FFI (Foreign Function Interface)</strong> extension have opened a breach into which new architectures are
flooding.</p>
<p>Today, the <strong>BosonPHP</strong> project stands as the new frontier of the ecosystem. It is not just a localized web server, but
a true open-source runtime (MIT licensed) designed to run PHP code as a native desktop application. Gone is the
excessive weight of Chromium and Node.js inherent to the Electron ecosystem. Welcome to direct, ultra-lightweight, and
lightning-fast execution.</p>
<h2>BosonPHP 0.19.5: Anatomy of a Desktop Kernel</h2>
<p>The project’s official slogan on GitHub perfectly summarizes its philosophy: <em>“Because it’s not an Electron!”</em>.</p>
<p>The traditional approach to building desktop apps with web technologies involves embedding a full browser within each
application. The result? A basic app often consumes over 200 MB of RAM at rest and carries significant weight on the
disk.</p>
<p>BosonPHP takes the opposite path. In its current version <strong>0.19.5</strong>, the system relies on high-level bindings to
<strong>Saucer v6.0</strong>, an ultra-lightweight C++ library dedicated to creating smart WebView windows. BosonPHP wraps your code
in the native WebView engine provided by the operating system (Edge WebView2 on Windows, WebKit on macOS and Linux). The
final compiled application weighs only a few dozen megabytes.</p>
<h3>The Strategic Choice of PHP 8.4</h3>
<p>You might wonder if BosonPHP already uses PHP 8.5, which is starting to be discussed. The answer is no. Currently, the
reactor’s core remains firmly anchored on <strong>PHP 8.4</strong> (as confirmed by the <code>php84</code> technical tag in their official
repository).</p>
<p>Why stick to version 8.4? Because creating native interfaces via FFI requires complex manipulation of memory pointers in
C. PHP 8.4 offers extremely well-documented stability regarding the asynchronous <strong>Garbage Collector</strong> and typed
structures—vital elements to avoid memory leaks in a long-running process. Moving to a higher minor version would
require revalidating the reliability of all underlying memory bridges.</p>
<h2>The ‘Zero HTTP Overhead’ Architecture and Framework Bridges</h2>
<p>The real revolution of BosonPHP lies in the absence of a network. In previous attempts to port PHP to the desktop, a
micro-web server was launched in the background, and the interface communicated with it via TCP requests on <code>localhost</code>.</p>
<p>With BosonPHP, the GUI communicates directly with the PHP process in memory. Events trigger PHP methods directly. But
how can we use our favorite frameworks if the whole concept of an HTTP request has disappeared?</p>
<h3>The Bridge System</h3>
<p>This is where BosonPHP demonstrates its engineering prowess. The team has developed an ecosystem of <strong>Bridges</strong> that
emulate HTTP behavior directly in RAM, without ever opening a network port.</p>
<p>The project offers official components to integrate your frameworks without modification:</p>
<ul>
<li><code>boson-php/laravel-provider</code> and <code>boson-php/laravel-http-bridge</code></li>
<li><code>boson-php/symfony-bundle</code> and <code>boson-php/symfony-http-bridge</code></li>
<li><code>boson-php/spiral-bridge</code></li>
<li><code>boson-php/psr-http-bridge</code> (for any PSR-7 compatible router)</li>
</ul>
<p>When your application’s WebView attempts to load an internal URL or submit a form, the Boson Bridge intercepts the call,
builds a native request object (e.g., an <code>Illuminate\Http\Request</code> for Laravel), and injects it into the framework in
memory. The response is generated and returned to the WebView instantly.</p>
<h2>Developing with BosonPHP: A Practical Case</h2>
<p>BosonPHP’s software structure is highly modular. To add native features, you install specific extensions via Composer.</p>
<p>Let’s take an example of an application that monitors network and battery status. We will use the
<code>boson-php/webview-ext-battery</code> and <code>boson-php/app-ext-alert</code> components.</p>
<pre><code class="language-php">&lt;?php

use Boson\App;
use Boson\Window;
use Boson\Extensions\Alert\AlertExtension;
use Boson\Extensions\Battery\BatteryExtension;

class SystemMonitor
{
  private App $app;
  private Window $window;

  public function __construct()
  {
    $this-&gt;app = new App();
    
    // We register native extensions into the Kernel
    $this-&gt;app-&gt;register(new AlertExtension());
    $this-&gt;app-&gt;register(new BatteryExtension());
  }

  public function boot(): void
  {
    $this-&gt;window = new Window(
      title: 'Boson System Monitor',
      width: 800,
      height: 600
    );

    $this-&gt;window-&gt;on('ready', function (Window $win)
    {
      $this-&gt;checkBatteryStatus($win);
    });

    $this-&gt;app-&gt;run();
  }

  private function checkBatteryStatus(Window $win): void
  {
    // Calling the native Battery API via FFI bindings
    $battery = $win-&gt;native-&gt;getBatteryInfo();
    
    if ($battery-&gt;percent &lt; 20 &amp;&amp; !$battery-&gt;isCharging)
    {
      // Calling native OS message box without HTML/JS
      $win-&gt;native-&gt;alert(
        title: 'Warning',
        message: 'Battery level is critically low.'
      );
    }

    // Pushing data to the WebView DOM
    $win-&gt;executeJS('updateBatteryUI(' . $battery-&gt;percent . ');');
  }
}

$monitor = new SystemMonitor();
$monitor-&gt;boot();
</code></pre>
<p>In this code, we see the power of the API. The <code>app-ext-alert</code> extension does not create a fake HTML dialog box. It
calls the actual <code>MessageBox</code> API of the OS on Windows or the <code>NSAlert</code> API on macOS via FFI bindings.</p>
<h2>Critical Memory Management in a Desktop Context</h2>
<p>This is the major friction point for a backend developer transitioning to BosonPHP. In classic PHP (PHP-FPM), memory
cleanup is not your primary concern because the process dies at the end of the request.</p>
<p>In BosonPHP, your application can stay open in the background for weeks. The development rules change:</p>
<ol>
<li><strong>Ban Infinite Global State:</strong> Arrays stored in <code>$GLOBALS</code> or static class properties that accumulate over time will
cause a fatal memory leak.</li>
<li><strong>Master Weak References:</strong> Boson provides the <code>boson-php/weak-types</code> component to manage data. A weak reference
allows you to associate metadata with an object without preventing the Garbage Collector from destroying it when it
is no longer used elsewhere.</li>
<li><strong>Force Cyclic Cleanup:</strong> In complex applications, it is often wise to bind the <code>gc_collect_cycles()</code> function to an
internal timer or a change in application state (such as minimizing the window to the taskbar).</li>
</ol>
<h2>The Workflow: From Writing to Compilation</h2>
<p>The project excels in its fluid deployment process. The Developer Experience (DX) is designed to be as simple as
possible.</p>
<p>You initialize your project with:</p>
<pre><code class="language-bash">composer create-project boson-php/app my-app
</code></pre>
<p>During development, you test the application by simply running:</p>
<pre><code class="language-bash">php index.php
</code></pre>
<p>Once development is complete, the <code>boson-php/compiler</code> component comes into play. It consolidates your source code,
front-end assets, and the internal PHP engine into a single, standalone executable.</p>
<pre><code class="language-bash">php vendor/bin/boson compile
</code></pre>
<p>The generated executable contains everything needed. The end user <strong>absolutely does not need to have PHP installed</strong> on
their machine. It is total plug-and-play.</p>
<h2>Conclusion</h2>
<p>BosonPHP is no longer just an experiment. With a stable architecture based on PHP 8.4, the integration of Saucer v6.0,
and robust framework support via native asynchronous bridges, version 0.19.5 offers high-level industrial tooling.</p>
<p>Capitalizing on BosonPHP means using your current technical knowledge to deploy ultra-lightweight and high-performance
software on any desktop operating system. The elephant language is no longer just the king of the server; it now has a
place on your desktops.</p>
<hr>
<h3>Frequently Asked Questions</h3>
<details>
<summary>Can I use a local database with a BosonPHP application?</summary>
Yes. The recommended technology for the desktop is <strong>SQLite</strong>. PHP's native <code>PDO_SQLITE</code>
extension integrates perfectly because it requires no external daemon or service. Read and write operations are
performed directly on a local file within the application's storage space.
</details>
<details>
<summary>Does BosonPHP support asynchronous code or multithreading?</summary>
PHP is fundamentally single-threaded. However, Boson's event architecture uses the OS's internal event loop. For
complex asynchronous tasks (like heavy network calls without freezing the UI), you can use native PHP 8.1+
<strong>Fibers</strong> or resort to compatible background processing libraries.
</details>
<details>
<summary>Are BosonPHP applications secure against code injection?</summary>
Since the PHP code is executed locally and packaged in a binary, the risk of server-side injection (Remote Code
Execution) disappears. However, the risk of client-side XSS vulnerabilities (WebView) remains. It is imperative to
sanitize all data sent to the <code>executeJS()</code> method to prevent a user from injecting malicious scripts into
the application interface.
</details>
<details>
<summary>Can I manipulate the host system's files?</summary>
Yes, the application has the same read and write permissions as the operating system user who launched it. Unlike a
traditional browser (which is sandboxed), BosonPHP allows you to freely manipulate entire directories using native
functions like <code>file_put_contents()</code> or <code>scandir()</code>.
</details>

            ]]></content:encoded>
        </item><item>
            <title>Native Gradient Interpolation: Mastering the CSS Houdini @property API</title>
            <link>https://lionel-peramo.com/posts/native-gradient-interpolation-css-houdini/</link>
            <guid>https://lionel-peramo.com/posts/native-gradient-interpolation-css-houdini/</guid>
            <pubDate>Thu, 19 Feb 2026 18:00:00 +0000</pubDate>
            <description>A technical analysis of transitioning from opacity hacks to native interpolation. Learn how to use typed variables to animate gradients without DOM complexity.</description>
            <content:encoded><![CDATA[
              <p>⏱️ Reading time: 7 min</p>
              
<p>Browser rendering engines have historically treated CSS gradients as generated images. Since an image is a complex value
rather than a simple numerical unit, the browser cannot calculate a smooth transition between two <code>background-image</code>
states. Without intervention, switching from one color configuration to another is binary and instantaneous, lacking any
fluid interpolation.</p>
<p>The <strong>CSS Houdini API</strong>, specifically through the <code>@property</code> rule, transforms this constraint. It allows developers to
declare typed variables that the CSS engine can interpolate mathematically. This document details how to leverage this
technology to fluidize interfaces while optimizing the rendering pipeline.</p>
<h2>The Architecture of Typed Variables</h2>
<p>A standard CSS variable (Custom Property) is a string of characters with no semantic meaning for the browser. To enable
animation, the nature of the data must be explicitly defined. <code>@property</code> associates a type (<code>syntax</code>) with a variable,
such as an angle or a color.</p>
<h3>Declaration and Registration of Properties</h3>
<p>Property registration must be precise. The <code>inherits: false</code> parameter is critical for performance. It prevents the
variable from unnecessarily propagating down the DOM tree, thereby limiting the scope of style calculations during
transition phases.</p>
<pre><code class="language-css">/* Registration of the animation tokens */
@property --gradient-angle {
  syntax        : '&lt;angle&gt;';
  inherits      : false;
  initial-value : 45deg;
}

@property --gradient-start {
  syntax        : '&lt;color&gt;';
  inherits      : false;
  initial-value : #00f;
}

@property --gradient-end {
  syntax        : '&lt;color&gt;';
  inherits      : false;
  initial-value : #09f;
}

.surface {
  /* Fluid sizing via arithmetic functions, eliminating media queries */
  height             : clamp(15rem, 30vh + 5rem, 40rem);
  width              : 100%;
  margin-block-start : clamp(1rem, 5vw, 3rem);
  position           : relative;
  cursor             : pointer;

  background         : linear-gradient(var(--gradient-angle), var(--gradient-start), var(--gradient-end));
  transition         : --gradient-angle .7s cubic-bezier(.4, 0, .2, 1),
                       --grad-start .7s cubic-bezier(.4, 0, .2, 1),
                       --grad-end .7s cubic-bezier(.4, 0, .2, 1);

  /* Layer isolation for painting optimization */
  contain     : layout paint style;
  will-change : transform;
}

.surface:hover {
  --gradient-angle : 225deg;
  --gradient-start : #f00;
  --gradient-end   : #f70;
}
</code></pre>
<h2>Rendering Pipeline Optimization</h2>
<p>Choosing this technique directly impacts the Critical Rendering Path. Unlike opacity animation, which runs on the
<strong>Compositor (GPU)</strong>, animating gradient properties triggers a <strong>repaint</strong>.</p>
<h3>Managing the Repaint Cycle</h3>
<p>At each frame of the animation, the browser recalculates the pixels of the background image. Although more costly than a
simple layer merge, this process is optimized by two factors:</p>
<ol>
<li><strong>Semantic Isolation:</strong> By declaring <code>inherits: false</code>, you reduce the cost of style recalculation. The browser knows
that modifying the variable does not affect child nodes.</li>
<li><strong>DOM Tree Reduction:</strong> This method eliminates the need for pseudo-elements (<code>::after</code>) or extra tags. A lighter DOM
accelerates all phases of rendering, from parsing to layout.</li>
</ol>
<h2>Responsive Arithmetic and Fluidity</h2>
<p>The use of <code>clamp()</code> allows for the removal of traditional Media Queries. Every <code>@media</code> rule forces the browser to
re-evaluate the CSS cascade during window resizing. By using mathematical functions, size calculation becomes a dynamic
operation performed during the Layout phase.</p>
<p>This approach ensures constant visual stability. It also reduces the total size of the CSS file, speeding up download
and analysis time by the main thread.</p>
<h2>Accessibility and Motion Compliance</h2>
<p>Animating colors and angles can impact users suffering from vestibular disorders or motion sensitivity. Respecting
system preferences is both a technical and ethical necessity.</p>
<pre><code class="language-css">@media (prefers-reduced-motion : reduce) {
  .surface {
    transition : none;
  }
}
</code></pre>
<p>Integrating this media query ensures compliance with international accessibility standards (EAA 2025 / WCAG). It ensures
that the aesthetic of the interface does not become a barrier to navigation.</p>
<h2>SEO Impact and Core Web Vitals</h2>
<p>Perceived and real performance is a major ranking criterion. The use of <code>@property</code> optimizes several key metrics:</p>
<ul>
<li><strong>Largest Contentful Paint (LCP):</strong> Rendering is immediate because it does not depend on loading an external
resource (image). The gradient is generated natively by the graphics engine.</li>
<li><strong>Cumulative Layout Shift (CLS):</strong> Fluid dimension definition via <code>clamp</code> prevents abrupt layout shifts during style
loading.</li>
<li><strong>Total Blocking Time (TBT):</strong> Since the CSS code is more concise and lacks JavaScript logic for animation, the main
thread remains available for user interactions.</li>
</ul>
<h2>Deployment Strategy and Support</h2>
<p>As of 2025, support for <code>@property</code> is widespread across Blink (Chrome, Edge), WebKit (Safari), and Gecko (Firefox)
engines. For environments that do not support Houdini, the browser simply ignores the transition. The user benefits from
a static gradient that changes instantly on hover. This principle of progressive enhancement ensures that the interface
remains functional everywhere while providing a superior experience on modern browsers.</p>
<h2>Conclusion</h2>
<p>The CSS Houdini API redefines how we design graphic transitions. By moving from a hack based on overlapping elements to
a native interpolation of typed variables, we clean up the source code and optimize system resource usage. Mastering
<code>@property</code> allows for the marriage of surgical CSS engineering precision with a fluid and high-performance user
experience.</p>
<hr>
<h3>Technical FAQ</h3>
<details>
<summary>Why is the <code>inherits: false</code> syntax preferable?</summary>
It prevents the browser from checking every child element to see if it uses the modified variable. This saves
significant calculation cycles on pages with a complex DOM.
</details>
<details>
<summary>What is the advantage of <code>will-change: transform</code> here?</summary>
Although we are not directly animating the transform, this property often forces the browser to place the element on
its own GPU layer, isolating "repaint" operations from the rest of the page.
</details>
<details>
<summary>Can gradients with more than two colors be animated?</summary>
Yes. Simply register as many typed properties as necessary and integrate them into the linear-gradient function.
Interpolation will occur on each variable simultaneously.
</details>

            ]]></content:encoded>
        </item><item>
            <title>Animated Border and Glow Effect: How to Code an Ultra-Fast Premium Button</title>
            <link>https://lionel-peramo.com/posts/high-performance-animated-glow-border-css/</link>
            <guid>https://lionel-peramo.com/posts/high-performance-animated-glow-border-css/</guid>
            <pubDate>Wed, 18 Feb 2026 17:30:00 +0000</pubDate>
            <description>Learn how to create a rotating border with a glow effect using pure CSS. A method optimized for performance, SEO, and accessibility without any JavaScript.</description>
            <content:encoded><![CDATA[
              <p>⏱️ Reading time: 8 min</p>
              
<p>Website design should never slow down the user.
A button is the most critical element for conversion.
If it looks good, users want to click.
If it is fast, users feel confident.</p>
<p>Often, light effects (Glow) require many computer resources.
If the code is poorly written, the animation stutters.
We will see how to create a rotating luminous border.
This code uses only CSS to remain ultra-performant.</p>
<h2>The Problem with Poorly Designed Buttons</h2>
<p>Many developers make the mistake of using images or JavaScript to make a button shine.
This causes three problems:</p>
<ol>
<li><strong>Weight</strong>: An animated image is heavy to download.</li>
<li><strong>Readability</strong>: If the effect passes in front of the text, it becomes unreadable.</li>
<li><strong>Slowness</strong>: JavaScript uses the browser’s main processor.</li>
</ol>
<p>Our solution uses <strong>hardware rendering</strong>.
This means the work is done by the graphics card (GPU).
The main processor (CPU) remains free for other site tasks.</p>
<h2>HTML Structure: Simplicity and Efficiency</h2>
<p>For the browser to work fast, it needs simple code.
We use a box (<code>div</code> or <code>button</code>) and a container for the text.
This allows the visual effect to be separated from the actual content.</p>
<pre><code class="language-html">
&lt;div class=box&gt;
  &lt;div class=content&gt;
    &lt;h1&gt;Glowing border&lt;/h1&gt;
    &lt;p&gt;Hover your mouse to animate the border&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;
</code></pre>
<p>Here, we do not use quotes for simple classes like <code>class=box</code>.
This is an optimization that slightly reduces the HTML file size.
Modern browsers understand this code perfectly.</p>
<h2>Step 1: Declaring an Intelligent Variable</h2>
<p>In CSS, we often use variables.
But here, we use a “typed” variable.
We tell the browser that <code>--angle</code> is a unit of rotation measurement.</p>
<pre><code class="language-css">@property --angle {
  syntax        : &quot;&lt;angle&gt;&quot;;
  initial-value : 76deg;
  inherits      : false;
}
</code></pre>
<p><strong>Why is this important?</strong>
Without this, the browser does not know how to smoothly transition from 0 to 360 degrees.
Thanks to <code>@property</code>, the animation is handled mathematically.
This allows for 120 frames per second without any effort.</p>
<h2>Step 2: Fluid Design with <code>clamp</code> and <code>min</code></h2>
<p>We want our box to look good everywhere.
We do not use fixed sizes in pixels.
Instead, we use <code>min()</code> and <code>clamp()</code> functions.</p>
<pre><code class="language-css">.box {
  position    : relative;
  display     : grid;
  place-items : center;
  /* Width adapts between 90% on mobile and 25rem on desktop */
  width       : min(90vw, 25rem);
  height      : auto;
  background  : #012;
  /* Fluid spacing */
  padding     : clamp(.625rem, calc(1.136vw + .3978rem), 1.25rem);
  margin      : 1.25rem;
}
</code></pre>
<p><code>clamp()</code> automatically calculates the best size.
There is no need for complex rules for mobile phones.
This is a win for performance and code maintenance.</p>
<h2>Step 3: Creating Light Layers</h2>
<p>We use two invisible layers behind the box: <code>::before</code> and <code>::after</code>.
The secret is to use a <strong>conic gradient</strong>.</p>
<ol>
<li><strong>The <code>::before</code> layer</strong>: This is the sharp border. It is placed right behind the background.</li>
<li><strong>The <code>::after</code> layer</strong>: This is the glowing halo. It is placed even further back (<code>z-index: -2</code>) and is blurred.</li>
</ol>
<pre><code class="language-css">.box::before, .box::after {
  content    : &quot;&quot;;
  position   : absolute;
  inset      : -3px; /* Border thickness */
  z-index    : -1;
  background : conic-gradient(from var(--angle), #56e0a6, #060c21, #11b9d1, #060c21, #56e0a6);
}

.box::after {
  z-index : -2;
  filter  : blur(20px);
}
</code></pre>
<p>By using <code>inset: -3px</code>, we ask the gradient to slightly overlap the box.
This creates the colored border.</p>
<h2>Step 4: Interaction and Animation</h2>
<p>The effect only activates when the user hovers over the box.
This saves energy.
We use two animations at the same time.
The first rotates the angle.
The second adds a <code>sepia</code> filter to make the light more intense.</p>
<pre><code class="language-css">&amp;:hover::before, &amp;:hover::after {
  animation : glowing-border 3.5s linear infinite;
}

&amp;:hover::after {
  animation-name : glowing-border, blur-effect;
}

@keyframes glowing-border {
  to { --angle : 436deg }
  /* 76deg + 360deg for a full rotation */
}

@keyframes blur-effect {
  to { filter : blur(15px) sepia(.3) }
}
</code></pre>
<p>The <code>sepia</code> filter is very clever.
It slightly changes the hue of the colors.
This gives a more “vivid” and warm look to the button during clicks or hovers.</p>
<h2>Why is this Technique the Fastest?</h2>
<p>There are several ways to draw a border.
But most of them force the browser to recalculate the page’s shape.
This is called <strong>Layout Shift</strong>.</p>
<p>Our method uses only the final <strong>Rendering Process</strong> (Composite).
Since we only modify one variable (<code>--angle</code>) and one filter (<code>blur</code>), the browser does not redo position calculations.
This is the least tiring method for the computer.</p>
<h2>SEO Impact and Core Web Vitals</h2>
<p>SEO is not just text.
It is also the technical quality of your components.
Here is how this button helps your ranking:</p>
<ol>
<li><strong>LCP (Largest Contentful Paint)</strong>: The button is lightweight. It does not block the display of the rest of the page.</li>
<li><strong>INP (Interaction to Next Paint)</strong>: The hover response is instantaneous because it is handled by the GPU. Google
loves fast interactions.</li>
<li><strong>CLS (Cumulative Layout Shift)</strong> : By using <code>aspect-ratio</code> or calculated sizes (<code>height: auto</code>), content does not
jump during loading.</li>
</ol>
<h2>Accessibility: Readability and Movement</h2>
<p>A button must be readable for everyone.
In our example, the text is in a separate layer (<code>.content</code>).
It always remains white on a dark background.
The contrast is excellent, which is vital for visually impaired users.</p>
<p>We must also think of people sensitive to movement.
Some people may feel dizzy with rotating lights.
CSS allows us to automatically disable the animation for them.</p>
<pre><code class="language-css">@media (prefers-reduced-motion : reduce) {
  .box::before, .box::after {
    animation  : none;
    background : #11b9d1; /* A fixed and calm border */
  }
}
</code></pre>
<h2>Performance Optimization: Avoiding Overrides</h2>
<p>In our code, we do not use complicated selectors.
We use CSS nesting (<code>&amp;::before</code>).
This allows the browser to read the code faster.
If you need multiple variants, use <code>:not()</code>.
For example: <code>.box:not(.no-animation)</code>.
This avoids forcing the browser to cancel styles that have already been calculated.</p>
<h2>Conclusion: The Power of Modern CSS</h2>
<p>Creating “Premium” interfaces does not require heavy libraries.
With a few well-thought-out lines of CSS, you get:</p>
<ul>
<li>Fluid animation at 120 FPS.</li>
<li>A perfect performance score on Lighthouse.</li>
<li>A pleasant and interactive user experience.</li>
</ul>
<p>Performance is not the enemy of design.
It is the engine that allows design to be appreciated by everyone.
Every millisecond of calculation saved is a victory for your SEO and the planet.</p>
<hr>
<h3>Frequently Asked Questions (FAQ)</h3>
<details>
<summary>Why use 436deg in the animation?</summary>
We start at 76deg. To make a full 360deg turn, we must reach 436deg (76 + 360 = 436). This allows for a perfect loop
without a visual jump.
</details>
<details>
<summary>Does the sepia filter slow down the site?</summary>
No, because it is only applied during hover. The rest of the time, the browser performs no calculations on this filter.
</details>
<details>
<summary>Can I put long text in this box?</summary>
Yes. Thanks to <code>height: auto</code> and fluid <code>padding</code>, the box will grow with your text without
breaking the border effect.
</details>
<details>
<summary>How do I change the border color?</summary>
Simply change the color codes in the <code>conic-gradient</code>. You can put as many colors as you want to create a
rainbow or bicolor effect.
</details>

            ]]></content:encoded>
        </item><item>
            <title>Optimizing Conversion: The Complete Guide to the HTML autocomplete Attribute</title>
            <link>https://lionel-peramo.com/posts/optimizing-conversion-autocomplete-html-guide/</link>
            <guid>https://lionel-peramo.com/posts/optimizing-conversion-autocomplete-html-guide/</guid>
            <pubDate>Mon, 16 Feb 2026 17:45:00 +0000</pubDate>
            <description>Discover how the autocomplete attribute transforms your forms. A technical guide focused on HTML to reduce friction, improve accessibility, and boost your sales by 20%.</description>
            <content:encoded><![CDATA[
              <p>⏱️ Reading time: 9 min</p>
              
<p>On the internet, friction is the number one enemy. Every field a user must fill manually is an opportunity for them to
leave your site. This is called form abandonment. For an e-commerce site or an online service, this represents a direct
loss of money.</p>
<p>However, there is a free, native, and extremely high-performance technical solution: the <code>autocomplete</code> attribute.
According to figures from <a href="https://www.zuko.io/blog/does-browser-autofill-affect-form-conversion-rate">Zuko</a>, <strong>correctly using auto-completion increases form success rates from 59% to 71%</strong>.</p>
<p>This guide explains how to transform your forms using only HTML.</p>
<h2>Why autocomplete changes everything?</h2>
<p>Filling out a form requires significant effort, especially on a mobile phone. The user must click the field, wait for
the keyboard to appear, type their information without mistakes, and then move to the next field.</p>
<p>The <code>autocomplete</code> attribute allows the browser to do all this work for the user. In a fraction of a second, the browser
identifies the data stored in its system and offers to fill the entire form at once.</p>
<h3>The difference between “heuristic” and “semantic”</h3>
<p>If you don’t use the <code>autocomplete</code> attribute, the browser tries to guess what it should fill. This is called
<strong>heuristics</strong>. It looks at the field name (<code>name=prenom</code>) or the surrounding text. But browsers often make mistakes,
especially if your site is translated into several languages.</p>
<p>By adding <code>autocomplete</code>, you provide a <strong>semantic</strong> instruction. You tell the browser: “This field is exactly for the
first name.” There is no more room for error. The performance gain is immediate because the browser no longer needs to
analyze your code to guess your intentions.</p>
<h2>1. User Identity</h2>
<p>This is the basis of every form. For the browser to suggest the correct information, you must use standard tokens.</p>
<p>Here is a code example optimized for identity:</p>
<pre><code class="language-html">
&lt;div class=form-group&gt;
  &lt;label for=first-name&gt;First Name&lt;/label&gt;
  &lt;input id=first-name name=fname type=text autocomplete=given-name required&gt;
&lt;/div&gt;

&lt;div class=form-group&gt;
  &lt;label for=last-name&gt;Last Name&lt;/label&gt;
  &lt;input id=last-name name=lname type=text autocomplete=family-name required&gt;
&lt;/div&gt;

&lt;div class=form-group&gt;
  &lt;label for=nickname&gt;Username&lt;/label&gt;
  &lt;input id=nickname name=user type=text autocomplete=nickname&gt;
&lt;/div&gt;

&lt;div class=form-group&gt;
  &lt;label for=job-title&gt;Job Position&lt;/label&gt;
  &lt;input id=job-title name=position type=text autocomplete=organization-title&gt;
&lt;/div&gt;
</code></pre>
<h3>Why separate first and last names?</h3>
<p>Some forms use a single “Full Name” field. This is an error for auto-completion performance. Browsers often store first
and last names separately. By using <code>given-name</code> and <code>family-name</code>, you guarantee perfect filling.</p>
<h2>2. Contact details</h2>
<p>Typing errors in email addresses or phone numbers are the leading causes of account creation failure. Auto-completion
eliminates this risk.</p>
<pre><code class="language-html">&lt;!-- Contact details optimized for mobile interaction --&gt;
&lt;div class=form-group&gt;
  &lt;label for=user-email&gt;Email Address&lt;/label&gt;
  &lt;input id=user-email name=email type=email autocomplete=email required&gt;
&lt;/div&gt;

&lt;div class=form-group&gt;
  &lt;label for=user-phone&gt;Phone Number&lt;/label&gt;
  &lt;input id=user-phone name=phone type=tel autocomplete=tel&gt;
&lt;/div&gt;
</code></pre>
<p><strong>Technical note:</strong> Always use <code>type=email</code> and <code>type=tel</code> in addition to autocomplete. This allows smartphones to
display the correct keyboard (numeric keypad for phone), which further increases input speed.</p>
<h2>3. Shipping Address: The e-commerce challenge</h2>
<p>The address is the longest part to fill. It often contains five or six different fields. This is where the impact on
conversion is strongest.</p>
<pre><code class="language-html">&lt;!-- Shipping address tokens for e-commerce performance --&gt;
&lt;div class=form-group&gt;
  &lt;label for=street&gt;Street Address&lt;/label&gt;
  &lt;input id=street name=addr1 type=text autocomplete=&quot;shipping street-address&quot;&gt;
&lt;/div&gt;

&lt;div class=form-group&gt;
  &lt;label for=city&gt;City&lt;/label&gt;
  &lt;input id=city name=city type=text autocomplete=&quot;shipping address-level2&quot;&gt;
&lt;/div&gt;

&lt;div class=form-group&gt;
  &lt;label for=zip&gt;Zip Code&lt;/label&gt;
  &lt;input id=zip name=zip type=text autocomplete=&quot;shipping postal-code&quot;&gt;
&lt;/div&gt;

&lt;div class=form-group&gt;
  &lt;label for=country&gt;Country&lt;/label&gt;
  &lt;input id=country name=country type=text autocomplete=&quot;shipping country&quot;&gt;
&lt;/div&gt;
</code></pre>
<p>By adding the word <code>shipping</code> before the token (e.g., <code>shipping postal-code</code>), you indicate to the browser that this is
the delivery address. If it is the billing address, use <code>billing</code>. This allows the browser to offer two different
addresses if the user has saved them.</p>
<h2>4. Payments and Security</h2>
<p>Filling in credit card numbers is stressful for the user. By automating this step, you reduce anxiety and speed up the
payment.</p>
<pre><code class="language-html">&lt;!-- Payment fields with secure native autocomplete --&gt;
&lt;div class=form-group&gt;
  &lt;label for=card-num&gt;Card Number&lt;/label&gt;
  &lt;input id=card-num name=cnum type=text autocomplete=cc-number&gt;
&lt;/div&gt;

&lt;div class=form-group&gt;
  &lt;label for=card-name&gt;Name on Card&lt;/label&gt;
  &lt;input id=card-name name=cname type=text autocomplete=cc-name&gt;
&lt;/div&gt;

&lt;div class=form-group&gt;
  &lt;label for=card-exp&gt;Expiry Date&lt;/label&gt;
  &lt;input id=card-exp name=cexp type=text autocomplete=cc-exp&gt;
&lt;/div&gt;
</code></pre>
<p>Contrary to popular belief, this is <strong>more secure</strong>. The user does not need to take out their card in a public place.
The browser protects this data with a password or fingerprint (TouchID/FaceID).</p>
<h2>5. Password Management</h2>
<p>This is one of the most critical points. Poor autocomplete configuration can block a user trying to log in.</p>
<ul>
<li><strong>For Login</strong>: Use <code>autocomplete=current-password</code>.</li>
<li><strong>For Registration</strong>: Use <code>autocomplete=new-password</code>.</li>
</ul>
<p>This tells the password manager whether to suggest an old code or generate a new one securely.</p>
<h2>6. Accessibility (WCAG): A right for everyone</h2>
<p>Web accessibility is not just for the blind. It also concerns people with motor impairments (difficulty typing) or
cognitive impairments (difficulty remembering their own information).</p>
<p>The <strong>WCAG 2.1</strong> standard requires identifying the purpose of the input (criterion 1.3.5). The <code>autocomplete</code> attribute
is the official solution to comply with this rule. Without it, your site may be considered non-compliant with
accessibility laws.</p>
<h2>7. Performance: Why native always wins?</h2>
<p>Many sites use heavy JavaScript scripts to help with input (address search via API). While these tools are useful, they
slow down the page. They require time to load the script and execute the code.</p>
<p>The HTML <code>autocomplete</code> attribute has a performance cost of <strong>zero</strong>.</p>
<ol>
<li>No additional network request.</li>
<li>No CPU calculation time.</li>
<li>Works even if the network is slow or if JavaScript is blocked.</li>
</ol>
<h2>Absolute mistakes to avoid</h2>
<ul>
<li><strong>Abuse of autocomplete=off</strong>: Some developers think they increase security by forbidding auto-completion. It’s the
opposite. You force the user to use simple passwords to remember them.</li>
<li><strong>Fancy field names</strong>: If you use <code>name=field_1</code>, the browser will struggle to understand without the <code>autocomplete</code>
attribute. Always be explicit.</li>
</ul>
<h2>Conclusion</h2>
<p>Form optimization is not about adding complex features, but about the intelligent use of web standards. The
<code>autocomplete</code> attribute is the most powerful tool to improve user experience without any compromise on performance.</p>
<p>As a developer or site manager, your mission is to reduce your visitors’ effort. A form that fills itself is a form that
converts.</p>
<hr>
<h3>FAQ</h3>
<details>
<summary>Is autocomplete available on all browsers?</summary>
Yes, it is a standard supported by all modern browsers (Chrome, Safari, Edge, Firefox). Even very old browsers simply ignore the attribute without ever crashing the site.
</details>
<details>
<summary>Can autocomplete fill dropdown menus (select)?</summary>
Yes, perfectly! You can add the <code>autocomplete</code> attribute to a <code>select</code> tag, for example, for the choice of country or state.
</details>
<details>
<summary>Can the user disable this feature?</summary>
Yes, the user always maintains control in their browser settings. But the vast majority of internet users use it because it makes their lives easier.
</details>

            ]]></content:encoded>
        </item><item>
            <title>Mastering AbortController in JavaScript: The Guide to High-Performance Requests</title>
            <link>https://lionel-peramo.com/posts/mastering-javascript-abortcontroller-high-performance-requests/</link>
            <guid>https://lionel-peramo.com/posts/mastering-javascript-abortcontroller-high-performance-requests/</guid>
            <pubDate>Thu, 12 Feb 2026 12:00:00 +0000</pubDate>
            <description>Learn how to use AbortController to cancel fetch requests, handle native timeouts, and optimize the memory of your JS applications.</description>
            <content:encoded><![CDATA[
              <p>⏱️ Reading time: 9 min</p>
              
<p>Modern <strong>web</strong> development relies almost exclusively on asynchrony. Whether fetching data via an API, loading modules on
the fly, or managing streaming flows, the <code>fetch()</code> function has become the universal tool. However, a crucial question
is often ignored: what happens when the user leaves a page before the loading finishes?</p>
<p>Without control, you create “zombie requests.” These processes continue to consume bandwidth and processor resources (
CPU) in the background, even if the result is no longer needed. This is where <strong>AbortController</strong> comes in.</p>
<p>In this expert guide, we will break down how this API transforms the management of your requests to achieve an optimal
level of <strong>performance</strong> and digital sobriety.</p>
<h2>The Problem of Orphaned Requests</h2>
<p>Imagine a “search-as-you-type” interface. For every character typed, a <code>fetch()</code> request is launched. If the user
types “JavaScript” quickly, seven or eight requests can be sent to the server. If the early requests arrive after the
last one, they might overwrite the most recent data in your interface (a <em>race condition</em> problem).</p>
<p>Previously, canceling a promise was complex, if not impossible to do cleanly. The introduction of <strong>AbortController</strong> in
2018 radically changed the game by providing a standardized way to interrupt any asynchronous process.</p>
<h2>Anatomy of AbortController</h2>
<p>The object consists of two distinct but linked parts:</p>
<ol>
<li><strong>The Controller:</strong> The object that holds the power to cancel.</li>
<li><strong>The Signal:</strong> The token passed to asynchronous functions so they know when to stop.</li>
</ol>
<p>Here is the simplest implementation:</p>
<pre><code class="language-js">const
  controller = new AbortController(),
  signal = controller.signal;

// Triggers cancellation
controller.abort();
</code></pre>
<h2>Canceling a <code>fetch</code> Request: A Practical Case</h2>
<p>To cancel a <code>fetch()</code>, simply pass the <code>signal</code> in the request’s options object.</p>
<pre><code class="language-js">async function fetchData(url)
{
  const controller = new AbortController();

  try
  {
    const response = await fetch(url, {signal: controller.signal});
    return await response.json();
  } catch (error)
  {
    if (error.name === 'AbortError')
      console.warn('Fetch request was cancelled by the user.');
    else
      console.error('A network error occurred:', error);
  }
}
</code></pre>
<h3>Why Is It Vital for Performance?</h3>
<p>By calling <code>abort()</code>, the <strong>browser</strong> immediately cuts the TCP connection. You instantly save battery on mobile devices
and free up RAM that won’t be used to process a useless response.</p>
<h2>Native Timeout Management: Goodbye Manual <code>setTimeout</code></h2>
<p>One of the greatest recent advancements (Baseline 2023) is the static <code>AbortSignal.timeout()</code> method. It allows you to
set a time limit for an operation without having to manage complex counters yourself.</p>
<pre><code class="language-js">async function fetchWithTimeout(url, ms)
{
  try
  {
    // Automatically aborts after 'ms' milliseconds
    const response = await fetch(url, {signal: AbortSignal.timeout(ms)});
    return await response.json();
  } catch (error)
  {
    if (error.name === 'TimeoutError')
      console.error('The request took too long and timed out.');
  }
}
</code></pre>
<p>This approach is much more robust than old “hacks” using <code>Promise.race()</code>, because it actually cancels the network
request instead of simply ignoring its result.</p>
<h2>Advanced Usage: AbortSignal.any()</h2>
<p>In 2026, we often have to handle cancellations from multiple sources (a “Cancel” button AND an automatic timeout). The
<code>AbortSignal.any()</code> method allows combining several signals. The first signal to activate triggers the global
cancellation.</p>
<pre><code class="language-js">async function robustFetch(url)
{
  const
    userController = new AbortController(),
    timeoutSignal = AbortSignal.timeout(5000),
    // Combine signals: aborts if user clicks OR if 5s elapse
    combinedSignal = AbortSignal.any([
      userController.signal,
      timeoutSignal
    ]);

  return fetch(url, {signal: combinedSignal});
}
</code></pre>
<h2>State Management and User Feedback</h2>
<p>Canceling an asynchronous task should not come at the expense of clarity. An interface that remains frozen after
clicking “Cancel” is a UX error. The logic resides in state transitions driven by JavaScript and reflected by robust *
<em>CSS</em>*.</p>
<pre><code class="language-js">async function handleActionWithFeedback(controller)
{
  const btn = document.getElementById('action-btn');
  btn.classList.add('is-loading');

  try
  {
    await performHeavyTask(controller.signal);
  } catch (err)
  {
    if (err.name === 'AbortError')
      btn.classList.replace('is-loading', 'is-cancelled');
  }
}
</code></pre>
<p>To accompany this logic, I use a fluid design that ensures my status indicators remain readable on any screen, without
multiplying media queries:</p>
<pre><code class="language-css">.status-indicator {
  /* Fluid typography: min 14px, max 20px based on viewport width */
  font-size : clamp(0.875rem, 1.2vw + 0.5rem, 1.25rem);
  padding   : clamp(0.5rem, 2vh, 1.5rem);

  /* Target only end states without overriding the base */
  &amp;:not(.is-loading, .is-success) {
    background-color : var(--background-soft);
    filter           : grayscale(1);
    opacity          : 0.7;
  }
}
</code></pre>
<h2>AbortController Beyond the Network: Event Listeners</h2>
<p><strong>AbortController</strong> is not reserved for network requests. You can use it to clean up your Event Listeners all at once.
This is a major technique for avoiding memory leaks in Single Page Applications (SPA).</p>
<pre><code class="language-js">const menuController = new AbortController();

window.addEventListener('resize', handleResize, {signal: menuController.signal});
window.addEventListener('scroll', handleScroll, {signal: menuController.signal});

// Clean up everything at once
function destroyComponent()
{
  menuController.abort();
}
</code></pre>
<h2>Performance and Eco-design: The Virtuous Circle</h2>
<p>On this blog, I often advocate for <strong>digital sobriety</strong>. <strong>AbortController</strong> is one of its best technical ambassadors:</p>
<ul>
<li><strong>Server Traffic Reduction:</strong> Fewer useless requests processed by your PHP or Node.js backend.</li>
<li><strong>Data Economy:</strong> Crucial for users with limited plans or in low network coverage areas (3G/Edge).</li>
<li><strong>Display Fluidity:</strong> By cutting useless processing (JSON parsing, DOM manipulations), you avoid jank and allow the
browser to maintain a smooth 60 FPS rendering.</li>
</ul>
<h2>SEO Strategy and Accessibility</h2>
<p>While request cancellation is a background task, it indirectly impacts your <strong>SEO</strong>. Google analyzes the visual
stability and response speed of your pages (Core Web Vitals). A site that doesn’t manage its zombie requests ends up
lagging, degrading the <strong>LCP (Largest Contentful Paint)</strong> score.</p>
<p>On the accessibility side, ensure that when an operation is canceled by a timeout, the user is informed via an
<code>aria-live</code> region.</p>
<pre><code class="language-js">const statusEl = document.getElementById('status-message');

if (error.name === 'AbortError')
{
  statusEl.textContent = 'Loading interrupted.';
  statusEl.setAttribute('aria-live', 'polite');
}
</code></pre>
<h2>Conclusion: Toward Responsible Code</h2>
<p><strong>AbortController</strong> is not an option; it is a necessity for any developer aiming for technical excellence. It allows you
to move from code that suffers from asynchrony to code that directs it. In 2026, the quality of an application is judged
not only by what it displays but by the cleanliness with which it handles what it no longer displays.</p>
<p>Take back control, cancel the superfluous, and build a faster, more human web.</p>
<hr>
<h3>Frequently Asked Questions</h3>
<details>
<summary>Is the cancellation reversible?</summary>
No. Once a signal has transitioned to the "aborted" state, it cannot go back. To restart an operation, you must create a new instance of <strong>AbortController</strong>.
</details>
<details>
<summary>Can I cancel synchronous code with this API?</summary>
Not natively. <strong>AbortController</strong> is designed for asynchronous APIs that accept an <code>AbortSignal</code>. For synchronous code (like a massive <code>for</code> loop), you must manually check the <code>signal.aborted</code> property at each iteration.
</details>
<details>
<summary>What is the browser support in 2026?</summary>
Support is at <strong>95.78%</strong> (data as of <time datetime="2026-02-11T18:00:00+00:00">February 11, 2026</time>, subject to change). You can check the current support status on <a href="https://caniuse.com/?search=abortController">CanIUse</a>. All modern browsers (Chrome, Firefox, Safari, Edge) as well as Node.js and Deno support AbortController natively. For very old environments, lightweight polyfills exist.
</details>

            ]]></content:encoded>
        </item><item>
            <title>Web Accessibility Audit: A Critical Guide to 11 Essential Tools (WCAG &amp; EAA 2025)</title>
            <link>https://lionel-peramo.com/posts/web-accessibility-audit-tools/</link>
            <guid>https://lionel-peramo.com/posts/web-accessibility-audit-tools/</guid>
            <pubDate>Wed, 11 Feb 2026 11:30:00 +0000</pubDate>
            <description>Critical and detailed analysis of 11 accessibility tools (Axe, WAVE, NVDA, Stark). Understand their strengths, weaknesses, and their role in WCAG and EAA 2025 compliance.</description>
            <content:encoded><![CDATA[
              <p>⏱️ Reading time: 11 min</p>
              
<p>Accessibility is not just a checkbox; it is a <strong>software quality</strong> assurance process. Even the best intentions can fail
if they are not backed by rigorous tools and a clear audit methodology.</p>
<p>An audit tool does only one thing: it helps you validate the technical application of <strong>WCAG</strong> rules. It will never
replace your <strong>developer</strong> judgment. For this reason, it is essential to know the strengths and limits of each
instrument.</p>
<p>This guide is a critical examination of the <strong>11 essential tools</strong> to ensure the compliance of your projects, especially
in view of the <strong>European Accessibility Act (EAA 2025)</strong>.</p>
<h2>1. Automated Analysis Tools (CI/CD Integration)</h2>
<h3>A. Axe Accessibility (Deque Systems) — The Industrial Standard</h3>
<table>
<thead>
<tr>
<th align="left">Feature</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><strong>Format</strong></td>
<td align="left"><strong>Browser</strong> extension (DevTools), <strong>Node.js</strong> library (<code>axe-core</code>).</td>
</tr>
<tr>
<td align="left"><strong>Site</strong></td>
<td align="left"><a href="https://www.deque.com/axe/">deque.com/axe</a></td>
</tr>
<tr>
<td align="left"><strong>Strengths</strong></td>
<td align="left"><strong>Extremely reliable.</strong> Almost zero false positives. Focuses on clear technical issues (e.g., misspelled <strong>ARIA</strong> roles).</td>
</tr>
<tr>
<td align="left"><strong>Weaknesses</strong></td>
<td align="left"><strong>Limited coverage (~40% of WCAG).</strong> Misses issues requiring human judgment (e.g., meaningful <code>alt</code> text).</td>
</tr>
<tr>
<td align="left"><strong>Pro usage</strong></td>
<td align="left">Integrate <code>axe-core</code> into tests to block the deployment of non-compliant components.</td>
</tr>
</tbody>
</table>
<h3>B. WAVE (WebAIM) — The Educational Evaluation Tool</h3>
<table>
<thead>
<tr>
<th align="left">Feature</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><strong>Format</strong></td>
<td align="left"><strong>Browser</strong> extension and online web service.</td>
</tr>
<tr>
<td align="left"><strong>Site</strong></td>
<td align="left"><a href="https://wave.webaim.org/">wave.webaim.org</a></td>
</tr>
<tr>
<td align="left"><strong>Strengths</strong></td>
<td align="left"><strong>Instant visualization.</strong> Overlays icons directly on your <strong>page</strong> to spot errors (missing titles, <strong>forms</strong> without labels).</td>
</tr>
<tr>
<td align="left"><strong>Weaknesses</strong></td>
<td align="left">Less precise than Axe. Can produce too many “Structure” or “Best Practice” alerts.</td>
</tr>
<tr>
<td align="left"><strong>Pro usage</strong></td>
<td align="left"><strong>Quick check</strong> to raise team awareness or verify the visual flow of the <strong>page</strong>.</td>
</tr>
</tbody>
</table>
<h3>C. Lighthouse (Chrome DevTools) — The Global Score Audit</h3>
<table>
<thead>
<tr>
<th align="left">Feature</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><strong>Format</strong></td>
<td align="left">Native tab integrated into Chrome and Edge development tools (F12).</td>
</tr>
<tr>
<td align="left"><strong>Strengths</strong></td>
<td align="left"><strong>360° Vision.</strong> The only tool linking accessibility, <strong>performance</strong> (Core Web Vitals), and <strong>SEO</strong> in one report.</td>
</tr>
<tr>
<td align="left"><strong>Weaknesses</strong></td>
<td align="left"><strong>Less granular.</strong> Uses the Axe engine but with fewer options. Scores can be misleading if manual barriers remain.</td>
</tr>
<tr>
<td align="left"><strong>Pro usage</strong></td>
<td align="left"><strong>Sanity Check.</strong> Use it to ensure no major regressions across performance and accessibility before launch.</td>
</tr>
</tbody>
</table>
<h2>2. Manual Testing Tools</h2>
<h3>A. Screen Readers (NVDA and VoiceOver)</h3>
<table>
<thead>
<tr>
<th align="left">Feature</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><strong>Format</strong></td>
<td align="left"><strong>NVDA</strong> (Free software for Windows), <strong>VoiceOver</strong> (Built into macOS/iOS).</td>
</tr>
<tr>
<td align="left"><strong>Site</strong></td>
<td align="left"><a href="https://www.nvaccess.org/">NVDA</a> &amp; <a href="https://www.apple.com/accessibility/vision/">VoiceOver</a></td>
</tr>
<tr>
<td align="left"><strong>Strengths</strong></td>
<td align="left"><strong>The ultimate test.</strong> Only way to verify if the meaning of your <strong>HTML</strong> and <strong>ARIA</strong> tags is truly understood by the user.</td>
</tr>
<tr>
<td align="left"><strong>Weaknesses</strong></td>
<td align="left">Learning curve for <strong>developers</strong>. Audit time is significantly longer.</td>
</tr>
<tr>
<td align="left"><strong>Pro usage</strong></td>
<td align="left"><strong>Mandatory</strong> for testing complex widgets (menus, <strong>combobox</strong>, modal windows).</td>
</tr>
</tbody>
</table>
<h3>B. Keyboard Navigation (The Tab Key)</h3>
<table>
<thead>
<tr>
<th align="left">Feature</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><strong>Format</strong></td>
<td align="left">Native to any <strong>browser</strong>.</td>
</tr>
<tr>
<td align="left"><strong>Strengths</strong></td>
<td align="left"><strong>Zero tools required.</strong> Validates logical navigation order and identifies elements unreachable via keyboard.</td>
</tr>
<tr>
<td align="left"><strong>Weaknesses</strong></td>
<td align="left">Provides no information about what is read by a screen reader.</td>
</tr>
<tr>
<td align="left"><strong>Pro usage</strong></td>
<td align="left">Manage focus movement with <code>tabindex</code> and the <strong><code>inert</code></strong> attribute for modals.</td>
</tr>
</tbody>
</table>
<h2>3. Design and Contrast Validation Tools</h2>
<h3>A. Color Contrast Analyzer (TPGi)</h3>
<table>
<thead>
<tr>
<th align="left">Feature</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><strong>Format</strong></td>
<td align="left">Simple desktop application (includes an eyedropper).</td>
</tr>
<tr>
<td align="left"><strong>Site</strong></td>
<td align="left"><a href="https://www.tpgi.com/color-contrast-checker/">tpgi.com/color-contrast-checker</a></td>
</tr>
<tr>
<td align="left"><strong>Strengths</strong></td>
<td align="left">Measures exact contrast ratios anywhere on your screen (web page or Figma mockups).</td>
</tr>
<tr>
<td align="left"><strong>Weaknesses</strong></td>
<td align="left"><strong>Manual check</strong>: cannot scan a whole site at once; each color combination must be tested individually.</td>
</tr>
<tr>
<td align="left"><strong>Pro usage</strong></td>
<td align="left">Final validation of <strong>4.5:1 (WCAG AA)</strong> contrast ratio for text.</td>
</tr>
</tbody>
</table>
<h3>C. Stark (Figma/Sketch Plugin) — Design Integration</h3>
<table>
<thead>
<tr>
<th align="left">Feature</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><strong>Format</strong></td>
<td align="left">Plugin for Figma, Sketch, or Adobe XD.</td>
</tr>
<tr>
<td align="left"><strong>Site</strong></td>
<td align="left"><a href="https://www.getstark.co/">getstark.co</a></td>
</tr>
<tr>
<td align="left"><strong>Strengths</strong></td>
<td align="left"><strong>Anticipation.</strong> Check contrast <em>while</em> designing mockups, before any <strong>development</strong> begins.</td>
</tr>
<tr>
<td align="left"><strong>Weaknesses</strong></td>
<td align="left">Some advanced features require a paid subscription.</td>
</tr>
<tr>
<td align="left"><strong>Pro usage</strong></td>
<td align="left">Build an accessibility culture from the very start of the project.</td>
</tr>
</tbody>
</table>
<h2>4. Journey Audit Tools</h2>
<h3>A. Tanaguru — User Journey Audit</h3>
<table>
<thead>
<tr>
<th align="left">Feature</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><strong>Format</strong></td>
<td align="left">Online platform (free and paid options).</td>
</tr>
<tr>
<td align="left"><strong>Site</strong></td>
<td align="left"><a href="https://tanaguru.com/">tanaguru.com</a></td>
</tr>
<tr>
<td align="left"><strong>Strengths</strong></td>
<td align="left"><strong>Comprehensive analysis.</strong> Tests a sequence of actions across multiple pages. Ideal for checkout or registration flows.</td>
</tr>
<tr>
<td align="left"><strong>Weaknesses</strong></td>
<td align="left">Requires more setup time than browser extensions.</td>
</tr>
<tr>
<td align="left"><strong>Pro usage</strong></td>
<td align="left">Verification of <strong>EAA 2025</strong> compliance for critical user journeys.</td>
</tr>
</tbody>
</table>
<h2>Conclusion: Accessibility is a Quality Metric</h2>
<p>Mastering these <strong>tools</strong> allows you to offload low-level validation from <strong>development</strong> to focus on <strong>complex
semantics</strong> and <strong>UX</strong>. By combining automation (Axe) with manual testing (NVDA), you guarantee not only <strong>WCAG</strong>
compliance but also a truly superior experience for every user.</p>
<p>In 2026, accessibility is the new indicator of <strong>performance</strong> and technical rigor.</p>
<hr>
<h3>Frequently Asked Questions</h3>
<details>
<summary>Which tool should be integrated into a CI/CD pipeline for accessibility?</summary>
The <strong><code>axe-core</code></strong> library is the standard choice. It is ultra-fast and designs its tests for
minimum false positives, guaranteeing that the <em>build</em> will only be broken in case of a proven technical error on
the <strong>HTML</strong> or <strong>ARIA</strong>.
</details>
<details>
<summary>How to test LCP (Largest Contentful Paint) for accessibility?</summary>
LCP is a <strong>performance</strong> metric. Accessibility techniques encourage the use of native <strong>semantic
HTML</strong> rather than heavy <strong>JavaScript</strong>. This native sobriety mechanically leads to better LCP
scores. Use <strong>Lighthouse</strong> for measurement.
</details>
<details>
<summary>Is the HTML inert attribute supported everywhere?</summary>
The <strong><code>inert</code></strong> attribute has been part of the "Baseline" since 2024 and is now widely supported
by modern <strong>browsers</strong> (Chrome, Edge, Safari, Firefox). It is safe to use to improve
<strong>accessibility</strong> and keyboard <strong>focus</strong> without external scripts.
</details>

            ]]></content:encoded>
        </item><item>
            <title>CSS Media Queries and Accessibility: The Complete Guide for an Inclusive Web</title>
            <link>https://lionel-peramo.com/posts/css-media-queries-accessibility/</link>
            <guid>https://lionel-peramo.com/posts/css-media-queries-accessibility/</guid>
            <pubDate>Mon, 02 Feb 2026 21:30:00 +0000</pubDate>
            <description>Learn how to use CSS media queries to build sites that adapt to everyone. A simple, high-performance guide to respecting your users&#039; preferences.</description>
            <content:encoded><![CDATA[
              <p>⏱️ Reading time: 8 min</p>
              
<p>Web accessibility is often seen as a technical chore. We tend to think it is only about complying with laws like the
<strong>EAA 2025</strong>. In reality, accessibility is a mark of quality. An accessible site is better built and faster for
everyone.</p>
<p>In 2026, we have precision tools to help users: <strong>Preference Media Queries</strong>. These lines of code detect settings chosen
by users on their phones or computers. The site can then change its look automatically.</p>
<p>In this guide, we will explore 7 essential media queries. We will learn how to code for maximum performance while
remaining compatible with all browsers.</p>
<h2>A Golden Rule: Progressive Enhancement</h2>
<p>Before coding, you must understand an important rule. Do not build a heavy site and then try to “fix” it for people with
disabilities. Do the opposite.</p>
<p>Use the <strong>Progressive Enhancement</strong> logic:</p>
<ol>
<li>First, create a simple, static, and easy-to-read base. This is the version for everyone.</li>
<li>Add animations or visual effects only if the user has not requested restrictions.</li>
</ol>
<p>To achieve this, we often use the <code>no-preference</code> value.</p>
<h2>1. <code>prefers-reduced-motion</code>: mastering movement</h2>
<p>Some people experience dizziness or nausea when there is too much movement on the screen. These are called vestibular
disorders. About 35% of adults over 40 are affected by these disorders, according to a
<a href="https://pubmed.ncbi.nlm.nih.gov/19468085/">study published by the National Institutes of Health</a>.</p>
<p>Unfortunately, since support is currently limited on some browsers, we cannot condition everything via this media query.
If a browser does not support it, no style will be applied. To avoid this, we define a static base and then add the
animation inside the media query block. We will therefore have two contradictory orders when the value is
“no-preference,” but that is the price of compatibility.</p>
<h3>The high-performance method:</h3>
<pre><code class="language-css">/* Static and lightweight base for everyone */
.my-title {
  transform: none;
}

/* Animation is only enabled if the user accepts movement */
@media (prefers-reduced-motion: no-preference) {
  .my-title {
    animation: 1s slide-in forwards;
  }
  
  :root {
    scroll-behavior: smooth;
  }
}
</code></pre>
<h2>2. <code>prefers-color-scheme</code>: native dark mode</h2>
<p>This is likely the most well-known media query. It detects whether the user has chosen a light or dark theme in their
device settings.</p>
<p>Using <code>prefers-color-scheme</code> is essential for visual comfort. It is also a gesture for the planet: on modern (OLED)
screens, displaying black consumes less energy.</p>
<h3>Optimize with light-dark()</h3>
<p>To go further and simplify your code, you can combine this query with the new <code>light-dark()</code> function. It allows you to
manage two colors in a single line of code.</p>
<p>To understand how to use it and boost your rendering performance, read my
<a href="/posts/guide-css-light-dark-mode/">complete guide on the light-dark() function and eco-design</a>.</p>
<h2>3. <code>prefers-contrast</code>: visual clarity</h2>
<p>Not everyone perceives contrasts the same way. With age or certain vision conditions (like cataracts), light gray text
on a white background becomes unreadable.</p>
<h3>Implementation:</h3>
<pre><code class="language-css">.my-card {
  border: 1px solid #ccc;
}

@media (prefers-contrast: more) {
  .my-card {
    border: 2px solid #000; /* Thicker, black border */
    box-shadow: none;       /* Remove shadows that blur vision */
  }
}
</code></pre>
<h2>4. <code>forced-colors</code>: visual survival mode</h2>
<p>On Windows, “High Contrast” mode replaces your colors with a palette chosen by the system. In this case, your background
colors disappear. You must ensure that your elements remain visible through their borders.</p>
<p>It is useless to fight against this mode. You must embrace it by using system color keywords.</p>
<pre><code class="language-css">@media (forced-colors: active) {
  .action-button {
    /* Force a border that adapts to system colors */
    outline: 2px solid ButtonText;
    border: 1px solid ButtonText;
  }
}
</code></pre>
<p>To see all available codes, check the
<a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/system-color">system colors list on MDN</a>. This
guarantees that your buttons will never be invisible.</p>
<h2>5. <code>inverted-colors</code>: respecting system inversion</h2>
<p>Some visually impaired users invert all their screen colors to read better (white becomes black, blue becomes orange).
The problem is that your photos also become unreadable “negatives.” The <code>inverted-colors</code> query allows you to fix this.</p>
<pre><code class="language-css">@media (inverted-colors: inverted) {
  img, video {
    /* Re-invert images to make them look natural again */
    filter: invert(100%);
  }
}
</code></pre>
<h2>6. <code>prefers-reduced-transparency</code>: avoiding visual fatigue</h2>
<p>Blur effects (Glassmorphism) are pretty but tire the brains of people with attention disorders or reading difficulties.
Text becomes blurry on a transparent background.</p>
<p>Since Firefox does not yet handle this option, we use the same logic as for movement: a solid base style, and the visual
effect added only for those without restrictions.</p>
<pre><code class="language-css">/* Base: solid, opaque background for easy reading */
.nav-menu {
  background: #ffffff;
}

/* Visual effect added only if the user has no restriction */
@media (prefers-reduced-transparency: no-preference) {
  .nav-menu {
    background: rgba(255, 255, 255, 0.7);
    backdrop-filter: blur(5px);
  }
}
</code></pre>
<h2>7. The <code>speech</code> media query: the web for ears</h2>
<p>Accessibility is also for those who listen to the web. Blind users use software that reads the site aloud. The <code>speech</code>
query allows you to adapt the text specifically for these tools.</p>
<pre><code class="language-css">@media speech {
  .decorative-spacer, .ads-banner {
    display: none;
  }
}
</code></pre>
<h2>Performance and SEO: why code this way?</h2>
<p>Using these techniques is not just an ethical act. It is a software quality strategy:</p>
<ol>
<li><strong>Zero JavaScript:</strong> CSS is handled natively by the browser, which is much faster than detection scripts.</li>
<li><strong>LCP Score:</strong> Rendering is more stable because media queries are resolved instantly during CSS parsing.</li>
<li><strong>Technical SEO:</strong> Google favors sites that respect web standards and provide a smooth experience for all user
profiles.</li>
</ol>
<h2>Conclusion: a more human web</h2>
<p>Learning accessibility media queries is the mark of an expert developer in 2026. It’s not just extra code; it’s
better-thought-out code. An accessible site is a universal site, performant and ready for the future.</p>
<p>Inclusion is the ultimate form of optimization.</p>
<hr>
<h3>Frequently Asked Questions</h3>
<details>
<summary>Do I have to test all these media queries?</summary>
Yes, and it's easy! In <strong>Chrome DevTools</strong>, go to the "Rendering" tab. You can simulate every user
preference with one click.
</details>
<details>
<summary>Why does <code>forced-colors</code> break my gradients?</summary>
That is intentional. The goal of this mode is readability, not aesthetics. The system simplifies everything so the user
can read effortlessly.
</details>
<details>
<summary>Is native dark mode enough for accessibility?</summary>
No. It is a good start for comfort, but accessibility also requires checking contrasts and keyboard navigation.
</details>

            ]]></content:encoded>
        </item><item>
            <title>Mastering Dark Mode in 2026: The Expert Guide to light-dark() and Eco-design</title>
            <link>https://lionel-peramo.com/posts/css-light-dark-mode-guide/</link>
            <guid>https://lionel-peramo.com/posts/css-light-dark-mode-guide/</guid>
            <pubDate>Wed, 28 Jan 2026 10:00:00 +0000</pubDate>
            <description>Dark mode is used by 82% of internet users. Learn how to use native light-dark() and color-scheme functions for a fast, energy-efficient website.</description>
            <content:encoded><![CDATA[
              <p>⏱️ Reading time: 8 min</p>
              
<p>Dark mode is no longer just a trend. It is a mandatory ergonomic standard. According to a study on <a href="https://thesmallbusinessblog.com/dark-mode-users/">Dark Mode usage by
82% of users</a>, this setting has become the norm. It now dictates how I design my interfaces.</p>
<p>However, many websites still use outdated methods. These methods slow down the browser. They create unpleasant flashes
of light during page load. In 2026, I must use native CSS tools. This guide explains how to combine technical
performance with visual comfort.</p>
<h2>Why dark mode is a strategic priority</h2>
<p>A dark theme is not just “pretty.” It is a powerful lever for three pillars: health, energy, and performance.</p>
<h3>1. Accessibility and eye health</h3>
<p>Dark mode reduces eye strain. This is especially true in dark environments. It also helps people sensitive to bright
light (photophobia).</p>
<p>However, I must be careful with contrasts. Dark gray on a black background is unreadable. I follow <strong>WCAG 2.1</strong>
standards. This ensures my content remains accessible to everyone.</p>
<h3>2. Eco-design and battery life</h3>
<p>This is where technology meets ecology. On OLED screens, a black pixel is a pixel turned off. A turned-off pixel
consumes no energy.</p>
<p>According to <a href="https://dl.acm.org/doi/10.1145/3458864.3467682">a study published by the ACM</a>, dark mode can save up to <strong>47% of battery</strong>. This gain is highest when
screen brightness is high. At 50% brightness, the saving drops to around 9%. Dark mode is a concrete <strong>digital
sobriety</strong> tool for mobile users.</p>
<h3>3. Rendering performance</h3>
<p>Old methods used a lot of JavaScript. JavaScript must be loaded and executed. This increases <strong>Total Blocking Time
(TBT)</strong>.</p>
<p>Native CSS is handled directly by the browser’s rendering engine. It is faster. It uses less processor (CPU) power. It
is the best choice for web performance.</p>
<h2>The <code>color-scheme: light dark</code> revolution</h2>
<p>For a long time, developers used classes like <code>.dark-mode</code> on the <code>&lt;body&gt;</code> tag. It was heavy. It required syncing
JavaScript and CSS.</p>
<p>The first modern step is to declare theme support to the browser:</p>
<pre><code class="language-css">:root {
  /* Tell the browser that I support both themes */
  color-scheme: light dark;
}
</code></pre>
<p>This line is magic. It automatically changes native elements of the page:</p>
<ul>
<li>Scrollbars.</li>
<li>Buttons and form fields.</li>
<li>Default system background colors.</li>
</ul>
<h2>The elegance of the CSS <code>light-dark()</code> function</h2>
<p>The <code>light-dark()</code> function is a major new feature. It allows defining two values in a single property. It is much
cleaner than repeating media queries everywhere.</p>
<h3>Syntax and implementation</h3>
<p>Here is how I centralize my colors:</p>
<pre><code class="language-css">:root {
  color-scheme: light dark;

  /* light-dark(light-value, dark-value) */
  --bg-primary: light-dark(#f4f4fa, #16191a);
  --text-main: light-dark(#333333, #eeeeee);
  --accent: light-dark(#005398, #4dabf7);
}

body {
  background-color: var(--bg-primary);
  color: var(--text-main);
}
</code></pre>
<p><strong>The major benefit:</strong> The code is shorter. The CSS tree is simplified. The browser decides which value to use instantly.</p>
<h2>Managing images in dark mode</h2>
<p>A very bright image can blind a user in dark mode. This breaks the user experience. There are two technical solutions.</p>
<h3>1. Darken via CSS filters</h3>
<p>I can apply a global filter. It is fast and effective for photos:</p>
<pre><code class="language-css">@media (prefers-color-scheme: dark) {
  img:not([src$=&quot;.svg&quot;]) {
    /* Lower brightness and boost contrast for better visibility */
    filter: brightness(.85) contrast(1.1);
  }
}
</code></pre>
<h3>2. Use the <picture> element for diagrams</h3>
<p>Sometimes, a simple brightness drop is not enough. This applies to charts or logos. In that case, I use two versions of
the image:</p>
<pre><code class="language-html">&lt;picture&gt;
  &lt;source srcset=&quot;chart-dark.avif&quot; media=&quot;(prefers-color-scheme: dark)&quot;&gt;
  &lt;img src=&quot;chart-light.avif&quot; alt=&quot;Technical architecture diagram&quot; width=&quot;800&quot; height=&quot;400&quot;&gt;
&lt;/picture&gt;
</code></pre>
<h2>Avoiding Flash of Unstyled Content (FOUC)</h2>
<p>The light “flash” (FOUC) happens when JavaScript takes too long to execute. The user sees the light mode for a fraction
of a second before the dark mode activates. This is a serious UX error.</p>
<p><strong>The high-performance solution:</strong>
By using <code>prefers-color-scheme</code> and <code>light-dark()</code>, the browser knows the theme before displaying the first pixel.</p>
<ol>
<li>No JavaScript to load.</li>
<li>No preference to read from a database.</li>
<li>No visual flash.</li>
</ol>
<p>This is the approach I use in <strong>EcoComposer</strong>. The library detects user preferences declaratively. This ensures a smooth
experience, even on slow connections.</p>
<h2>Dark design pitfalls</h2>
<p>A successful dark mode requires subtlety. Here are three common mistakes I avoid.</p>
<h3>1. Pure black (#000)</h3>
<p>I never put pure white text on a pure black background. High contrast tires the eyes. It creates a “halation” effect. I
prefer very dark grays like <code>#121212</code>.</p>
<h3>2. Color saturation</h3>
<p>A bright color is perfect on a white background. On a dark background, it can become “electric” and aggressive. <strong>I
desaturate my accent colors</strong> for dark mode. Users will appreciate it.</p>
<h3>3. Depth and elevation</h3>
<p>In light mode, I use drop shadows to create depth. In dark mode, shadows are invisible. To show that an element is in
the foreground (like a modal), I use a slightly lighter background color.</p>
<ul>
<li>Page background: <code>#121212</code>.</li>
<li>Elevated element: <code>#1e1e1e</code>.</li>
</ul>
<h2>Impact on SEO and Core Web Vitals</h2>
<p>Google loves fast sites. Native dark mode directly helps your scores:</p>
<ul>
<li><strong>LCP (Largest Contentful Paint):</strong> Less JavaScript means faster display.</li>
<li><strong>CLS (Cumulative Layout Shift):</strong> Avoiding late CSS classes prevents layout shifts.</li>
</ul>
<p>A comfortable site keeps users longer. This improves your bounce rate. It is a positive signal for your SEO.</p>
<h2>Conclusion: responsible code craftsmanship</h2>
<p>Mastering dark mode is proof of professionalism. By using <code>light-dark()</code> and <code>color-scheme</code>, I show that I master modern
tools. I build a lighter, more accessible, and more sustainable web.</p>
<p>I don’t let technical constraints dictate my work. I use them to offer the best possible experience.</p>
<hr>
<h3>FAQ</h3>
<details>
<summary>Is light-dark() supported everywhere?</summary>
Yes, the function is supported by all modern browsers since late 2024. It is a "baseline" feature. For old browsers, I
use standard CSS variables as a fallback.
</details>
<details>
<summary>Does dark mode really save energy on all screens?</summary>
No. It only works on OLED and AMOLED screens. On standard LCD screens, the backlight is always on, even for black areas.
But since OLED is the mobile standard, the global gain is real.
</details>
<details>
<summary>Can I use light-dark() with images?</summary>
No, the function applies to CSS values (colors, lengths). For images, I use the <code>&lt;picture&gt;</code> element as
explained above.
</details>
<details>
<summary>What is the best contrast ratio for dark mode?</summary>
The AA standard requires a 4.5:1 ratio for text. In dark mode, aiming for a ratio between 7:1 and 10:1 is often more
comfortable to avoid eye fatigue.
</details>

            ]]></content:encoded>
        </item><item>
            <title>The HTML inert attribute: How to make an area inactive for a more accessible navigation</title>
            <link>https://lionel-peramo.com/posts/html-inert-attribute-make-area-inactive-accessibility/</link>
            <guid>https://lionel-peramo.com/posts/html-inert-attribute-make-area-inactive-accessibility/</guid>
            <pubDate>Tue, 27 Jan 2026 18:00:00 +0000</pubDate>
            <description>Learn how the HTML &#039;inert&#039; attribute allows you to make parts of your page inactive. Improve accessibility for people with disabilities and boost your performance.</description>
            <content:encoded><![CDATA[
              <p>⏱️ Reading time: 9 min</p>
              
<p>Creating a modern website often requires displaying overlapping elements, such as pop-up windows (modals) or slide-out
menus. But one question remains: how can you be sure that the user won’t click on a button left “behind” or navigate
with their keyboard in an area they can no longer see?</p>
<p>For a long time, this simple task was a nightmare for developers. It required writing very long and complicated
JavaScript scripts to prevent the cursor from moving anywhere. Today, there is a much simpler solution built directly
into the HTML language: the <strong><code>inert</code></strong> attribute.</p>
<p>In this guide, we will see how this tiny tool makes your sites faster, lighter, and above all, much simpler to use for
people with disabilities.</p>
<h2>What exactly is the <code>inert</code> attribute?</h2>
<p>The word “inert” means something that does not move or act. In web programming, when you add the <code>inert</code> attribute to a
part of your page (a <code>div</code>, a <code>section</code>, or a <code>main</code>), you tell the browser to consider that this area no longer exists
for the user.</p>
<p>It is not just a visual change. It is a deep “sleep mode” for the element. Here are the three main effects it produces
immediately:</p>
<ol>
<li><strong>No more clicking:</strong> Any links, buttons, or forms in the area become impossible to click with a mouse or touch on a</li>
<li>touchscreen.</li>
<li><strong>The keyboard ignores it:</strong> If a user uses the “Tab” key to move from one link to another, the browser will</li>
<li>directly skip the entire part marked as <code>inert</code>. This is a huge help for people with motor difficulties.</li>
<li><strong>Screen readers stay silent:</strong> Software used by blind people completely ignores the content of the area. This</li>
<li>prevents reading information that is not relevant at that moment.</li>
</ol>
<h3>A radically simple approach</h3>
<p>Unlike old methods that required modifying every button one by one, <code>inert</code> applies to a parent. If you set a box to
“inert,” everything inside it automatically becomes inert as well. This is called “shorthand” or “cascade” propagation.</p>
<h2>Why is it a revolution for accessibility?</h2>
<p>For a user who sees well and uses a mouse, it is easy to understand not to click on what is behind an open window. But
for a person with a disability, the situation is different.</p>
<h3>Protecting the user from “navigation errors”</h3>
<p>Imagine a blind person opening a navigation menu on their smartphone. If the developer hasn’t made the rest of the page
inactive, the screen reader will continue to suggest links from the footer or articles in the background, even though
the menu is still open. The user feels lost and no longer knows where they are on the site.</p>
<p>By using <code>inert</code>, you create a kind of “safety barrier.” You guide the user so they stay focused on the important action
of the moment (filling out a form, choosing an option in a menu) without risking leaving that area by mistake.</p>
<h3>Simplifying keyboard usage</h3>
<p>Many people use the keyboard instead of the mouse, either by habit or necessity (motor disability). Without the <code>inert</code>
attribute, these users sometimes have to press the “Tab” key 50 times to cross an entire page before reaching the
“Close” button of a window. With <code>inert</code>, you remove all unnecessary obstacles. Navigation becomes fluid and natural.</p>
<h2>How to use ‘inert’ in your code?</h2>
<p>One of the greatest advantages of this solution is its technical simplicity. You don’t need to be a programming expert
to use it.</p>
<h3>Practical example: the modal window</h3>
<p>This is the most common case. Here is how to structure your page so it works perfectly:</p>
<pre><code class="language-html">&lt;body&gt;
  &lt;!-- Wrap all main content in a div --&gt;
  &lt;div id=main-content&gt;
    &lt;header&gt;...&lt;/header&gt;
    &lt;main&gt;...&lt;/main&gt;
    &lt;footer&gt;...&lt;/footer&gt;
  &lt;/div&gt;

  &lt;!-- The window that pops up on top --&gt;
  &lt;div id=my-modal-window role=dialog aria-modal=true&gt;
    &lt;button onclick=&quot;close()&quot;&gt;Close&lt;/button&gt;
    &lt;p&gt;This is important information.&lt;/p&gt;
  &lt;/div&gt;
&lt;/body&gt;
</code></pre>
<p>When you display the window, you simply add the attribute to the area you want to make inactive:
<code>document.getElementById('main-content').setAttribute('inert', '');</code></p>
<p>And when you close the window, you remove the attribute:
<code>document.getElementById('main-content').removeAttribute('inert');</code></p>
<p>In a single line of <strong>code</strong>, you have solved all the interactivity problems on your page.</p>
<h2><code>Inert</code> vs <code>aria-hidden</code>: don’t get them confused anymore</h2>
<p>This is a very common confusion during <strong>development</strong>. Many sites use <code>aria-hidden=&quot;true&quot;</code>. It is a good intention, but
it is incomplete.</p>
<ul>
<li><strong><code>aria-hidden=&quot;true&quot;</code></strong>: Tells the screen reader not to read the area. But the user can still click on it or access</li>
<li>it with the Tab key on their keyboard. This is very confusing because you can interact with something that isn’t being</li>
<li>announced.</li>
<li><strong><code>inert</code></strong>: Blocks everything at the same time. Mouse, keyboard, and voice. It is the complete solution.</li>
</ul>
<h2>Performance and eco-design: code less to do more</h2>
<p>On this blog, I often talk about performance and respect for the digital environment (<strong>eco-design</strong>). The <code>inert</code>
attribute is an excellent example of this philosophy.</p>
<h3>Reducing page weight</h3>
<p>Previously, to manage navigation blocking, we downloaded JavaScript libraries (like <code>focus-trap</code>) that weighed several
dozen kilobytes. Multiplied by millions of visitors, this represents significant energy consumption for servers and
networks.</p>
<p>By using a native browser function, you remove these useless files. Your site loads faster, which improves your <strong>LCP
(Largest Contentful Paint)</strong> score. For Google, this is a positive signal that can help your <strong>SEO</strong>.</p>
<h3>Less work for the user’s computer</h3>
<p>Every script running in a browser consumes battery on a smartphone. <code>inert</code> is handled directly by the browser engine
(in very fast C++ language). It is much more energy-efficient than a JavaScript script that monitors every mouse
movement or every key press.</p>
<h2>A word on compatibility (Baseline 2024)</h2>
<p>For a few years, <code>inert</code> was an experimental novelty. That is no longer the case. Since 2024, it has been part of what
is called the “Baseline.” This means all modern browsers (Chrome, Firefox, Safari, Edge) support it perfectly.</p>
<p>If you still need to support very old browsers (which is increasingly rare), light “polyfills” (backup scripts) exist,
but for 96% of internet users, this will work natively without any extra effort on your part.</p>
<h2>Design tip: stylizing inactive zones</h2>
<p>To improve the <strong>user experience (UX)</strong>, it is recommended to visually show that the background content is no longer
available. You can use the <code>inert</code> attribute as a selector in your CSS file:</p>
<pre><code class="language-css">/* Reduce visibility of everything that is inert */
[inert] {
  opacity        : .4;
  filter         : blur(2px);
  user-select    : none;
  pointer-events : none;
}
</code></pre>
<p>This way, the user immediately understands, at a glance, that they must focus on the active window. It’s an elegant way
to marry design and technology.</p>
<h2>Conclusion: Toward responsible code craftsmanship</h2>
<p>Adopting the <code>inert</code> attribute is not just about saving the developer time. It is a sign of respect toward users. By
choosing native and lightweight solutions, we build a <strong>web</strong> that leaves no one behind, whether they are people with
disabilities or users with slow internet connections.</p>
<p>In 2026, the quality of a site is no longer measured by the complexity of its scripts, but by the relevance of its
technical choices. Use <code>inert</code>, simplify your code, and make accessibility a strength for your project.</p>
<hr>
<h3>Frequently Asked Questions</h3>
<details>
<summary>Does the inert attribute also block forms?</summary>
Yes. If you apply <code>inert</code> to a form, the user will no longer be able to fill in fields or click the submit
button. This is very useful for preventing double form submission during loading.
</details>
<details>
<summary>Can I set the 'body' element to inert?</summary>
Technically yes, but it is discouraged because it would block absolutely the entire site, including the window you are
trying to display. It is better to target a container that holds everything except your modal window.
</details>
<details>
<summary>Does Google see inert content?</summary>
Yes. Search engine bots still read the HTML code. <code>inert</code> does not prevent the indexing of content; it only
prevents human interaction.
</details>

            ]]></content:encoded>
        </item><item>
            <title>Visual Impairments and the Web: The Ultimate Guide to Inclusive Design</title>
            <link>https://lionel-peramo.com/posts/visual-impairments-inclusive-design/</link>
            <guid>https://lionel-peramo.com/posts/visual-impairments-inclusive-design/</guid>
            <pubDate>Mon, 26 Jan 2026 21:00:00 +0000</pubDate>
            <description>Over 2.2 billion people live with a vision impairment. Learn how to simulate, test, and code for inclusion without sacrificing your design.</description>
            <content:encoded><![CDATA[
              <p>⏱️ Reading time: 9 min</p>
              
<p>Web accessibility is often perceived as a purely technical constraint—a simple checkbox to comply with legal standards
like the <strong>EAA 2025</strong>. However, behind the algorithms and tags lies a massive human reality: according to the <a href="https://www.who.int/news-room/fact-sheets/detail/blindness-and-visual-impairment">World
Health Organization</a>, at least <strong>2.2 billion people</strong> suffer from near or far vision impairment.</p>
<p>For a developer or designer, ignoring this audience is not just an ethical lapse; it’s a major strategic mistake. An
unreadable site is a site that doesn’t convert. In this article, we will explore how to turn this “constraint” into a
lever for software quality by learning how to simulate these impairments and code robust CSS solutions.</p>
<h2>Understanding the Spectrum of Visual Impairments</h2>
<p>A common mistake is reducing vision impairment to total blindness. In reality, the spectrum is vast and impacts web
navigation in diverse ways:</p>
<ol>
<li><strong>Color Blindness (Dyschromatopsia):</strong> According to the <a href="https://www.colourblindawareness.org/colour-blindness/">Colour Blind Awareness
organization</a>, it affects approximately 8% of men and 0.5%
of women. Whether it’s protanopia (red), deuteranopia (green), or tritanopia (blue), the problem remains the same:
information transmitted solely through color is lost.</li>
<li><strong>Low Vision:</strong> This includes reduced visual acuity, blurred vision, or extreme sensitivity to light. These users
often rely on intensive zooming (up to 400%), an adaptation requirement now mandated by <a href="https://www.w3.org/WAI/WCAG21/Understanding/reflow.html">W3C WCAG standards</a>.</li>
<li><strong>Central or Peripheral Vision Loss:</strong> Conditions like macular degeneration (AMD) or glaucoma create “dead zones” in
the field of vision.</li>
<li><strong>Cataracts:</strong> This produces clouded vision and a drastic loss of contrast, making thin or light gray fonts
completely invisible.</li>
</ol>
<h2>Simulating to Better Understand: Browser Tools</h2>
<p>Before fixing, you must feel. Did you know that your <strong>Chrome DevTools</strong> (and Firefox) include real-time vision
simulators?</p>
<h3>How to Enable the Simulation?</h3>
<ol>
<li>Open the Inspector (F12).</li>
<li>Use the shortcut <code>Ctrl+Shift+P</code> (or <code>Cmd+Shift+P</code> on Mac) to open the command palette.</li>
<li>Type “<strong>Rendering</strong>” and select the tab.</li>
<li>Scroll down to the “<strong>Emulate vision deficiencies</strong>” section.</li>
</ol>
<p>Here, you can test your site through the eyes of someone with protanopia or blurred vision. It’s often a brutal
experience for a designer: you instantly realize that your “critical” red buttons on a dark background are invisible to
part of your users.</p>
<h2>CSS Strategies for an Inclusive Interface</h2>
<p>Once the observation is made, how do you act at the <strong>code</strong> level? Accessibility doesn’t mean making “ugly” or
black-and-white sites. It’s about resilient design.</p>
<h3>1. Contrast: The Golden Rule</h3>
<p>The WCAG 2.1 standard requires a contrast ratio of at least <strong>4.5:1</strong> for normal text and <strong>3:1</strong> for large text.</p>
<ul>
<li><strong>Technical Tip:</strong> Use tools like <code>color.review</code> to find combinations that work.</li>
<li><strong>Beyond Black and White:</strong> Avoid pure contrast (black #000 on white #FFF), which can cause eye strain (halation) in
people with dyslexia or photophobia. Prefer very dark grays on off-whites.</li>
</ul>
<h3>2. Typography: Abandon Pixels</h3>
<p>This is the most common <strong>frontend</strong> error. Using <code>px</code> for font sizes blocks the user’s ability to resize text via their
browser settings.</p>
<ul>
<li><strong>The Solution:</strong> Use the <code>rem</code> unit. It is based on the root size defined by the user.</li>
<li><strong>Line Height and Spacing:</strong> A <code>line-height</code> of at least 1.5 and generous paragraph spacing radically improve
reading for people with blurred vision.</li>
</ul>
<h3>3. Layout Robustness (The Zoom Test)</h3>
<p>A visually impaired user will zoom your page to 200% or even 400%. If your menu overlaps the content or columns clash,
the site is unusable.</p>
<ul>
<li><strong>Fluid Design:</strong> Use Flexbox and CSS Grid to allow content to reorganize naturally.</li>
<li><strong>Container Queries:</strong> This is the future. They allow a component to adapt to the space allocated to it, rather than
the total screen width, which is crucial during intensive zooming.</li>
</ul>
<h2>Media Queries: Give Control Back to the User</h2>
<p>Modern CSS offers tools to detect user preferences at the operating system level.</p>
<pre><code class="language-css">/* Detect &quot;High Contrast&quot; modes forced by the OS */
@media (forced-colors: active) {
  .button {
    /* We force a border because the background might disappear */
    border: 2px solid ButtonText;
    outline: 1px solid transparent;
  }
}

/* For light-sensitive users */
@media (prefers-color-scheme: dark) {
  body { background-color: #121212; color: #e0e0e0; }
}

/* For those who enabled &quot;High Contrast&quot; on Windows/macOS */
@media (prefers-contrast: more) {
  .button { border: 2px solid currentColor; }
}

/* Activate animations only if no reduction is requested */
@media (prefers-reduced-motion: no-preference) {
    .modal {
      animation: fadeIn 0.3s ease-in-out;
    }
    .link {
      transition: color 0.2s ease;
    }
}
</code></pre>
<p>These <strong>media queries</strong> allow you to offer a personalized experience without the user having to configure anything on
your site. This is the principle of <strong>Universal Design</strong>.</p>
<h2>SEO and Performance Impact: The Virtuous Circle</h2>
<p>Many don’t know it, but visual accessibility is a direct booster for your <strong>Organic Search (SEO)</strong>. Google behaves like
the most powerful “visually impaired” user in the world: it analyzes code to understand meaning, not pixels.</p>
<h3>Alt Attributes: Signal vs. Noise</h3>
<p>It’s often said that everything must be described. This is false.</p>
<ol>
<li><strong>Informative Image:</strong> (e.g., a technical diagram) Use a descriptive <code>alt</code>. It’s vital for the user and excellent</li>
<li>for Google Images.</li>
<li><strong>Decorative Image:</strong> (e.g., an abstract shape, a repetitive icon) **The <code>alt</code> attribute must be present but empty</li>
<li>(<code>alt=&quot;&quot;</code>)**. Why? Because an empty <code>alt</code> tells the screen reader to ignore the image. If it’s missing, the reader</li>
<li>will often read the file name (e.g., “bg-pattern-01.jpg”), which is useless noise.</li>
</ol>
<h3>LCP and Core Web Vitals</h3>
<p>An accessible page often avoids heavy JavaScript layout manipulations. By using native and robust CSS, you improve your
<strong>LCP (Largest Contentful Paint)</strong> and visual stability, two key factors for ranking in 2026.</p>
<h2>Conclusion: Toward Responsible Code Craftsmanship</h2>
<p>Accessibility is not a destination; it’s a continuous practice. By integrating visual impairment simulation from the
<strong>development</strong> phase, you create more robust, faster, and more human interfaces.</p>
<p>In 2026, the web can no longer afford to be exclusive. Take control of your contrasts, free your typography, and
remember that every millisecond of clarity gained is a victory for all your users.</p>
<hr>
<h3>Frequently Asked Questions</h3>
<details>
<summary>Does visual accessibility make my site less aesthetic?</summary>
Absolutely not. Giants like Apple or Stripe have extremely polished designs that scrupulously respect contrast ratios.
"Beautiful" and "accessible" are not opposites; accessibility is simply a superior form of ergonomics.
</details>
<details>
<summary>What is the easiest tool to check my contrasts?</summary>
In addition to DevTools, the <strong><a href="https://color.review/">Color Review</a></strong> website is a gold
standard. It allows you to see in real-time if your text is readable according to AA and AAA standards, while suggesting
hue adjustments.
</details>
<details>
<summary>Is dark mode enough to make a site accessible?</summary>
No. While it helps people with photophobia, dark mode can cause contrast issues if not managed well. It should be seen
as a complement, not a universal solution.
</details>
<details>
<summary>Why is 400% zoom important?</summary>
It's a requirement of the <strong>WCAG 1.4.10 (Reflow)</strong> criterion. At 400% on a desktop screen, the site must
behave like a mobile version without data loss or horizontal scrolling. It's the ultimate test for your CSS flexibility.
</details>

            ]]></content:encoded>
        </item><item>
            <title>Mastering Web Printing with CSS: The Complete Guide to Perfect Pages</title>
            <link>https://lionel-peramo.com/posts/mastering-css-print/</link>
            <guid>https://lionel-peramo.com/posts/mastering-css-print/</guid>
            <pubDate>Sat, 24 Jan 2026 17:00:00 +0000</pubDate>
            <description>Discover how to use @media print in CSS to create perfect print layouts. Optimize UX, accessibility, and eco-design while saving paper and ink.</description>
            <content:encoded><![CDATA[
              <p>⏱️ Reading time: 13 min</p>
              
<p>In the all-digital era, the idea of printing a web page might seem outdated. Yet, it is an essential feature that is far
from dead. From <strong>cooking recipes</strong> to consult with your hands full, to <strong>assembly guides</strong> to follow away from the
screen, or <strong>plane tickets</strong> to keep safe, users still have many reasons to move from pixels to paper.</p>
<p>What if I told you that your <strong>CSS</strong> can not only make this experience pleasant but also save trees and strengthen your
brand image?</p>
<p>This comprehensive guide will show you how to master print styles to transform a chaotic web page into a clear,
professional, and environmentally friendly document.</p>
<h2>The Strategic Impact of a Print Stylesheet</h2>
<p>Many developers ignore the print stylesheet, considering it a minor detail. This is a strategic mistake. Proper print
management has direct impacts on user experience, accessibility, and even your brand image.</p>
<h3>1. User Experience (UX) and Professionalism</h3>
<p>When a user clicks “Print,” they expect a readable document. If the result is a page filled with navigation elements,
advertisements, and cut-off columns, the experience is frustrating. A site that offers a clean, well-formatted print
version shows attention to detail and high professionalism.</p>
<h3>2. Accessibility (a11y)</h3>
<p>Accessibility isn’t limited to screen readers. For many people, especially seniors or those suffering from eye strain,
reading a long document is more comfortable on paper. Providing a printable and readable version is an important facet
of inclusion.</p>
<h3>3. Eco-design and Savings</h3>
<p>A well-designed print stylesheet is a simple but powerful <strong>eco-design</strong> gesture. By hiding unnecessary images and
forcing a white background, you significantly reduce your users’ ink and paper consumption. It’s good for their wallets
and for the planet.</p>
<h2>The Basics: <code>@media print</code></h2>
<p>The heart of the magic lies in a simple CSS <em>media query</em>. Everything inside this block will only apply when the page
is printed.</p>
<pre><code class="language-css">@media print {
  /* Your print styles go here... */
}
</code></pre>
<p>This approach keeps your print styles completely separate from your screen styles, with no impact on site performance
during normal browsing.</p>
<h2>6 Steps to a Perfect Print Layout</h2>
<p>Optimizing for print isn’t complicated. Follow these steps to cover 99% of needs.</p>
<h3>Step 1: Clean Up the Unnecessary</h3>
<p>The first rule is to hide everything that doesn’t belong on a sheet of paper. This includes navigation, footers,
sidebars, ads, comment forms, and interactive buttons.</p>
<pre><code class="language-css">@media print {
  header,
  nav,
  footer,
  aside,
  form,
  .comments,
  .ads,
  .no-print {
    display: none;
  }
}
</code></pre>
<h3>How to ensure these rules apply without conflict?</h3>
<p>You might think of specificity wars or using <code>!important</code>. However, the cleanest and most robust solution is
architectural: <strong>isolating screen-specific styles</strong>.</p>
<p>The best practice is to wrap all your complex layout rules or styles that only concern the screen display in a
<code>@media screen</code> media query.</p>
<p><strong>Concrete Example:</strong></p>
<p>Instead of having a global style for your header:</p>
<pre><code class="language-css">/* Bad practice: global style that may conflict */
.main-header {
  display: flex;
  justify-content: space-between;
  background-color: #333;
}
</code></pre>
<p>Structure your CSS to clearly separate contexts:</p>
<pre><code class="language-css">/* Base styles, shared by screen and print */
.main-header {
  /* Ex: padding, etc. */
}

/* Styles ONLY for the screen */
@media screen {
  .main-header {
    display: flex;
    justify-content: space-between;
    background-color: #333;
  }
}

/* Styles ONLY for print */
@media print {
  .main-header {
    display: none;
  }
}
</code></pre>
<p>With this architecture, the rules for <code>@media screen</code> and <code>@media print</code> are mutually exclusive. The browser will never
apply screen styles during printing, thus eliminating any risk of specificity conflict. Your <code>display: none;</code> will work
every time without needing to override selectors or use <code>!important</code>.</p>
<p>This approach ensures cleaner, more predictable, and easier-to-maintain code in the long run.</p>
<h3>Step 2: Adapt Typography for Reading</h3>
<p>What is readable on a screen isn’t necessarily so on paper.</p>
<ul>
<li><strong>Font Family:</strong> Serif fonts, such as <em>Georgia</em> or <em>Times New Roman</em>, are often considered more readable for long
texts on paper.</li>
<li><strong>Font Size:</strong> Use points (<code>pt</code>) rather than pixels (<code>px</code>) or <code>rem</code>. A size of <code>12pt</code> is a comfortable standard.</li>
<li><strong>Color:</strong> To save ink and maximize contrast, force the text to pure black and the background to white.</li>
</ul>
<pre><code class="language-css">@media print {
  body {
    font-family: Georgia, 'Times New Roman', Times, serif;
    font-size: 12pt;
    color: #000;
    background: #fff;
  }
}
</code></pre>
<h3>Step 3: Guarantee a Linear Layout</h3>
<p>Unlike a screen, a sheet of paper is a fixed-width linear medium. The goal is therefore to ensure that your content
flows in a single column, from top to bottom, for maximum readability.</p>
<p>Modern layouts using <code>display: flex</code> or <code>display: grid</code> are powerful assets here. If your site is already responsive and
displays in a single column on mobile screens, you’ve already done most of the work.</p>
<p>However, to guarantee this behavior during printing, regardless of the screen size from which the user starts the print,
it is recommended to explicitly reset the layout. This also ensures that screen-specific properties, like <code>position: sticky</code>, are neutralized.</p>
<pre><code class="language-css">@media print {
  /* Basic reset for main containers */
  main, .container, article {
    width: 100%;
    min-width: 0;
    margin: 0;
    padding: 0;
    box-shadow: none;
    border: none;
  }

  /* Force flexbox containers into a single vertical column */
  .flex-container {
    flex-direction: column;
  }

  /* Transform CSS grids into a simple, single-column flow */
  .grid-container {
    display: block; /* The simplest and most robust solution */
  }
}
</code></pre>
<p>By forcing a vertical direction for your main containers and resetting their dimensions, you ensure that the content
will flow naturally, providing an optimal reading experience on paper.</p>
<h3>Step 4: Handle Links</h3>
<p>Hyperlinks are useless on paper. To keep them helpful, it is good practice to display the full URL next to the link
text. This can be done very simply with a CSS pseudo-element.</p>
<pre><code class="language-css">@media print {
  a::after {
    content: ' (' attr(href) ')';
    font-size: 9pt;
    color: #333;
  }

  /* Avoid displaying internal links or anchors */
  a[href^=&quot;#&quot;]::after,
  a[href^=&quot;javascript:&quot;]::after {
    content: '';
  }
}
</code></pre>
<h3>Step 5: Control Page Breaks</h3>
<p>This is where the magic really happens. CSS gives you control over where page breaks should (or should not) occur.</p>
<ul>
<li><code>break-inside: avoid;</code>: Prevents an element (like an image or a code block) from being split in two by a page break.</li>
<li><code>break-before: page;</code>: Forces a page break <em>before</em> an element. Very useful for starting a new section on a new page.</li>
<li><code>break-after: page;</code>: Forces a page break <em>after</em> an element.</li>
</ul>
<pre><code class="language-css">@media print {
  h2, h3 {
    break-after: avoid; /* Prevents a page break right after a heading */
  }

  figure, pre, table {
    break-inside: avoid; /* Protects figures and tables from being cut */
  }
}
</code></pre>
<h3>Step 6: Manage Page Margins with <code>@page</code></h3>
<p>The <code>@page</code> rule is specific to printing and allows you to define the margins of the printed document, much like in a
word processor.</p>
<pre><code class="language-css">@media print {
  @page {
    margin : 2cm;
  }

  /* You can even target the first page differently */
  @page :first {
    margin-block-start : 3cm;
  }
}
</code></pre>
<h2>Testing Your Print Styles</h2>
<p>No need to waste paper! All modern browsers include a print preview mode in their developer tools.</p>
<ol>
<li>Open developer tools (F12 or Ctrl+Shift+I).</li>
<li>Go to the “More tools” menu &gt; “Rendering”.</li>
<li>Look for the “Emulate CSS media type” option and select “print”.</li>
</ol>
<p>Your page will instantly display as if it were being printed, allowing you to adjust your styles in real time.</p>
<h2>Conclusion: Small Effort, Big Impact</h2>
<p>Optimizing print styles is an often-neglected task, but it demonstrates a high level of polish and respect for the user.
With just a few lines of <strong>CSS</strong>, you not only improve the <strong>user experience</strong> and <strong>accessibility</strong>, but you also make
a concrete gesture for digital <strong>eco-design</strong>.</p>
<p>It is proof that well-thought-out code can have benefits far beyond the screen.</p>
<hr>
<h3>Frequently Asked Questions</h3>
<details>
<summary>Is print optimization still relevant in 2026?</summary>
Absolutely, and perhaps even more than we think. While uses like printing invoices are decreasing with digitalization,
many contexts where paper remains indispensable persist:
<ul>
<li>Practical guides and tutorials: A cooking recipe followed in the kitchen, a drawing guide, a sewing pattern, or a
furniture assembly plan. All these activities require consulting information while having your hands full, away from the screen.</li>
<li>Educational and dense content: Research articles, technical documentation, or course materials that one wishes to
physically annotate for better assimilation.</li>
<li>Accessibility and sharing: For people suffering from eye strain or to share information with a relative less
comfortable with digital tools.</li>
<li>Safety while traveling: Plane tickets, hotel reservations, or itineraries, where a paper copy remains a valuable
backup in case of battery or network issues.</li>
</ul>
<p>Ignoring printing means degrading the experience for all these use cases. Offering a clean printable version is a mark
of quality and respect for the end user.</p>
</details>
<details>
<summary>How do I handle frameworks like Bootstrap or Tailwind?</summary>
Most modern frameworks include utility classes for printing. For example, Bootstrap uses <code>d-print-none</code> to
hide an element during printing and <code>d-print-block</code> to show it. Tailwind offers a <code>print:</code>
modifier, such as <code>print:hidden</code>. You can combine these classes with your own <code>@media print</code>
stylesheet for total control.
</details>
<details>
<summary>What is the difference between creating a print stylesheet and generating a PDF?</summary>
It's true that most modern browsers allow you to "Save as PDF" directly from the print dialog box. In this case, the
<code>@media print</code> styles are indeed used to create the document.
<p>The real difference lies not in the output format (paper or PDF), but in the <strong>intent and the level of control</strong> of
the process:</p>
<ol>
<li><strong>Print style (<code>@media print</code>): Formatting initiated by the user.</strong></li>
</ol>
<ul>
<li><strong>Objective:</strong> Allow the user to obtain a clean version of the <em>current</em> page for their personal use (archiving,
offline reading, paper printing).</li>
<li><strong>Control:</strong> The <strong>user triggers the action</strong>. The final rendering may vary slightly depending on their browser and
settings. The document is a “snapshot” of the web page.</li>
<li><strong>Use case:</strong> Printing an article, a recipe, an itinerary.</li>
</ul>
<ol start="2">
<li><strong>PDF generation: A document controlled by the application.</strong></li>
</ol>
<ul>
<li><strong>Objective:</strong> Provide an official and standardized document, whose layout is <strong>identical for everyone</strong>, regardless
of the browser. This is often an explicit feature, like a “Download PDF” button.</li>
<li><strong>Control:</strong> The process is <strong>entirely mastered by the developer</strong>, via a server-side library (e.g.,
<code>FPDF</code> in PHP) or client-side (e.g., <code>jsPDF</code>). The developer precisely defines the structure,
headers, numbering, etc.</li>
<li><strong>Use case:</strong> Invoices, event tickets, financial reports, e-books. The PDF here is a product in itself, not just a
capture of the page.</li>
</ul>
<p>In summary:</p>
<ul>
<li>Use <strong><code>@media print</code></strong> to ensure that any page of your site is clean when the user decides to print or
save it.</li>
<li>Use <strong>dedicated PDF generation</strong> when you need to provide a specific, portable document whose format must be
perfectly controlled.</li>
</ul>
</details>

            ]]></content:encoded>
        </item><item>
            <title>WAI-ARIA: The Ultimate Guide to Mastering Web Accessibility Without Bloating Your Code</title>
            <link>https://lionel-peramo.com/posts/aria/</link>
            <guid>https://lionel-peramo.com/posts/aria/</guid>
            <pubDate>Wed, 21 Jan 2026 12:00:00 +0000</pubDate>
            <description>ARIA is not a magic wand; it is a surgical layer. Discover how to enrich your DOM for assistive technologies with expert precision.</description>
            <content:encoded><![CDATA[
              <p>⏱️ Reading time: 9 min</p>
              
<p>Web accessibility is often perceived as a compliance constraint—a checklist to avoid legal penalties. This is a narrow view. In reality, it is a pillar of software quality and <strong>code</strong> robustness.</p>
<p>In this article, we will dive deep into the world of <strong>WAI-ARIA</strong>. We won’t just talk about “doing the right thing,” but rather about data structures, rendering performance, and how the <strong>browser</strong> translates your tags for assistive technologies.</p>
<h2>The Birth of an Invisible Semantic Layer</h2>
<p>In the early days of the <strong>web</strong>, pages were simple static documents. A link was a link, a heading was a heading. But with the explosion of JavaScript and frameworks like React, Vue, or OTRA, we began simulating complex behaviors. A simple <code>&lt;div&gt;</code> can now become a dropdown menu, a modal window, or a price slider.</p>
<p>The problem? For a screen reader, a <code>&lt;div&gt;</code> remains a meaningless box. To bridge this gap, the <strong>WAI-ARIA</strong> (Web Accessibility Initiative - Accessible Rich Internet Applications) specification was created. It acts as an extension of HTML—a system of meta-information that changes nothing visually but redefines the object within the <strong>Accessibility Tree</strong>.</p>
<h3>The Concept of the Accessibility Tree</h3>
<p>Few developers realize that the browser does more than just build the DOM (Document Object Model) and the CSSOM (CSS Object Model). It also generates a third tree: the <strong>Accessibility Tree</strong>.</p>
<p>This tree filters DOM information to keep only what is useful for voice or braille navigation. When you use <strong>ARIA</strong> attributes, you directly modify the nodes of this tree. If you overload it with useless information, you create “semantic noise” that slows down the user. Performance, in this context, is measured by the speed at which the user understands the interface.</p>
<h2>The Three Pillars of the ARIA Specification</h2>
<p>To manipulate ARIA with surgical precision, you must understand its three components: roles, properties, and states.</p>
<h3>1. Roles (<code>role</code>)</h3>
<p>The role defines the element’s contract. Is it a button? A tab? A search area?</p>
<ul>
<li><strong>Structural Roles</strong>: <code>main</code>, <code>navigation</code>, <code>banner</code>, <code>contentinfo</code>. They help map out the <strong>page</strong>.</li>
<li><strong>Widget Roles</strong>: <code>dialog</code>, <code>tablist</code>, <code>tooltip</code>. They announce interactive behavior.</li>
<li><strong>Landmark Roles</strong>: They allow users to “jump” directly to a specific section.</li>
</ul>
<h3>2. Properties</h3>
<p>These describe characteristics that are generally stable. For example, <code>aria-labelledby</code> allows linking an element to its title via an ID. This is far more powerful than a simple title attribute because it allows for building a complex semantic hierarchy without duplicating text in the <strong>code</strong>.</p>
<h3>3. States (<code>states</code>)</h3>
<p>This is the most dynamic part of your <strong>development</strong>. States change based on user interaction:</p>
<ul>
<li><code>aria-expanded=&quot;true/false&quot;</code>: Indicates if a menu is open.</li>
<li><code>aria-busy=&quot;true&quot;</code>: Signals to the screen reader that a section is being updated (e.g., an AJAX load).</li>
<li><code>aria-invalid=&quot;true&quot;</code>: Indicates a real-time input error in a <strong>form</strong>.</li>
</ul>
<h2>The W3C Golden Rule: The Paradoxical “No ARIA”</h2>
<p>The number one rule in the official documentation is blunt: <strong>“If you can use a native HTML element that already has the semantics and behavior you need, then do not use ARIA.”</strong></p>
<h3>The Hidden Cost of “Custom CSS/JS”</h3>
<p>Take a checkbox for example.</p>
<ol>
<li><strong>Native Approach</strong>: <code>&lt;input type=&quot;checkbox&quot;&gt;</code>. Pros: Focus management, native keyboard support (Space), automatic “checked” state, maximum performance.</li>
<li><strong>ARIA Approach</strong>: <code>&lt;div role=&quot;checkbox&quot; aria-checked=&quot;false&quot; tabindex=&quot;0&quot;&gt;</code>. Cons: You must write JS to handle the click, JS to handle the Space key, and JS to toggle the state.</li>
</ol>
<p>Every line of JS added to compensate for a lack of native semantics is technical debt and an extra CPU load for the user’s device. By prioritizing native HTML, you practice <strong>eco-design</strong>: saving server resources (less code to send) and client resources (fewer scripts to run).</p>
<h2>Focus Management: The Heart of Interaction</h2>
<p>Accessibility isn’t just about text labels; it’s about movement. For a user navigating solely by keyboard, “focus” is their only means of action.</p>
<p>ARIA does not manage focus on its own. This is a common mistake. If you open a modal window with <code>role=&quot;dialog&quot;</code>, it is up to you as a <strong>developer</strong> to move the focus inside the window and implement a “Keyboard Trap” so it doesn’t escape into the background.</p>
<p>The <code>tabindex</code> attribute is your best ally here. <code>tabindex=&quot;0&quot;</code> inserts an element into the natural flow, while <code>tabindex=&quot;-1&quot;</code> allows an element to be focusable only via JavaScript. Mastering this mechanic is what differentiates an interface that is “accessible on paper” from one that is truly usable.</p>
<h2>Handling Dynamic Content with aria-live</h2>
<p>In modern <strong>web</strong> applications, content changes constantly without a page refresh. How does a blind person know that an error message just appeared at the top of the screen while they are filling out a field at the bottom?</p>
<p>The answer is: <strong>Live Regions</strong>. By using <code>aria-live</code>, you create a monitoring zone for the browser.</p>
<ul>
<li><code>aria-live=&quot;polite&quot;</code>: The announcement is made as soon as the user stops typing or navigating. This is the most UX-friendly approach.</li>
<li><code>aria-live=&quot;assertive&quot;</code>: The announcement interrupts the screen reader immediately. Use this with extreme caution for critical alerts only.</li>
</ul>
<h2>ARIA and Technical SEO: An Underestimated Alliance</h2>
<p>ARIA is often restricted to the realm of screen readers. People forget that search engine crawlers are also “non-visual users.” Google increasingly uses semantic signals to understand the structure of an application.</p>
<p>A site that correctly uses <code>main</code>, <code>search</code>, and <code>navigation</code> roles offers superior “semantic density.” By helping machines understand which button closes a window or which section is complementary (<code>role=&quot;complementary&quot;</code>), you indirectly assist Natural Language Processing (NLP) algorithms. High-performance <strong>SEO</strong> in 2026 is no longer just about keywords; it extends to the structural understanding of the <strong>code</strong>.</p>
<h2>Testing and Validation Strategies</h2>
<p>To guarantee the quality of your production <strong>version</strong>, automation is necessary but not sufficient.</p>
<ol>
<li><strong>Automated Tests</strong>: Use libraries like <code>axe-core</code> in your CI/CD pipelines. This catches about 40% of the most common errors (misspelled ARIA attributes, missing IDs).</li>
<li><strong>Manual Audit</strong>: Nothing replaces a walkthrough with a screen reader (NVDA or VoiceOver). Navigate with your eyes closed. If you feel lost, your ARIA architecture is failing.</li>
<li><strong>Browser Inspection</strong>: Chrome and Firefox dev tools now have an “Accessibility” tab. Use it to inspect the accessibility tree and verify that your attributes are correctly calculated.</li>
</ol>
<hr>
<h3>Frequently Asked Questions</h3>
<details>
<summary>Can I use ARIA with deprecated tags?</summary>
Technically yes, but it is bad practice. ARIA is designed to enrich modern HTML (HTML5). Using ARIA on tags like <code>&lt;font&gt;</code> or <code>&lt;center&gt;</code> makes no sense because these tags should no longer exist in optimized code.
</details>
<details>
<summary>Does <code>aria-label</code> replace visible text?</summary>
Only for assistive technologies. For sighted users, the image or icon must be explicit. Warning: if a button contains text, <code>aria-label</code> will overwrite it completely. Ensure the label contains at least the visible text to avoid cognitive dissonance.
</details>
<details>
<summary>What is the most complex ARIA role to implement?</summary>
Undoubtedly the <code>combobox</code> role. It requires precise management of focus, the associated dropdown list, and selection announcements. It is the ultimate test for any accessibility expert.
</details>
<details>
<summary>Does ARIA impact JS performance?</summary>
The attributes themselves are passive. However, the JavaScript logic required to maintain ARIA states (e.g., syncing a menu opening with <code>aria-expanded</code>) can impact <strong>Total Blocking Time (TBT)</strong> if not optimized or if it triggers unnecessary reflows.
</details>
<details>
<summary>How should translations of ARIA attributes be handled?</summary>
This is crucial. Values for <code>aria-label</code> or <code>aria-valuetext</code> must be translated in every language **version** of your site, as they are read exactly as written by voice synthesizers.
</details>
<h2>Conclusion: Toward Responsible Code Craftsmanship</h2>
<p>Mastering <strong>WAI-ARIA</strong> is not about slapping labels everywhere. It is about understanding how information flows between your source <strong>code</strong> and the end user. It is an exercise in precision that requires rigor but transforms an ordinary website into a universal platform.</p>
<p>As developers, we have a responsibility to build a <strong>web</strong> that leaves no one behind. Take back control of your semantics, simplify your components, and make accessibility a driver of your performance.</p>

            ]]></content:encoded>
        </item><item>
            <title>Forgejo: Discover 6 keys to master this Git platform</title>
            <link>https://lionel-peramo.com/posts/forgejo-git-tool/</link>
            <guid>https://lionel-peramo.com/posts/forgejo-git-tool/</guid>
            <pubDate>Tue, 06 Jan 2026 16:30:00 +0000</pubDate>
            <description>Discover Forgejo, the lightweight open-source Git alternative. Learn how to manage every version of your code on a community-driven platform.</description>
            <content:encoded><![CDATA[
              <p>⏱️ Reading time: 9 min</p>
              
<p>Forgejo is a complete solution for hosting your source <strong>code</strong>.
It is a free tool that belongs to its developer community.
It allows managing IT projects in an ethical and sovereign way.</p>
<p>You too can set up your own instance on your server in a few minutes.
Discover why Forgejo has become essential for <strong>web</strong> professionals seeking independence.</p>
<h2>The history of software forges and the emergence of Forgejo</h2>
<p>To understand the importance of this tool, one must look at the history of collaborative development.
For a long time, developers used centralized tools like SourceForge.
Then, GitHub became the global standard for storing <strong>code</strong>.</p>
<p>However, GitHub is owned by a very large private corporation.
This raises questions about data ownership and freedom of choice technological.
It is in this context of needing sovereignty that tools like Gitea appeared.</p>
<h3>Project origins and the conflict with Gitea Ltd</h3>
<p>Forgejo was born from a specific event in the free software ecosystem.
Originally, the tool was named Gitea and was managed by passionate volunteers.
But in 2022, a company called Gitea Ltd was created to monetize the tool without everyone’s consent.</p>
<p>The community feared losing its technical independence to financial interests.
They decided to create a “fork”: a free and community-led copy of the project.
This is how Forgejo was born to protect the actual interests of users.</p>
<h3>Codeberg and digital sovereignty in Europe</h3>
<p>Today, the Codeberg e.V. association oversees the development of the project.
It is a non-profit organization based in Germany, subject to European laws.
It guarantees that the software will always remain free, open, and ad-free for everyone.</p>
<p>Forgejo’s source <strong>code</strong> is fully public and can be audited by anyone.
Every developer can suggest a bug fix or a new improvement.
To do this, you just need to fill out a contribution <strong>form</strong> on their official platform.</p>
<h3>A Git forge managed as a common good</h3>
<p>Unlike private platforms, Forgejo has no shareholders to satisfy.
Priority remains on <strong>software</strong> stability and contributor satisfaction.
This democratic structure prevents any takeover by a single entity.</p>
<p>The project uses its resources to improve essential <strong>developer</strong> functions.
This avoids adding useless features that often bloat modern tools.
It is this philosophy of “chosen sobriety” that makes Forgejo strong.</p>
<h2>Technical performance adapted to eco-design</h2>
<p>Forgejo’s strength is undoubtedly its lightness and digital sobriety.
Unlike GitLab, which requires a lot of RAM, Forgejo is optimized for efficiency.</p>
<h3>A lightweight infrastructure for every project version</h3>
<p>The software is written in the Go (Golang) language, known for its high <strong>performance</strong>.
This language allows compilation into a single binary, very easy to deploy.
You can track every <strong>version</strong> of your project without slowing down your server, even under heavy load.</p>
<p>Forgejo can run on very modest hardware without losing responsiveness.
It is capable of running on a Raspberry Pi with only 100 MB of available RAM.
This is a major advantage for reducing the electricity consumption of data centers.</p>
<h3>Advanced functions for daily collaborative work</h3>
<p>Forgejo is not just a passive storage space for your <strong>code</strong>.
It includes all the modern tools to organize a technical team’s work:</p>
<ul>
<li>Integrated Kanban boards to track task progress in real time.</li>
<li>A powerful ticketing system (Issues) to manage bugs and suggestions.</li>
<li>A complete Wiki to document every feature of your <strong>software</strong>.</li>
</ul>

<p>Each tool is designed to be fast and accessible, even with a slow connection.
The interface is minimalist to avoid distracting the user from their main task.
This also reduces page weight and speeds up overall display on the <strong>web</strong>.</p>
<h3>Modern automation with Forgejo Actions</h3>
<p>Modern development requires testing <strong>code</strong> with every modification.
Forgejo now integrates its own CI/CD system called Forgejo Actions.
This allows running automatic tests to ensure everything works as expected.</p>
<p>The system is compatible with GitHub Actions configuration files.
You can migrate your current automations to Forgejo without rewriting everything.
This greatly facilitates the switch to a more respectful and private infrastructure.</p>
<h3>Technical choice: Go language vs Ruby</h3>
<p>Why is Forgejo so fast compared to its competitors?
The answer lies in the choice of the Go language used for its <strong>development</strong>.
Go consumes far fewer resources than Ruby or Java.</p>
<p>This allows managing thousands of repositories on a standard server.
This raw efficiency reduces hosting costs for companies.
It also helps extend the life of old hardware.</p>
<h3>Constant evolution towards version 10.0 and beyond</h3>
<p>The project progresses very fast thanks to a global community of contributors.
The recent <strong>version</strong> 10.0 brought major visual and technical improvements.
The user interface is smoother, and permission management is more precise.</p>
<p>The software also integrates the latest security standards on the market.
It natively supports two-factor authentication and physical security keys.
This is a crucial point for protecting your work against unauthorized access.</p>
<h2>Why choose Forgejo for your projects in 2026?</h2>
<p>Choosing a Git forge is a strategic decision that impacts the longevity of a project.
Forgejo offers the best balance today between freedom, security, and power.</p>
<h3>An ethical alternative to web giants</h3>
<p>By using Forgejo, you take back total control over your digital assets.
Your files are no longer stored with a <strong>web</strong> giant with opaque terms of service.
It is a strong commitment toward a more decentralized and respectful IT world.</p>
<p>This autonomy protects you against sudden price changes in cloud services.
It also allows you to comply with data protection regulations (GDPR).
Your <strong>code</strong> stays on an infrastructure that you control from end to end.</p>
<h3>Performance gain for your development workflow</h3>
<p>A lightweight server is a server that responds faster to your requests.
By using sober tools like Forgejo, you optimize your entire production chain.
This is exactly the <strong>performance</strong> philosophy I share on this technical blog.</p>
<p>Every millisecond saved on your tools increases your productivity.
It also reduces the frustration related to heavy and slow interfaces.
The tool fades away to make room for creativity and pure logic.</p>
<h3>Impact on SEO and brand image</h3>
<p>My goal is to prove that good <strong>SEO</strong> starts with a quality infrastructure.
Choosing Forgejo is part of this quest for global and sustainable quality.
It shows your partners that you take care of your technical environment.</p>
<p>By using Forgejo, you join an ecosystem that values <strong>code</strong> craftsmanship.
You invest in a tool that respects the user as much as the machine.
It is the way to build a healthier and faster digital future.</p>
<hr>
<h3>Frequently Asked Questions</h3>
<details>
<summary>How to import a project from GitHub to Forgejo?</summary>
Forgejo has a very powerful automatic import tool. You just need to enter your repository URL and an access key. The software then retrieves your <strong>code</strong>, your branches, and the entire history in a few seconds.
</details>
<details>
<summary>Is Forgejo free for a company?</summary>
Yes. Forgejo is distributed under a free license (MIT/GPL). You can use it for personal or commercial projects without paying any royalties. This is a significant saving for a small structure.
</details>
<details>
<summary>Can the Forgejo interface be customized?</summary>
Absolutely. You can change the colors and the logo to match your identity. Since the <strong>code</strong> is free, you have total freedom over the appearance of your Git instance.
</details>

            ]]></content:encoded>
        </item><item>
            <title>Web Accessibility: 6 Essential Steps to Master Inclusive Design</title>
            <link>https://lionel-peramo.com/posts/web-accessibility-guide/</link>
            <guid>https://lionel-peramo.com/posts/web-accessibility-guide/</guid>
            <pubDate>Tue, 30 Dec 2025 16:30:00 +0000</pubDate>
            <description>Master web accessibility with this deep guide. Discover 6 steps to improve SEO, comply with EAA 2025, and build inclusive digital products for all users.</description>
            <content:encoded><![CDATA[
              <p>⏱️ Reading time: 9 min</p>
              
<p>Web accessibility is the practice of making websites and applications usable for every human being.</p>
<p>This includes people with visual, motor, auditory, or cognitive disabilities.</p>
<p>Creating <strong>inclusive</strong> digital experiences is not just a technical task.</p>
<p>It is a fundamental human right in our modern world.</p>
<p>It is also a powerful way to reach the largest possible audience.</p>
<p>In this guide, we explore how to build better products for everyone.</p>
<h2>The Strategic Impact of Accessibility</h2>
<p>Many business owners think that <strong>accessibility</strong> is only for a small group of people.</p>
<p>This is a major mistake that limits your potential growth.</p>
<p>Making things accessible helps every user, even those without a permanent disability.</p>
<h3>Universal Design and the Curb Cut Effect</h3>
<p>The Curb Cut Effect is a very famous idea in the world of <strong>design</strong>.</p>
<p>It refers to the ramps cut into stone sidewalks for people in wheelchairs.</p>
<p>Initially, these were made for a specific group of citizens.</p>
<p>However, today these ramps help parents with heavy strollers.</p>
<p>They help travelers pulling large suitcases.</p>
<p>They even help skateboarders and delivery workers.</p>
<p>In the digital world, this same logic applies to every piece of <strong>code</strong> you write.</p>
<p>For example, <strong>subtitles</strong> on a video were first made for deaf people.</p>
<p>Now, they are used by millions of people in loud trains or quiet offices.</p>
<p>High <strong>contrast</strong> settings help people with very low vision.</p>
<p>But they also help you read your screen in bright sunlight on a beach.</p>
<p>Good <strong>design</strong> for a few people creates better products for many people.</p>
<p>By thinking about the edges, you improve the center of your <strong>user experience</strong>.</p>
<p>It is about creating a world where no one is left behind.</p>
<h3>SEO Synergy and Technical Search Benefits</h3>
<p>Google and other major search engines love <strong>inclusive</strong> websites.</p>
<p>A search bot acts very much like a person who cannot see the screen.</p>
<p>The bot cannot look at your colors or your beautiful images.</p>
<p>It only reads the underlying <strong>code</strong> of your web page.</p>
<p>If your site is easy for a screen reader to understand, it is easy for Google to index.</p>
<p>This creates a direct link between <strong>accessibility</strong> and <strong>SEO</strong> rankings.</p>
<p>Using a clear heading structure allows bots to find your main keywords quickly.</p>
<p>Adding descriptive text to your images helps you appear in image search results.</p>
<p>Furthermore, accessible websites are often much faster to load.</p>
<p>This is because they use cleaner files and less heavy scripts.</p>
<p>Fast loading times are a critical factor for your <strong>search engine optimization</strong>.</p>
<p>Google rewards sites that provide a high-quality experience for every visitor.</p>
<p>By fixing your site for disabled users, you are also training it for Google.</p>
<p>It is a win-win situation for your marketing and your community.</p>
<h3>Brand Trust and the EAA 2025 Legal Framework</h3>
<p>Building with <strong>inclusion</strong> shows that your brand cares about human beings.</p>
<p>It shows that you take your <strong>social responsibility</strong> seriously.</p>
<p>This builds deep trust with your customers and your local community.</p>
<p>People prefer to buy from companies that respect diversity.</p>
<p>Beyond the moral choice, there is also a major legal reason to act now.</p>
<p>The <strong>European Accessibility Act</strong>, or <strong>EAA</strong>, starts in 2025.</p>
<p>This law requires that many digital services must be accessible.</p>
<p>This includes online shops, banking apps, and transport services.</p>
<p>This is the most important <strong>version</strong> of digital law we have seen in years.</p>
<p>Companies that do not follow these rules may face very large fines.</p>
<p>They also risk damaging their reputation in the global market.</p>
<p>Starting your journey early protects your business from these legal risks.</p>
<p>It ensures that your site stays active and profitable for a long time.</p>
<h2>Technical Guidelines for Modern Web Products</h2>
<p>You do not need to be a genius to start making meaningful changes.</p>
<p>Most big wins come from following simple technical standards.</p>
<p>By focusing on the foundations, you will see a massive impact on your quality.</p>
<h3>The Evolution of WCAG Standards</h3>
<p>The <strong>WCAG</strong> is the global rulebook for all web <strong>accessibility</strong> work.</p>
<p>Experts from around the world update these rules to follow new technology.</p>
<p>There are different levels of success, known as A, AA, and AAA.</p>
<p>Most businesses should aim for the AA level to be safe and helpful.</p>
<p>You should always try to follow the latest <strong>version</strong> of the guidelines.</p>
<p>Currently, the most modern <strong>version</strong> is 2.2.</p>
<p>This <strong>version</strong> includes new rules about mobile devices and touch screens.</p>
<p>It makes sure that buttons are large enough for people with motor issues.</p>
<p>It also ensures that users do not get confused by complex animations.</p>
<p>Following the latest <strong>version</strong> guarantees that your site works for modern tools.</p>
<p>It keeps your technology fresh and ready for the future.</p>
<p>Consistent updates to your <strong>code</strong> help maintain this high standard of quality.</p>
<h3>Semantic HTML vs Component Complexity</h3>
<p>The most effective way to build a site is to use <strong>Semantic HTML</strong>.</p>
<p>Modern developers often use too many generic tags like <code>&lt;div&gt;</code> or <code>&lt;span&gt;</code>.</p>
<p>This creates what experts call a “div-soup” in your <strong>code</strong>.</p>
<p>A <code>&lt;div&gt;</code> tag has no special meaning for a screen reader or a bot.</p>
<p>If you want a button, you should always use the <code>&lt;button&gt;</code> tag.</p>
<p>Native tags provide keyboard support and focus management automatically.</p>
<p>They make your files lighter and much easier for other developers to read.</p>
<p>When you use the wrong tag, you have to write extra JavaScript to fix it.</p>
<p>This makes your <strong>code</strong> fragile and increases the risk of errors.</p>
<p>Simple, native tags are more robust than complex custom scripts.</p>
<p>Always choose the simplest tag that correctly describes your content.</p>
<p>This is the secret to building a fast and stable <strong>inclusive</strong> interface.</p>
<h3>User Interaction and High-Conversion Forms</h3>
<p>The <strong>form</strong> is often the place where users interact most with your brand.</p>
<p>It is where they buy your products or sign up for your email list.</p>
<p>If your <strong>form</strong> is not accessible, you are losing money every single day.</p>
<p>An inaccessible <strong>form</strong> is the fastest way to kill your conversion rate.</p>
<p>Every single input field must have a clear <code>&lt;label&gt;</code> attached to it.</p>
<p>This label tells the user exactly what information you are asking for.</p>
<p>Do not use only placeholder text inside the box.</p>
<p>Placeholders disappear when the user starts typing, which causes confusion.</p>
<p>Also, make sure that errors are easy to see and clearly explained.</p>
<p>A good <strong>form</strong> allows users to navigate through every box using only the <code>Tab</code> key.</p>
<p>It does not rely only on colors like red or green to show mistakes.</p>
<p>You should always use text or icons to help people who are colorblind.</p>
<p>Testing your <strong>form</strong> with real users is the best way to ensure it works.</p>
<p>A fast and simple <strong>form</strong> is a key part of a great <strong>user experience</strong>.</p>
<hr>
<h3>Frequently Asked Questions</h3>
<details>
<summary>How does accessibility help my Google SEO ranking?</summary>
Accessibility improves your internal site structure and the quality of your code. Google uses these technical signals to decide if your page is high quality. A well-structured page is much easier for search bots to understand, crawl, and index properly in the search results.
</details>
<details>
<summary>Is there a free tool to check my website for accessibility?</summary>
Yes. You can use free browser tools like WAVE or Axe to find common errors. These tools look at your code and highlight issues like missing labels or low color contrast. They are a great starting point, but you should also test your site using only your keyboard to find navigation problems.
</details>
<details>
<summary>What is the EAA 2025 law and who does it affect?</summary>
The European Accessibility Act (EAA) is a law that requires digital products to be accessible by June 2025. It affects most private companies that provide essential services like e-commerce, banking, and media. Non-compliance can lead to legal action and significant fines for the business owners.
</details>
<details>
<summary>Do I need to change my whole design for accessibility?</summary>
In most cases, you do not need to start from zero. Small, targeted changes often make the biggest difference for your users. Fixing your color contrast ratios, adding proper labels to your forms, and using semantic HTML tags is usually enough to significantly improve your score.
</details>

            ]]></content:encoded>
        </item><item>
            <title>History of PHP: Discover 30 Years of Evolution</title>
            <link>https://lionel-peramo.com/posts/history-of-php/</link>
            <guid>https://lionel-peramo.com/posts/history-of-php/</guid>
            <pubDate>Wed, 10 Dec 2025 18:27:00 +0000</pubDate>
            <description>From Rasmus Lerdorf in 1994 to PHP 8 today. Explore the complete history of PHP and understand how it became the backbone of the modern web.</description>
            <content:encoded><![CDATA[
              <p>⏱️ Reading time: 8 min</p>
              
<p>The story of PHP is one of resilience, community, and constant reinvention.</p>
<p>What started as a simple hacking tool for a personal resume has evolved into the engine powering the vast majority of the internet.</p>
<p>To understand the modern web, one must understand the journey of PHP. It is a language that refused to die, adapting to every new era of the internet.</p>
<h2>The History and Evolution of PHP</h2>
<p>The journey of PHP is not just about syntax; it is the story of how the web transitioned from static HTML pages to the dynamic, interactive applications we use every day.</p>
<ol>
<li>
<p>The beginning (1994)<br>
It all started with Rasmus Lerdorf. In 1994, the web was a very different place, consisting mostly of static text and images.</p>
<p>Lerdorf wrote the initial <strong>code</strong> to manage his personal web <strong>page</strong>. His goal was simple: strictly to track who was viewing his online resume.</p>
<p>Initially named “Personal Home Page Tools,” these were simple Common Gateway Interface (CGI) binaries written in C.</p>
<p>At this stage, it wasn’t even meant to be a <strong>programming language</strong>. It was merely a collection of practical utilities to handle repetitive tasks that HTML couldn’t solve on its own.</p>
</li>
<li>
<p>The growth (1995-1997)<br>
By 1995, a new <strong>version</strong> known as PHP/FI (Forms Interpreter) was introduced. This was a massive leap forward for the early web.</p>
<p>It allowed scripts to process a web <strong>form</strong>, communicate with databases like mSQL, and generate dynamic content based on user input. This was revolutionary for its time.</p>
<p>Before this innovation, connecting a webpage to a database was a complex, compiled affair requiring specialized knowledge in C or Perl. PHP made it accessible to everyone.</p>
<p>It quickly became open-source, enabling developers worldwide to contribute fixes and improvements. By 1997, PHP/FI 2.0 was running on thousands of domains, proving that there was a hunger for a simpler way to build dynamic sites.</p>
</li>
<li>
<p>The turning point (1998-Present)<br>
PHP 3 (1998) marked a new era and the professionalization of the project. Andi Gutmans and Zeev Suraski joined forces with Lerdorf to rewrite the core engine.</p>
<p>They created the famous “Zend Engine”. A complete rewrite transformed it from a simple tool into a full-fledged programming <strong>language</strong>.</p>
<p>This powerful <strong>language</strong> introduced features like extensibility and better support for object-oriented programming.</p>
<p>This period also saw the rise of the “LAMP stack” (Linux, Apache, MySQL, PHP), which democratized web hosting. Suddenly, anyone could host a dynamic application cheaply.</p>
<p>Later, PHP 5 consolidated this dominance by introducing a robust object model, cementing PHP as the standard for enterprise web development. Despite the cancelled PHP 6 project, the community rallied to produce PHP 7, saving the language from obsolescence.</p>
</li>
</ol>
<h2>Why PHP Dominates the Modern Web</h2>
<p>Fast forward to today, <strong>PHP</strong> remains a giant, shrugging off predictions of its demise. It persists not because of legacy, but because it is uniquely suited to the web’s needs.</p>
<h3>Market Share &amp; CMS</h3>
<p>PHP powers nearly 77.5% of all websites with known server-side languages. This statistic is staggering and hard to ignore.</p>
<p>It is largely driven by the Content Management System (CMS) revolution. Major platforms like WordPress, Drupal, and Magento rely on it, ensuring its omnipresence.</p>
<p>When you browse a blog, buy a product on a small e-commerce site, or read a news portal, there is a very high probability that PHP is generating that HTML.</p>
<p>The “WordPress economy” alone employs millions of developers, designers, and hosting providers. This creates a self-sustaining ecosystem that keeps PHP relevant and constantly updated.</p>
<h3>The Framework Ecosystem</h3>
<p>In the early 2000s, PHP code could be messy (often called “spaghetti code”). That changed with the arrival of modern tools and standards.</p>
<p>Frameworks like Laravel and Symfony bring modern standards to the ecosystem. They allow for rapid, secure, and structured development comparable to any other modern stack like Ruby on Rails or Django.</p>
<p>Crucially, the introduction of “Composer,” a dependency manager, revolutionized how PHP developers work. It allowed them to share libraries easily.</p>
<p>This moved PHP from a language of copy-pasted scripts to a modular, professional architecture. Today, a PHP developer uses the same design patterns (MVC, Dependency Injection) as a Java or C# architect.</p>
<h3>Performance Innovation</h3>
<p><strong>PHP</strong> has never stopped innovating, specifically regarding speed. In the past, PHP was criticized for being slower than compiled languages.</p>
<p>The community responded aggressively to this criticism. PHP 7 brought dramatic performance improvements, doubling the speed of many applications compared to PHP 5.6.</p>
<p>They achieved this by optimizing the memory footprint and the engine’s execution pipeline.</p>
<p>More recently, PHP 8 introduced modern features like JIT (Just In Time compilation) and better type safety.</p>
<p>The JIT compiler monitors code execution and compiles parts of it into machine code at runtime. This offers potential performance boosts for CPU-intensive tasks, opening new doors for PHP beyond simple request-response cycles.</p>
<h3>Asynchronous Future</h3>
<p>Traditionally, PHP was synchronous: one request, one process. This is simple but can be limiting for real-time applications.</p>
<p>However, the paradigm is shifting. Tools like Swoole enable asynchronous programming, pushing boundaries of what the web can do.</p>
<p>Along with an active community ensuring constant updates, PHP adapts to modern <strong>web</strong> needs without losing its simplicity.</p>
<p>Projects like ReactPHP and native Fibers (introduced in PHP 8.1) allow developers to write non-blocking code. This makes PHP capable of handling WebSockets, real-time notifications, and high-concurrency microservices—territories previously reserved for Node.js or Go.</p>
<hr>
<h3>Frequently Asked Questions</h3>
<details>
<summary>Is PHP still relevant in 2025?</summary>
Absolutely. Despite the rise of new languages, PHP powers over 77% of the web. As detailed in this retrospective on Lionel Péramo's Blog, its continuous evolution, the introduction of strict typing, and the robustness of frameworks like Laravel keep it a top choice for backend development.
</details>
<details>
<summary>Can PHP handle high-traffic websites?</summary>
Yes. Giants like Slack, Wikipedia, Etsy, and Facebook use PHP. With modern features like the JIT compiler, OPcache, and asynchronous tools like Swoole, PHP is highly performant at scale and powers some of the most visited pages on the internet.
</details>
<details>
<summary>Is PHP difficult to learn for beginners?</summary>
No, it is considered one of the easiest languages to start with. Unlike stricter languages like Java or C++, PHP is "forgiving" and allows you to write code and see the result on a web page immediately. This low barrier to entry makes it ideal for learning web development logic before moving to complex architectures.
</details>

            ]]></content:encoded>
        </item>
    </channel>
    </rss>