Go Back

read

Published on: Jul 24, 2025

UI

Change Language:

Preventing UI Shifting on the Web

One of the things that I hate the most on the web is UI Shifting - that awful movement when the content unexpectedly jumps, often due to images loading late, or dynamic content injected into the layout. It disrupts flow, affects perceived performance, and can even cause users to click the wrong thing.

While this happens mostly to web apps written on complex Javascript UI frameworks, this can also happen on a simple html & css only website (if those even exists at this point).

In this post, we’ll explore what causes layout shifts, how to prevent them with vanilla CSS and Tailwind CSS, and tips to improve your interface stability.


What Causes UI Shifting?

Common causes behind layout shifts include:

  • Images without dimensions: Browsers don’t know how much space to reserve before they load.
  • Web fonts: Swapping fonts can cause text size to change.
  • Async content injection: DOM updates or lazy-loaded elements without reserved space.
  • Third-party widgets/ads: External scripts inserting elements late in the render cycle.

How to Prevent UI Shifting (CSS Tips)

1. Reserve Space for Images

Specify “width” and “height” for images so browsers can allocate the correct space.

img {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9; /* fallback if no explicit height */
}

Or use fixed dimensions when appropriate:

<img src="hero.webp" width="1200" height="600" alt="Hero image">

2. Use Aspect Ratio Boxes

When dimensions are dynamic, use aspect ratio containers:

    .aspect-box {
        aspect-ratio: 16 / 9;
    }

3. Font Loading Optimization

Prevent “flash of unstyled text” (FOUT) or layout shifts by:

  1. Using font-display: swap in your @font-face rule.

  2. Preloading fonts with:

<link rel="preload" href="/fonts/custom.woff2" as="font" type="font/woff2" crossorigin>

Prevent UI Shifting with Tailwind CSS

I love Tailwind , most of the stuff that I make uses Tailwind . Hell, this site is writen with tailwind . Tailwind is life. So let’s see how we can apply all of that stuff with tailwind Tailwind .

1. Use Fixed Sizes or Aspect Ratios

<!-- Fixed image container -->
<div class="w-full h-64 bg-gray-200">
  <img src="/image.jpg" class="w-full h-full object-cover" alt="Example">
</div>

2. Skeleton Loaders or Placeholder Elements

Use placeholders to avoid abrupt content jumps:

<div class="w-full h-32 bg-gray-100 animate-pulse rounded"></div>

In the case of this site, I’m using skeleton, placeholder elements, and as well as fixed size style on the containers of the Imgs:


<!-- This is an Astro file btw-->
<div
    class={`object-contain md:object-cover overflow-hidden  w-auto ${props.footer ? "md:rounded-t-xl" : "md:rounded-xl"}`}>
    <img
        class="aspect-auto md:rounded-t-xl"
            src={props.img_url}
            alt={props.alt}
    />
    <div
        class="absolute flex justify-center items-center w-full h-full top-0 left-0 -z-10 animate-pulse bg-dark/50 rounded-xl"
        >
        <i class="far fa-spinner text-light font-bold text-3xl animate-spin"></i>
     </div>
</div>

This reserves the space for a spinner icon, and indicates loading content.

If you inspect element, you’ll see a spinner behind every post img, do what whatever you want with that forbidden knowledge.

Conclusion

Stable layouts make for smooth, delightful user experiences. Don’t be lazy, prevent UI Shifting!