How to avoid (CLS) Layout Shift when using JS Components
Tags: cls, javascript, pagespeed, cumulativelayoutsift
Published: 2022-10-10 17:31:58

When using components that are based on Javascript, you might notice a layout shift on your content (CLS), specially if you delay the start of Javascript in some way. On that situation, you’ll see the initial look of the elements until Javascript kicks in.

But of course, delaying javascript until user interaction or after some seconds it’s a good practice and a good trick to increase the score of a website on [pagespeed insights](https://pagespeed.web.dev/). So the better option is to find ways to avoid layout shift, fortunately is not that complicated.

For this tutorial I’ll be focusing on [Mr.Utils](https://marcosrego.com/development/mr-utils/) JS components, but the same logic applies to other tools.

**Understand how general JS Components work**
---------------------------------------------

The way Mr.Utils javascript components work is by adding the necessary CSS inline properties to the element after page load, but only if the element doesn’t have a utility class that already uses some of those properties.

And as you might know, HTML classes don’t rely on Javascript to apply the style of CSS properties. We’ll use that fact to our benefit, to avoid the layout shift when delaying Javascript on this situation.

**Fixing the Content Layout Shift**
-----------------------------------

### **Fix CLS for components that add properties**

Components such as **Mr.Utils Swipe component** add the following inline properties to the element:

    display: -webkit-inline-box;
    flex-wrap: unset !important;
    overflow-x: scroll !important;
    -webkit-overflow-scrolling: touch !important;
    overflow-y: hidden;

But there’s one utility class that does the exact same thing, so all you need to do is to add the following utility class after adding the swipe class:

    mr-horizontalscroll

If you are using Mr.Utils as a plugin: Instead of adding the class you can select the option at Misc > Scroll > Horizontal Scroll.

In the end, you’ll have the following classes on your element:

    mr-swipe mr-horizontalscroll

By doing this, the properties will be added before javascript runs and you’ll be avoiding the layout shift, without losing the benefits of the swipe component (such as the ability to drag with a mouse).

### **Fix CLS for components that create new elements**

Components such as **Tabs** and navigation options on **Pagination (Radio, Arrows, Dropdown)** add new elements to the page if those elements do not exist yet. So, the way to avoid layout shifting when Javascript starts on this situation, is to create the elements manually, let’s take a look at that:

If you want to use the exact same elements that Mr.Utils’ Javascript would create, you can use the below HTML Codes after the element _(or before when using [the proper class](https://github.com/marcosrego-web/mr-utils/wiki/Utility-Classes#components))_.

**Pagination Arrows**

    <div class="mr-pagination">
    <button class="mr-arrows mr-prev">⇦</button>
    <button class="mr-arrows mr-next">⇨</button>
    </div>

**Pagination Radio Buttons**

_Duplicate the last “mr-radio” to match the number of pages_.

    <div class="mr-pagination">
    <span class="mr-radios">
    <input name="mr-radio" title="1/2" class="mr-radio" type="radio" value="1" checked="checked">
    <input name="mr-radio" title="2/2" class="mr-radio" type="radio" value="2">
    </span>
    </div>

**Pagination Dropdown**

_Duplicate the last “option” to match the number of pages_.

    <div class="mr-pagination">
    <select class="mr-pageselect" title="/2">
    <option value="1">1</option>
    <option value="2">2</option>
    </select>
    </div>

**Tabs**

_Duplicate the last “mr-tab” to match the number of pages_.

    <div class="mr-tabsnav mr-horizontalscroll">
    <button class="mr-tab mr-active">Tab 01</button>
    <button class="mr-tab">Tab 02</button>
    </div>

If you want a bit more control or if you use site-builders, you can also create those new elements in a different way, as long as the main/parent element uses the class _mr-pagination_ or _mr-tabsnav_.

If you are using Mr.Utils as a plugin on WordPress, you can use the block editor to create buttons for the Tabs component. Then, by selecting the buttons container, on Utilities choose Components > Tabs Navigation.

**Live example of fixing Tabs CLS**
-----------------------------------

A good example of this live is on [Itemzero’s Shop](https://shop.itemzero.com/), the tabs were created using the block editor and Mr.Utils.

![Itemzero's shop uses tabs](https://marcosrego.com/wp-content/uploads/2021/04/itemzero-mrdev_widget-tabs-1024x572.jpg "itemzero mrdev widget tabs - How to avoid (CLS) Layout Shift when using JS Components")

Itemzero’s shop uses tabs from Mr.Utils components.

And that’s it! Those are some ways to avoid layout shift when using JS Components.