{"id":197,"date":"2026-08-09T04:09:56","date_gmt":"2026-08-09T04:09:56","guid":{"rendered":"https:\/\/www.serbeld.space\/en\/?p=197"},"modified":"2026-08-09T04:09:56","modified_gmt":"2026-08-09T04:09:56","slug":"accessibility-cost-of-infinite-scroll","status":"publish","type":"post","link":"https:\/\/www.serbeld.space\/en\/2026\/08\/09\/accessibility-cost-of-infinite-scroll\/","title":{"rendered":"The Accessibility Cost of Infinite Scroll (and What to Ship Instead)"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">A Colombian newspaper ran a piece recently about infinite scroll as a thief of time, with psychologists explaining the reward loop and readers being told to set alarms every fifteen minutes. It is a fair article. It is also aimed at the wrong audience. The people who can actually fix infinite scroll are not the ones scrolling. They are the ones shipping it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Aza Raskin built the pattern in 2006 as a navigation convenience and has spent years since saying he regrets it. Twenty years later it is a default. Somebody reaches for a feed, somebody wires up an <code>IntersectionObserver<\/code>, and the last page quietly stops existing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here is the part the wellness coverage misses: infinite scroll is not only an attention problem. It is one of the most reliable ways to ship an inaccessible page. I have audited enough interfaces against WCAG for the US market to say that with some confidence. The same design decision that removes the ending for a casual reader removes the entire footer for a keyboard user.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What the pattern actually removes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Physical media has closure signals built in. A book has a last page. A film has credits. A paginated list has a page 4 of 4. Those endings are not decoration, they are the moment a person gets to decide whether to continue.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Infinite scroll deletes that moment. And once you delete it, four technical failures tend to follow, all of them mine to fix as the person writing the component.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. The footer becomes unreachable<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This is the one that shows up in every audit. Your privacy policy, contact link, accessibility statement, and legal pages live in the footer. A sighted mouse user can hammer End and maybe catch it. A keyboard user tabbing forward never arrives, because every time they approach the bottom, twenty new focusable links get injected ahead of the footer. The footer recedes forever.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That is a WCAG 2.1.1 and 2.4.3 problem, and in a US compliance context it is the kind of finding that ends up in a demand letter. It is also completely avoidable.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2. New content arrives silently<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">You appended thirty articles to the DOM. A screen reader user has no idea. There was no announcement, no focus change, no status message. From their side the page simply did nothing, forever.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3. Back navigation loses the position<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">User scrolls through 200 items, opens one, hits back, and lands at item 1. This is not a minor annoyance, it is the single most common complaint about infinite scroll in ecommerce catalogs, and it is a direct revenue problem. Every restart is an abandonment opportunity.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">4. The page gets heavier until it dies<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Without virtualization, node count grows without bound. Layout and paint costs climb with it, CLS degrades as images settle in, and on a mid range Android phone the thing eventually just stops responding. Anyone who has run Lighthouse on a long feed has seen the curve.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The default that should have been the default<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A Load more button. That is it. It costs one click and it fixes almost everything above at once: the footer stays reachable, the user keeps an explicit decision point, back navigation is trivial to restore, and the growth of the DOM is bounded by intent instead of by inertia.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function ResultsList({ items, hasMore, onLoadMore, loading }) {\n  const [announcement, setAnnouncement] = useState(\"\");\n  const firstNewRef = useRef(null);\n  const previousCount = useRef(items.length);\n\n  useEffect(() =&gt; {\n    const added = items.length - previousCount.current;\n    if (added &gt; 0) {\n      setAnnouncement(`${added} more results loaded. ${items.length} of ${total} shown.`);\n      firstNewRef.current?.focus();\n    }\n    previousCount.current = items.length;\n  }, [items.length]);\n\n  return (\n    &lt;&gt;\n      &lt;ul&gt;\n        {items.map((item, i) =&gt; (\n          &lt;li key={item.id}&gt;\n            &lt;a\n              href={item.href}\n              ref={i === previousCount.current ? firstNewRef : null}\n              tabIndex={-1}\n            &gt;\n              {item.title}\n            &lt;\/a&gt;\n          &lt;\/li&gt;\n        ))}\n      &lt;\/ul&gt;\n\n      &lt;p role=\"status\" aria-live=\"polite\" className=\"visually-hidden\"&gt;\n        {announcement}\n      &lt;\/p&gt;\n\n      {hasMore &amp;&amp; (\n        &lt;button type=\"button\" onClick={onLoadMore} disabled={loading}&gt;\n          {loading ? \"Loading\u2026\" : \"Load more results\"}\n        &lt;\/button&gt;\n      )}\n    &lt;\/&gt;\n  );\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Three details in there matter more than the rest. The <code>role=\"status\"<\/code> region with <code>aria-live=\"polite\"<\/code> announces the change without interrupting whatever the user is reading. Moving focus to the first newly added item means a keyboard user resumes exactly where the new content begins rather than at the top. And the count in the announcement, <em>60 of 240 shown<\/em>, is the closure signal the pattern threw away. People deserve to know how much is left.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Keep <code>visually-hidden<\/code> as a clip based utility, not <code>display: none<\/code>. Hidden elements are removed from the accessibility tree and your announcement will never fire.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">If you genuinely need automatic loading<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Sometimes the product decision is already made and you are not going to win that argument. Fine. You can still make it survive an audit by treating the observer as a progressive enhancement on top of a real button rather than a replacement for one.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const sentinelRef = useRef(null);\nconst [autoLoads, setAutoLoads] = useState(0);\nconst MAX_AUTO_LOADS = 3;\n\nuseEffect(() =&gt; {\n  const el = sentinelRef.current;\n  if (!el || !hasMore || autoLoads &gt;= MAX_AUTO_LOADS) return;\n\n  const reducedMotion = window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n  if (reducedMotion) return;\n\n  const observer = new IntersectionObserver(\n    ([entry]) =&gt; {\n      if (entry.isIntersecting) {\n        onLoadMore();\n        setAutoLoads((n) =&gt; n + 1);\n      }\n    },\n    { rootMargin: \"400px\" }\n  );\n\n  observer.observe(el);\n  return () =&gt; observer.disconnect();\n}, [hasMore, autoLoads, onLoadMore]);<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The cap is the whole point. After three automatic loads the sentinel stops firing and the button takes over permanently. The user gets the frictionless experience the product manager wanted for the first stretch, and then the interface hands control back. The footer becomes reachable again. Nobody scrolls for forty minutes by accident.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>rootMargin<\/code> of 400px preloads before the user hits the bottom so it still feels instant. And respecting <code>prefers-reduced-motion<\/code> here is not strictly required by the spec, but users who set it are generally telling you they do not want the page moving on its own.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Restoring scroll position without a library<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The back button problem has a boring fix that almost nobody implements: put the page count in the URL and let the browser do its job.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ after each successful load\nconst url = new URL(window.location);\nurl.searchParams.set(\"loaded\", String(page));\nwindow.history.replaceState({ page, scrollY: window.scrollY }, \"\", url);\n\n\/\/ on mount\nconst restore = Number(new URLSearchParams(location.search).get(\"loaded\")) || 1;\n\/\/ fetch pages 1..restore, then:\nrequestAnimationFrame(() =&gt; {\n  window.scrollTo(0, history.state?.scrollY ?? 0);\n});<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Use <code>replaceState<\/code> rather than <code>pushState<\/code> so you are not stuffing the history stack with one entry per scroll batch. Refetching several pages on return is not free, but it is cheaper than losing the session, and it makes the URL shareable at the depth the user actually reached.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">When infinite scroll is the right call<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">It is not always wrong. The distinction that has held up for me is whether the user has a task.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li><strong>Browsing without a goal<\/strong>, like a social feed or a photo gallery, is where the pattern is honest. There is no last item and no completion state to deny anyone.<\/li>\n\n\n<li><strong>Search results and product catalogs<\/strong> are where it hurts most. The user is comparing, wants to know how many options exist, and needs to get back to item 47. Pagination or Load more wins on every metric that matters here.<\/li>\n\n\n<li><strong>Documentation, tables, and anything with a footer that carries obligations<\/strong> should never use it. Legal links, contact routes, and accessibility statements cannot live behind a receding horizon.<\/li>\n\n\n<li><strong>Admin and data tools<\/strong> need offsets and counts. Users of internal tools ask how many rows, not how much vibe.<\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">The part that is on us<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The advice in consumer articles is all downstream: set a timer, grayscale the screen, leave the phone in another room. None of it is bad. All of it asks the user to individually out discipline a system built by teams of people who were paid to remove their stopping points.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We are on the other side of that. A count in an announcement, a button after three loads, a footer that stays where you put it. These are half a day of work and they hand people back the thing the pattern quietly took, which is the ability to notice they are finished.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The accessibility case and the ethical case turn out to be the same case. That happens more often than you would expect.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Context and reporting on the consumer side of this pattern: <a href=\"https:\/\/www.eltiempo.com\/tecnosfera\/dejar-el-scroll-infinito-y-volver-a-ser-dueno-de-su-tiempo-3573694\" rel=\"nofollow noopener\" target=\"_blank\">El Tiempo, Dejar el scroll infinito y volver a ser due\u00f1o de su tiempo<\/a> (Spanish).<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>I build and audit frontends for accessibility compliance, including WCAG 2.2 AA and ADA readiness for the US market.<\/strong> If your team is shipping a catalog, feed, or search experience and nobody has run it through a keyboard yet, write to me at <a href=\"mailto:serbeldiaz@gmail.com\">serbeldiaz@gmail.com<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Infinite scroll is usually discussed as an attention problem. From the implementation side it is also one of the fastest ways to ship an inaccessible page. Four failures it causes, and the patterns that fix them.<\/p>\n","protected":false},"author":1,"featured_media":201,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"saved_in_kubio":false,"footnotes":""},"categories":[21],"tags":[],"class_list":["post-197","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-frontend"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>The Accessibility Cost of Infinite Scroll (and What to Ship Instead) - My Blog | Serbeld Digital Creations<\/title>\n<meta name=\"description\" content=\"Infinite scroll breaks keyboard access to your footer, hides new content from screen readers, and destroys back navigation. Accessible Load more and IntersectionObserver patterns, with React code.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.serbeld.space\/en\/2026\/08\/09\/accessibility-cost-of-infinite-scroll\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"The Accessibility Cost of Infinite Scroll (and What to Ship Instead) - My Blog | Serbeld Digital Creations\" \/>\n<meta property=\"og:description\" content=\"Infinite scroll breaks keyboard access to your footer, hides new content from screen readers, and destroys back navigation. Accessible Load more and IntersectionObserver patterns, with React code.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.serbeld.space\/en\/2026\/08\/09\/accessibility-cost-of-infinite-scroll\/\" \/>\n<meta property=\"og:site_name\" content=\"My Blog | Serbeld Digital Creations\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-09T04:09:56+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.serbeld.space\/en\/wp-content\/uploads\/2026\/08\/Infinite-scroll-on-a-smartphone-feed.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1080\" \/>\n\t<meta property=\"og:image:height\" content=\"720\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Sergio Bele\u00f1o\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Sergio Bele\u00f1o\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/2026\\\/08\\\/09\\\/accessibility-cost-of-infinite-scroll\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/2026\\\/08\\\/09\\\/accessibility-cost-of-infinite-scroll\\\/\"},\"author\":{\"name\":\"Sergio Bele\u00f1o\",\"@id\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/#\\\/schema\\\/person\\\/48af20418730d7abd4745862cb50bd91\"},\"headline\":\"The Accessibility Cost of Infinite Scroll (and What to Ship Instead)\",\"datePublished\":\"2026-08-09T04:09:56+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/2026\\\/08\\\/09\\\/accessibility-cost-of-infinite-scroll\\\/\"},\"wordCount\":1212,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/2026\\\/08\\\/09\\\/accessibility-cost-of-infinite-scroll\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/Infinite-scroll-on-a-smartphone-feed.jpg\",\"articleSection\":[\"Frontend\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.serbeld.space\\\/en\\\/2026\\\/08\\\/09\\\/accessibility-cost-of-infinite-scroll\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/2026\\\/08\\\/09\\\/accessibility-cost-of-infinite-scroll\\\/\",\"url\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/2026\\\/08\\\/09\\\/accessibility-cost-of-infinite-scroll\\\/\",\"name\":\"The Accessibility Cost of Infinite Scroll (and What to Ship Instead) - My Blog | Serbeld Digital Creations\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/2026\\\/08\\\/09\\\/accessibility-cost-of-infinite-scroll\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/2026\\\/08\\\/09\\\/accessibility-cost-of-infinite-scroll\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/Infinite-scroll-on-a-smartphone-feed.jpg\",\"datePublished\":\"2026-08-09T04:09:56+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/#\\\/schema\\\/person\\\/48af20418730d7abd4745862cb50bd91\"},\"description\":\"Infinite scroll breaks keyboard access to your footer, hides new content from screen readers, and destroys back navigation. Accessible Load more and IntersectionObserver patterns, with React code.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/2026\\\/08\\\/09\\\/accessibility-cost-of-infinite-scroll\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.serbeld.space\\\/en\\\/2026\\\/08\\\/09\\\/accessibility-cost-of-infinite-scroll\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/2026\\\/08\\\/09\\\/accessibility-cost-of-infinite-scroll\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/Infinite-scroll-on-a-smartphone-feed.jpg\",\"contentUrl\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/Infinite-scroll-on-a-smartphone-feed.jpg\",\"width\":1080,\"height\":720,\"caption\":\"A person scrolling a smartphone feed with one hand, screen lit against a dark background\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/2026\\\/08\\\/09\\\/accessibility-cost-of-infinite-scroll\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"The Accessibility Cost of Infinite Scroll (and What to Ship Instead)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/#website\",\"url\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/\",\"name\":\"My Blog | Serbeld Digital Creations\",\"description\":\"Explore a world of innovation and creativity with Serbeld Digital Creations. Discover cutting-edge technology projects and digital marvels crafted by Serbeld. Join us on a journey through the digital realm where ideas come to life.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/#\\\/schema\\\/person\\\/48af20418730d7abd4745862cb50bd91\",\"name\":\"Sergio Bele\u00f1o\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a10c42d0d6b00687137658785dd7dea4acf2aeaad435abb9bf0f05c5740a1681?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a10c42d0d6b00687137658785dd7dea4acf2aeaad435abb9bf0f05c5740a1681?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a10c42d0d6b00687137658785dd7dea4acf2aeaad435abb9bf0f05c5740a1681?s=96&d=mm&r=g\",\"caption\":\"Sergio Bele\u00f1o\"},\"sameAs\":[\"https:\\\/\\\/www.serbeld.space\\\/en\"],\"url\":\"https:\\\/\\\/www.serbeld.space\\\/en\\\/author\\\/admin\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"The Accessibility Cost of Infinite Scroll (and What to Ship Instead) - My Blog | Serbeld Digital Creations","description":"Infinite scroll breaks keyboard access to your footer, hides new content from screen readers, and destroys back navigation. Accessible Load more and IntersectionObserver patterns, with React code.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.serbeld.space\/en\/2026\/08\/09\/accessibility-cost-of-infinite-scroll\/","og_locale":"en_US","og_type":"article","og_title":"The Accessibility Cost of Infinite Scroll (and What to Ship Instead) - My Blog | Serbeld Digital Creations","og_description":"Infinite scroll breaks keyboard access to your footer, hides new content from screen readers, and destroys back navigation. Accessible Load more and IntersectionObserver patterns, with React code.","og_url":"https:\/\/www.serbeld.space\/en\/2026\/08\/09\/accessibility-cost-of-infinite-scroll\/","og_site_name":"My Blog | Serbeld Digital Creations","article_published_time":"2026-08-09T04:09:56+00:00","og_image":[{"width":1080,"height":720,"url":"https:\/\/www.serbeld.space\/en\/wp-content\/uploads\/2026\/08\/Infinite-scroll-on-a-smartphone-feed.jpg","type":"image\/jpeg"}],"author":"Sergio Bele\u00f1o","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Sergio Bele\u00f1o","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.serbeld.space\/en\/2026\/08\/09\/accessibility-cost-of-infinite-scroll\/#article","isPartOf":{"@id":"https:\/\/www.serbeld.space\/en\/2026\/08\/09\/accessibility-cost-of-infinite-scroll\/"},"author":{"name":"Sergio Bele\u00f1o","@id":"https:\/\/www.serbeld.space\/en\/#\/schema\/person\/48af20418730d7abd4745862cb50bd91"},"headline":"The Accessibility Cost of Infinite Scroll (and What to Ship Instead)","datePublished":"2026-08-09T04:09:56+00:00","mainEntityOfPage":{"@id":"https:\/\/www.serbeld.space\/en\/2026\/08\/09\/accessibility-cost-of-infinite-scroll\/"},"wordCount":1212,"commentCount":0,"image":{"@id":"https:\/\/www.serbeld.space\/en\/2026\/08\/09\/accessibility-cost-of-infinite-scroll\/#primaryimage"},"thumbnailUrl":"https:\/\/www.serbeld.space\/en\/wp-content\/uploads\/2026\/08\/Infinite-scroll-on-a-smartphone-feed.jpg","articleSection":["Frontend"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.serbeld.space\/en\/2026\/08\/09\/accessibility-cost-of-infinite-scroll\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.serbeld.space\/en\/2026\/08\/09\/accessibility-cost-of-infinite-scroll\/","url":"https:\/\/www.serbeld.space\/en\/2026\/08\/09\/accessibility-cost-of-infinite-scroll\/","name":"The Accessibility Cost of Infinite Scroll (and What to Ship Instead) - My Blog | Serbeld Digital Creations","isPartOf":{"@id":"https:\/\/www.serbeld.space\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.serbeld.space\/en\/2026\/08\/09\/accessibility-cost-of-infinite-scroll\/#primaryimage"},"image":{"@id":"https:\/\/www.serbeld.space\/en\/2026\/08\/09\/accessibility-cost-of-infinite-scroll\/#primaryimage"},"thumbnailUrl":"https:\/\/www.serbeld.space\/en\/wp-content\/uploads\/2026\/08\/Infinite-scroll-on-a-smartphone-feed.jpg","datePublished":"2026-08-09T04:09:56+00:00","author":{"@id":"https:\/\/www.serbeld.space\/en\/#\/schema\/person\/48af20418730d7abd4745862cb50bd91"},"description":"Infinite scroll breaks keyboard access to your footer, hides new content from screen readers, and destroys back navigation. Accessible Load more and IntersectionObserver patterns, with React code.","breadcrumb":{"@id":"https:\/\/www.serbeld.space\/en\/2026\/08\/09\/accessibility-cost-of-infinite-scroll\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.serbeld.space\/en\/2026\/08\/09\/accessibility-cost-of-infinite-scroll\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.serbeld.space\/en\/2026\/08\/09\/accessibility-cost-of-infinite-scroll\/#primaryimage","url":"https:\/\/www.serbeld.space\/en\/wp-content\/uploads\/2026\/08\/Infinite-scroll-on-a-smartphone-feed.jpg","contentUrl":"https:\/\/www.serbeld.space\/en\/wp-content\/uploads\/2026\/08\/Infinite-scroll-on-a-smartphone-feed.jpg","width":1080,"height":720,"caption":"A person scrolling a smartphone feed with one hand, screen lit against a dark background"},{"@type":"BreadcrumbList","@id":"https:\/\/www.serbeld.space\/en\/2026\/08\/09\/accessibility-cost-of-infinite-scroll\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.serbeld.space\/en\/"},{"@type":"ListItem","position":2,"name":"The Accessibility Cost of Infinite Scroll (and What to Ship Instead)"}]},{"@type":"WebSite","@id":"https:\/\/www.serbeld.space\/en\/#website","url":"https:\/\/www.serbeld.space\/en\/","name":"My Blog | Serbeld Digital Creations","description":"Explore a world of innovation and creativity with Serbeld Digital Creations. Discover cutting-edge technology projects and digital marvels crafted by Serbeld. Join us on a journey through the digital realm where ideas come to life.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.serbeld.space\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.serbeld.space\/en\/#\/schema\/person\/48af20418730d7abd4745862cb50bd91","name":"Sergio Bele\u00f1o","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/a10c42d0d6b00687137658785dd7dea4acf2aeaad435abb9bf0f05c5740a1681?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/a10c42d0d6b00687137658785dd7dea4acf2aeaad435abb9bf0f05c5740a1681?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a10c42d0d6b00687137658785dd7dea4acf2aeaad435abb9bf0f05c5740a1681?s=96&d=mm&r=g","caption":"Sergio Bele\u00f1o"},"sameAs":["https:\/\/www.serbeld.space\/en"],"url":"https:\/\/www.serbeld.space\/en\/author\/admin\/"}]}},"_links":{"self":[{"href":"https:\/\/www.serbeld.space\/en\/wp-json\/wp\/v2\/posts\/197","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.serbeld.space\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.serbeld.space\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.serbeld.space\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.serbeld.space\/en\/wp-json\/wp\/v2\/comments?post=197"}],"version-history":[{"count":3,"href":"https:\/\/www.serbeld.space\/en\/wp-json\/wp\/v2\/posts\/197\/revisions"}],"predecessor-version":[{"id":200,"href":"https:\/\/www.serbeld.space\/en\/wp-json\/wp\/v2\/posts\/197\/revisions\/200"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.serbeld.space\/en\/wp-json\/wp\/v2\/media\/201"}],"wp:attachment":[{"href":"https:\/\/www.serbeld.space\/en\/wp-json\/wp\/v2\/media?parent=197"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.serbeld.space\/en\/wp-json\/wp\/v2\/categories?post=197"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.serbeld.space\/en\/wp-json\/wp\/v2\/tags?post=197"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}