<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged css-architecture</title>
<link>https://coderlegion.com/tag/css-architecture</link>
<description>Powered by Question2Answer</description>
<item>
<title>Build a Lightweight CSS Marquee Without Damaging Web Vitals</title>
<link>https://coderlegion.com/29589/build-a-lightweight-css-marquee-without-damaging-web-vitals</link>
<description>&lt;p&gt;Infinite tickers and scrolling marquees are a frequent requirement for showcasing partner logos, engineering badges, or featured announcements on modern marketing sites. Yet, many implementations rely on third-party JavaScript libraries or heavy animation wrappers that degrade performance. When a marquee is driven by JavaScript style updates on every frame, it blocks the main thread, inflates Total Blocking Time, and triggers costly layout recalculations. Developers need a way to create continuous visual movement that remains buttery smooth without sacrificing user experience or performance scores. For a related implementation, see &lt;a rel=&quot;nofollow&quot; href=&quot;https://raylabs.app/articles/android-app-updates-play-vs-managed-devices/&quot;&gt;App Updates Play Vs Managed Devices&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;the-performance-cost-of-javascript-marquees&quot;&gt;The Performance Cost of JavaScript Marquees&lt;/h3&gt;
&lt;p&gt;Traditional ticker scripts rely on &lt;code&gt;requestAnimationFrame&lt;/code&gt; loops or timer intervals to mutate element positions on every tick. This approach forces the browser to recalculate styles and geometry during the layout phase for every active frame. On mobile devices or lower-powered hardware, this constant recalculation drops frame rates below sixty frames per second and elevates Total Blocking Time. Furthermore, dynamic DOM node insertion during script initialization can trigger sudden content jumps, ruining Cumulative Layout Shift metrics before the page fully settles. For a related implementation, see &lt;a rel=&quot;nofollow&quot; href=&quot;https://raylabs.app/articles/android-memory-optimization-low-ram-devices/&quot;&gt;Memory Optimization Low Ram Devices&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;the-double-track-duplication-pattern&quot;&gt;The Double-Track Duplication Pattern&lt;/h3&gt;
&lt;p&gt;To achieve a seamless infinite loop without JavaScript calculations, you can structure the HTML with a parent container and two identical track children. Each track contains the exact same sequence of items. When the container width is set to fit the content of a single track, duplicating that track ensures that as the first set of items scrolls completely out of view, the second set seamlessly takes its place.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;div class=&quot;marquee-container&quot;&amp;gt;
  &amp;lt;div class=&quot;marquee-track&quot;&amp;gt;
    &amp;lt;div class=&quot;marquee-group&quot;&amp;gt;
      &amp;lt;span&amp;gt;Acme Corp&amp;lt;/span&amp;gt;
      &amp;lt;span&amp;gt;Beta LLC&amp;lt;/span&amp;gt;
      &amp;lt;span&amp;gt;Gamma Inc&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&quot;marquee-group&quot; aria-hidden=&quot;true&quot;&amp;gt;
      &amp;lt;span&amp;gt;Acme Corp&amp;lt;/span&amp;gt;
      &amp;lt;span&amp;gt;Beta LLC&amp;lt;/span&amp;gt;
      &amp;lt;span&amp;gt;Gamma Inc&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Setting the second group with &lt;code&gt;aria-hidden=&quot;true&quot;&lt;/code&gt; ensures that screen readers do not read the duplicated items twice, preserving a clean accessibility tree.&lt;/p&gt;
&lt;h3 id=&quot;gpu-compositing-with-3d-transforms&quot;&gt;GPU Compositing with 3D Transforms&lt;/h3&gt;
&lt;p&gt;Performance relies entirely on choosing the right CSS properties to animate. Animating layout properties like &lt;code&gt;margin-left&lt;/code&gt; or &lt;code&gt;left&lt;/code&gt; forces the browser to repeat layout and paint steps continuously. By contrast, using hardware-accelerated transforms shifts the workload entirely to the GPU compositor thread.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;.marquee-container {
  overflow: hidden;
  width: 100%;
  display: flex;
}

.marquee-track {
  display: flex;
  width: max-content;
  animation: scroll-marquee 30s linear infinite;
}

.marquee-group {
  display: flex;
  gap: 2rem;
  justify-content: space-around;
  min-width: 100%;
}

@keyframes scroll-marquee {
  0% {
    transform: translate3d(0, 0, 0);
  }
  100% {
    transform: translate3d(-50%, 0, 0);
  }
}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because the track contains two identical groups side by side, translating the entire track by negative fifty percent moves exactly one full group width before looping back to zero instantly and invisibly.&lt;/p&gt;
&lt;h3 id=&quot;zero-cls-containment&quot;&gt;Zero CLS Containment&lt;/h3&gt;
&lt;p&gt;Layout shifts often occur when dynamic components load fonts or images after initial render. To prevent the marquee container from causing layout instability during hydration, enforce strict CSS containment. By applying explicit height constraints and sizing properties to the container, the browser reserves the exact layout box ahead of time.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;.marquee-container {
  contain: layout size;
  height: 4rem;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This containment rule tells the optimization engine that the internal layout of the marquee does not affect outside document elements, eliminating unexpected reflows during load.&lt;/p&gt;
&lt;h3 id=&quot;polishing-with-css-edge-masks&quot;&gt;Polishing with CSS Edge Masks&lt;/h3&gt;
&lt;p&gt;Fading out the left and right edges of a scrolling marquee provides a polished visual finish without adding extra structural DOM nodes or overlapping gradient overlays. The &lt;code&gt;mask-image&lt;/code&gt; property applies a linear alpha gradient directly to the element rendering surface.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;.marquee-container {
  mask-image: linear-gradient(
    to right,
    transparent,
    black 15%,
    black 85%,
    transparent
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This composited mask ensures that items fade smoothly into view at the container boundaries, adapting cleanly to any background color or theme.&lt;/p&gt;
&lt;h3 id=&quot;accessibility-and-user-control&quot;&gt;Accessibility and User Control&lt;/h3&gt;
&lt;p&gt;Continuous motion can cause discomfort for users with vestibular disorders. Providing clear ways to pause or disable the animation is both an ethical necessity and a requirement for strict accessibility compliance. You can pause movement on hover or keyboard focus, and completely disable it for users who prefer reduced motion.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;.marquee-container:hover .marquee-track,
.marquee-container:focus-within .marquee-track {
  animation-play-state: paused;
}

@media (prefers-reduced-motion: reduce) {
  .marquee-track {
    animation: none;
    transform: none;
    overflow-x: auto;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By adding these rules, users retain full control over their reading experience, and keyboard navigators can interact with the content inside the ticker without struggling against moving targets.&lt;/p&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Implementing an infinite ticker no longer requires heavy JavaScript plugins or complex timer loops. By combining a double-track flexbox structure, GPU-accelerated transforms, CSS edge masks, and strict accessibility safeguards, you can deliver smooth visual motion that protects Core Web Vitals and runs efficiently across all devices.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/29589/build-a-lightweight-css-marquee-without-damaging-web-vitals</guid>
<pubDate>Sat, 03 Oct 2026 05:14:58 +0000</pubDate>
</item>
</channel>
</rss>