<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pavel Borisov</title>
    <description>The latest articles on DEV Community by Pavel Borisov (@pavelcraft).</description>
    <link>https://dev.to/pavelcraft</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4187796%2Fad9ef788-f900-4203-af5c-a98e07554e8c.jpg</url>
      <title>DEV Community: Pavel Borisov</title>
      <link>https://dev.to/pavelcraft</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pavelcraft"/>
    <language>en</language>
    <item>
      <title>Why CSS Selectors Break — and How I Built StableHTMLFinder to Analyze DOM Stability</title>
      <dc:creator>Pavel Borisov</dc:creator>
      <pubDate>Tue, 20 Oct 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/pavelcraft/why-css-selectors-break-and-how-i-built-stablehtmlfinder-to-analyze-dom-stability-30n2</link>
      <guid>https://dev.to/pavelcraft/why-css-selectors-break-and-how-i-built-stablehtmlfinder-to-analyze-dom-stability-30n2</guid>
      <description>&lt;p&gt;If you've ever written CSS selectors for browser automation, web scraping, or blocking unwanted elements, you've probably encountered this situation: a selector works perfectly today, but tomorrow it can no longer find the element you need.&lt;/p&gt;

&lt;p&gt;Often, the problem isn't the selector itself. It's the page.&lt;/p&gt;

&lt;p&gt;Modern websites frequently use dynamically generated classes, changing attributes, advertising elements, and JavaScript-driven interfaces whose DOM structure can differ between page loads.&lt;/p&gt;

&lt;p&gt;I encountered this problem while developing &lt;strong&gt;BlockIt&lt;/strong&gt;, a Chrome extension for blocking unwanted elements on web pages.&lt;/p&gt;

&lt;p&gt;At some point, I needed a tool that would help me understand which parts of the DOM actually remain unchanged across repeated page loads.&lt;/p&gt;

&lt;p&gt;That's how &lt;strong&gt;StableHTMLFinder&lt;/strong&gt; was born.&lt;/p&gt;

&lt;p&gt;In this article, I'll explain why I created it, what a DOM stability map is, and how it helps identify reliable element characteristics — without going into the internal implementation of its algorithms.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: The DOM Keeps Changing
&lt;/h2&gt;

&lt;p&gt;Imagine you want to hide an advertising block on a website.&lt;/p&gt;

&lt;p&gt;You open DevTools, inspect the element, and see something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"ad-container_x7Kp2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"banner_9fA31"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Advertisement
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could write a selector:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.ad-container_x7Kp2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works. But after refreshing the page, the HTML looks different:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"ad-container_m4Rz8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"banner_2qB76"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Advertisement
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your selector no longer matches the element.&lt;/p&gt;

&lt;p&gt;Of course, you could try matching part of the class name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;class&lt;/span&gt;&lt;span class="o"&gt;^=&lt;/span&gt;&lt;span class="s1"&gt;"ad-container_"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this approach only works when dynamically generated values follow a predictable pattern.&lt;/p&gt;

&lt;p&gt;What if not only classes but also IDs, attributes, nesting levels, or element positions change?&lt;/p&gt;

&lt;p&gt;You have to examine the surrounding DOM structure and look for more reliable reference points.&lt;/p&gt;

&lt;p&gt;This leads to the central question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How can we distinguish genuinely stable DOM characteristics from those that merely happen to look stable in the current page load?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a Single DOM Snapshot Isn't Enough
&lt;/h2&gt;

&lt;p&gt;Many conventional selector-generation tools analyze the current state of a page.&lt;/p&gt;

&lt;p&gt;They can identify a unique class or ID, construct a CSS path, or generate an XPath expression.&lt;/p&gt;

&lt;p&gt;But uniqueness and stability are two very different things.&lt;/p&gt;

&lt;p&gt;Consider this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"action_583921"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn_8xQ2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Continue
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ID &lt;code&gt;action_583921&lt;/code&gt; might be unique on the page. But that tells us nothing about whether it will remain the same after a refresh.&lt;/p&gt;

&lt;p&gt;A tool that examines only one DOM snapshot cannot directly observe how that ID changes between page loads.&lt;/p&gt;

&lt;p&gt;Of course, heuristics can help identify classes or IDs that appear to be dynamically generated. But an educated guess is not the same as observation.&lt;/p&gt;

&lt;p&gt;When I started developing StableHTMLFinder in 2026, I couldn't find a tool that automatically collected multiple snapshots of the same page and used them to build a visual map of stable elements and their characteristics.&lt;/p&gt;

&lt;p&gt;And I wasn't trying to build another selector generator.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My original idea was much simpler: remove all the unstable noise from the DOM and see what remains.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing the DOM Stability Map
&lt;/h2&gt;

&lt;p&gt;StableHTMLFinder is a free Chrome extension that analyzes multiple consecutive page loads and builds a &lt;strong&gt;stability map&lt;/strong&gt; from the collected DOM snapshots.&lt;/p&gt;

&lt;p&gt;Its structure resembles a DOM tree, but with one fundamental difference: it displays only elements and characteristics whose stability has been established during the analysis.&lt;/p&gt;

&lt;p&gt;Suppose the same element appears across several page loads.&lt;/p&gt;

&lt;p&gt;First load:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"content_a72"&lt;/span&gt; &lt;span class="na"&gt;data-session=&lt;/span&gt;&lt;span class="s"&gt;"1842"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"section-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;News&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Second load:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"content_b91"&lt;/span&gt; &lt;span class="na"&gt;data-session=&lt;/span&gt;&lt;span class="s"&gt;"7501"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"section-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;News&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Third load:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"content_c38"&lt;/span&gt; &lt;span class="na"&gt;data-session=&lt;/span&gt;&lt;span class="s"&gt;"3926"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"section-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;News&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this simplified example, we can observe that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;section&lt;/code&gt; tag remains unchanged.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;class&lt;/code&gt; attribute is always present, but its value changes.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;data-session&lt;/code&gt; attribute is always present, but its value also changes.&lt;/li&gt;
&lt;li&gt;The child &lt;code&gt;h2&lt;/code&gt; element and its class remain unchanged.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the elements can be matched reliably across page loads, the stability map might represent the structure approximately like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt; &lt;span class="na"&gt;data-session&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"section-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        News
    &lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This is a schematic illustration, not an exact representation of the StableHTMLFinder interface.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Notice that the attribute names &lt;code&gt;class&lt;/code&gt; and &lt;code&gt;data-session&lt;/code&gt; remain, while their unstable values disappear.&lt;/p&gt;

&lt;p&gt;The stability map can therefore distinguish between several situations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An element, its attributes, and their values are stable.&lt;/li&gt;
&lt;li&gt;An element and certain attribute names are stable, but their values are not.&lt;/li&gt;
&lt;li&gt;The element itself can be identified across page loads, but its attributes provide no reliable reference points.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The purpose of this representation isn't to show as much HTML as possible.&lt;/p&gt;

&lt;p&gt;It's to retain only information that may be useful for constructing a reliable selector.&lt;/p&gt;

&lt;p&gt;Instead of examining dozens of random-looking classes, you can focus on characteristics that actually remain consistent across page loads.&lt;/p&gt;

&lt;p&gt;Here's what a section of the stability map looks like in practice. This example shows a fully stable part of a web page, where elements and their attributes remain consistent across multiple page loads. The tree-like structure makes it easy to explore these elements and their relationships without the distraction of unstable DOM characteristics.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhegy4haulb9pjj6dcgf5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhegy4haulb9pjj6dcgf5.png" alt=" " width="800" height="663"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Fully Stable and Relatively Stable Elements
&lt;/h2&gt;

&lt;p&gt;Not every element can be matched across page loads with the same level of confidence.&lt;/p&gt;

&lt;p&gt;That's why StableHTMLFinder distinguishes between fully stable and relatively stable elements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fully stable elements&lt;/strong&gt; are the most reliable parts of the stability map. Their own characteristics, along with those of their parents and immediate children, match exactly across the analyzed snapshots.&lt;/p&gt;

&lt;p&gt;These elements provide particularly useful reference points when examining the page structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Relatively stable elements&lt;/strong&gt; are elements for which there is sufficient evidence that they represent the same DOM element across different page loads, even though some characteristics or parts of the surrounding structure may change.&lt;/p&gt;

&lt;p&gt;They are displayed in a lighter color on the stability map.&lt;/p&gt;

&lt;p&gt;This is an important distinction: StableHTMLFinder doesn't assume that everything on a page must be either completely stable or entirely unsuitable for analysis.&lt;/p&gt;

&lt;p&gt;In real-world web applications, things are much more complicated.&lt;/p&gt;

&lt;p&gt;An element may retain its purpose while its classes change. Its parent may receive new attributes. Additional containers may appear between otherwise familiar elements.&lt;/p&gt;

&lt;p&gt;Rather than discarding everything that isn't perfectly stable, StableHTMLFinder preserves elements whose identity can still be established with reasonable confidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Islands of Stability Inside a Dynamic DOM
&lt;/h2&gt;

&lt;p&gt;One of the more interesting features of StableHTMLFinder is its ability to display &lt;strong&gt;islands of stability&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine that an entire chain of nested containers changes between page loads.&lt;/p&gt;

&lt;p&gt;During one load, the element you're interested in is nested inside two intermediate containers. During another, it might be nested inside four. Their classes and attributes may also be different.&lt;/p&gt;

&lt;p&gt;But somewhere inside this unstable structure, an element with recognizable characteristics remains.&lt;/p&gt;

&lt;p&gt;It would be a mistake to discard that element simply because its ancestors are unstable.&lt;/p&gt;

&lt;p&gt;StableHTMLFinder can preserve such an element on the stability map while representing the unstable intermediate levels using special gray placeholders.&lt;/p&gt;

&lt;p&gt;These placeholders resemble elements in the tree, but they actually represent unstable structures with potentially varying nesting depths.&lt;/p&gt;

&lt;p&gt;As a result, you can see that an unstable region exists between stable parts of the page without losing the ability to examine the elements inside it.&lt;/p&gt;

&lt;p&gt;This can be particularly useful on websites where JavaScript dynamically rebuilds parts of the interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding Elements on the Stability Map
&lt;/h2&gt;

&lt;p&gt;Suppose you've found an element on a website that you want to block.&lt;/p&gt;

&lt;p&gt;You open DevTools and inspect its HTML, but the classes and IDs look randomly generated.&lt;/p&gt;

&lt;p&gt;Instead of manually examining numerous parent and child elements, you can use StableHTMLFinder's search feature.&lt;/p&gt;

&lt;p&gt;The search supports several approaches, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pasting an HTML element copied from DevTools.&lt;/li&gt;
&lt;li&gt;Entering a selector to locate the corresponding element.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the element exists on the stability map, you can navigate to its card and examine the available stable characteristics.&lt;/p&gt;

&lt;p&gt;This provides a convenient way to move from the original DOM, filled with dynamically changing values, to a cleaner representation of the same page.&lt;/p&gt;

&lt;p&gt;It's particularly helpful when the target element itself has no reliable attributes, but more stable elements exist nearby.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Improve Search Accuracy
&lt;/h3&gt;

&lt;p&gt;StableHTMLFinder performs its search primarily against the last DOM snapshot collected during the analysis.&lt;/p&gt;

&lt;p&gt;If you haven't reloaded the page since the analysis finished, and the target element hasn't changed due to JavaScript activity, you can copy it from DevTools and paste it into the search field.&lt;/p&gt;

&lt;p&gt;In this case, the extension will accurately locate the corresponding element on the stability map, even if all its attributes and their values turned out to be unstable and only the element's tag remains on the map.&lt;/p&gt;

&lt;p&gt;If, however, you copied an element that had already changed since the last DOM snapshot, the search may still succeed. StableHTMLFinder will attempt to match it using the characteristics that remain recognizable, but with a lower level of confidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automatic Selector Generation
&lt;/h2&gt;

&lt;p&gt;Although StableHTMLFinder was originally designed as a visual DOM analysis tool, I later added automatic selector generation.&lt;/p&gt;

&lt;p&gt;It seemed like a natural extension of the original idea.&lt;/p&gt;

&lt;p&gt;If the tool has already identified stable characteristics of an element and its surroundings, why not try generating a selector from them?&lt;/p&gt;

&lt;p&gt;From an element's card, you can obtain a suggested selector and copy it.&lt;/p&gt;

&lt;p&gt;A human-readable explanation is displayed alongside the selector, describing which characteristics were used to construct it.&lt;/p&gt;

&lt;p&gt;I consider this important because a selector shouldn't be an incomprehensible string that users have to trust blindly.&lt;/p&gt;

&lt;p&gt;However, there's an important limitation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In particularly complex cases, StableHTMLFinder may be unable to generate a unique selector for a given element.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Although the extension can usually generate a unique selector, some elements lack a unique combination of stable characteristics within their nearby DOM structure. In these rare cases, StableHTMLFinder clearly indicates that a unique selector could not be generated.&lt;/p&gt;

&lt;p&gt;Some pages are structured in ways that simply don't provide enough stable characteristics.&lt;/p&gt;

&lt;p&gt;In those cases, the stability map can still be valuable because it gives you the information needed to investigate the problem and develop your own solution.&lt;/p&gt;

&lt;p&gt;That's why I see automatic selector generation as a convenience feature rather than the extension's primary purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  How StableHTMLFinder Connects to BlockIt
&lt;/h2&gt;

&lt;p&gt;StableHTMLFinder originated while I was working on another project of mine: &lt;strong&gt;BlockIt&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;BlockIt is a Chrome extension for blocking unwanted elements on web pages.&lt;/p&gt;

&lt;p&gt;It supports rules based on CSS, XPath, and additional conditions, along with more advanced methods of locating elements.&lt;/p&gt;

&lt;p&gt;But even a powerful rule syntax can't solve the fundamental problem: if a rule relies on unstable characteristics, it may stop working after the next page load.&lt;/p&gt;

&lt;p&gt;StableHTMLFinder helps identify more reliable reference points for those rules.&lt;/p&gt;

&lt;p&gt;The two extensions serve different purposes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;StableHTMLFinder&lt;/strong&gt; analyzes a page, displays its stability map, and helps create selectors. It doesn't block anything itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BlockIt&lt;/strong&gt; uses rules to locate and block unwanted elements on web pages.&lt;/p&gt;

&lt;p&gt;StableHTMLFinder can also suggest special rules designed for use with BlockIt.&lt;/p&gt;

&lt;p&gt;In other words, one extension helps you investigate the DOM and prepare a rule, while the other applies that rule in practice.&lt;/p&gt;

&lt;p&gt;I'll cover BlockIt and its capabilities in a separate article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can StableHTMLFinder Be Useful Beyond Ad Blocking?
&lt;/h2&gt;

&lt;p&gt;Although the project grew out of the need to block unwanted elements, unstable DOM locators are a problem in other areas as well.&lt;/p&gt;

&lt;p&gt;One example is browser automation and UI testing.&lt;/p&gt;

&lt;p&gt;If a test relies on a dynamically generated class, it may fail after a page update even though the button or form it's supposed to interact with still exists.&lt;/p&gt;

&lt;p&gt;A stability map could potentially help developers identify more reliable reference points.&lt;/p&gt;

&lt;p&gt;Similar challenges sometimes arise when writing browser scripts or extracting data from websites.&lt;/p&gt;

&lt;p&gt;However, StableHTMLFinder isn't a universal solution for these scenarios. Its usefulness depends on the structure of the particular website and whether sufficiently stable characteristics can be identified.&lt;/p&gt;

&lt;p&gt;There's also an important distinction between observed stability and guaranteed future stability.&lt;/p&gt;

&lt;p&gt;Just because an element remained unchanged across several page loads doesn't mean it will never change.&lt;/p&gt;

&lt;p&gt;The stability map reflects the results of the analysis, not an absolute guarantee.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Think This Approach Matters
&lt;/h2&gt;

&lt;p&gt;When developing StableHTMLFinder, I wanted to change the way I worked with the DOM.&lt;/p&gt;

&lt;p&gt;Normally, a developer opens DevTools, sees an enormous tree of elements, and tries to figure out which characteristics are suitable for a selector.&lt;/p&gt;

&lt;p&gt;But much of that information may be useless: random classes, temporary IDs, dynamic attributes, and constantly changing containers.&lt;/p&gt;

&lt;p&gt;StableHTMLFinder takes a different approach:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First, identify what remains stable across page loads. Then decide how to use those characteristics.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This doesn't eliminate every challenge associated with dynamic DOM structures, and it doesn't make selectors immune to future website changes.&lt;/p&gt;

&lt;p&gt;But it allows you to focus on more reliable information and reduce the amount of manual investigation required.&lt;/p&gt;

&lt;p&gt;And perhaps that best captures the original idea behind the project: not necessarily to write a selector for you, but to let you see a web page without the noise of constantly changing DOM characteristics.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try StableHTMLFinder
&lt;/h2&gt;

&lt;p&gt;StableHTMLFinder is a free Chrome extension.&lt;/p&gt;

&lt;p&gt;If you'd like to try it yourself, visit the &lt;strong&gt;&lt;a href="https://formacode.dev/en/stablehtmlfinder" rel="noopener noreferrer"&gt;official StableHTMLFinder project page&lt;/a&gt;&lt;/strong&gt;, where you'll find a link to install the extension from the Chrome Web Store.&lt;/p&gt;

&lt;p&gt;If you work with dynamic web pages, I'd be interested to hear what challenges you've encountered with selector stability and how you've approached solving them.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>css</category>
      <category>tools</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
