How to avoid (CLS) Layout Shift when using JS Components

Avoid Cumulative Layout Shift

When using components that are based on JavaScript, you might notice a layout shift on your content (CLS), especially if you delay the start of JavaScript in some way. In 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. So the better option is to find ways to avoid layout shifts, fortunately it is not that complicated.

For this tutorial, I’ll be focusing on 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 in 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).

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 differently, 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 live example of this is on Itemzero’s Shop, the tabs were created using the block editor and Mr.Utils.

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

Comments