DEV Community

Hussein Al Hammad
Hussein Al Hammad

Posted on

Alpine.js: responsive x-cloak

When using Alpine.js the x-cloak attribute is removed from DOM elements when Alpine is initialised. As noted in the docs, this makes it useful for hiding elements until Alpine is initialised:

x-cloak attributes are removed from elements when Alpine initializes. This is useful for hiding pre-initialized DOM. It's typical to add the following global style for this to work:

<style>
  [x-cloak] { display: none; }
</style>

You may want to hide pre-initialised DOM on some screen sizes, but not others. A good example for this is the links in a site's navigation bar, which are typically hidden by default on smaller screen sizes, but are always visible on wider screens.

So instead of hiding all elements with the x-cloak attribute, we can hide only the ones whose x-cloak attribute has no value:

[x-cloak=""] { display: none; }
Enter fullscreen mode Exit fullscreen mode

This allows us to target elements whose x-cloak attribute has a value:

[x-cloak="some-value"] { }
Enter fullscreen mode Exit fullscreen mode

So now we can write CSS rules targeting elements whose x-cloak value is mobile, tablet, desktop:

/* always hidden */
[x-cloak=""] { display: none; }

/* hidden on mobile/smaller screens */
@media screen and (max-width: 768px) {
    [x-cloak="mobile"] { display: none; }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (5)

Collapse
 
makingthings profile image
James Grubb

Hi Hussein. Thanks for this. Could you show how I should set up my HTML using x-cloak? Thanks in advance

Collapse
 
hus_hmd profile image
Hussein Al Hammad

Hi James, you would add x-cloak as an attribute to a HTML element:

<div x-cloak>
    <!-- this element is hidden until Alpine is initialised -->
</div>
Enter fullscreen mode Exit fullscreen mode

If you're following the example in the blog post:

<div x-cloak="mobile"></div>
Enter fullscreen mode Exit fullscreen mode

Here's Alpine.js's documentation, which is really good:
github.com/alpinejs/alpine#x-cloak

Collapse
 
makingthings profile image
James Grubb

Hi Hussein, thanks so much for getting back to me. I'm being a little slow on the uptake here and really would like to understand the benefits. Please bear with me. Would you mind elaborating a little more on using x-cloak within a media query? I guess in your initial post both your queries returned display: none and I was a little confused as to how to use this

//css
.hidden{
  display: none;
}
[x-cloak=""]{
  display: none;
}
[x-cloak="tablet"]{
  color: red;
}

//html

<div class="wrapper" x-data="{'isOpen' : true}">
  <h1 x-cloak :class="{'hidden': isOpen}">Hello</h1>
  <h2 x-cloak="tablet">World</h2>
</div>


Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
hus_hmd profile image
Hussein Al Hammad

Sure thing. Perhaps the post was light on the possible use-cases for this.

Firstly to recap, x-cloak is an attribute that Alpine.js removes from HTML elements once it is initialised. So you have the following phases:

  1. HTML is rendered in the browser, Alpine.js is yet to initialise. HTML elements still have the x-cloak attribute.
  2. Alpine.js is initialised. Alpine.js removes the x-cloak attribute from HTML elements.

So during (1), [x-cloak=""] styles are applied. During (2), they are no longer applied to the elements because the elements no longer have the x-cloak attribute.

A user with a slow internet connection for instance may view a page in phase (1) for some time. During this time you may not want to hide some elements by default.

Taking the dropdown example from Alpine's docs:

<div x-data="{ open: false }">
    <button @click="open = true">Open Dropdown</button>

    <ul
        x-show="open"
        @click.away="open = false"
    >
        Dropdown Body
        <!-- this ul is visible during phase (1) -->
    </ul>
</div>
Enter fullscreen mode Exit fullscreen mode

If we apply x-cloak to the <ul>, we can hide it during phase (1):

<div x-data="{ open: false }">
    <button @click="open = true">Open Dropdown</button>

    <ul
        x-cloak
        x-show="open"
        @click.away="open = false"
    >
        Dropdown Body
        <!-- this ul is NOT visible during phase (1) -->
    </ul>
</div>
Enter fullscreen mode Exit fullscreen mode

In the example of a dropdown, such a component typically behaves in an identical way across different screen sizes.

However, for some components you may want to have some elements hidden during phase (1) only on some screen sizes. A common example is the main navigation bar of a website where you have the links displayed by default on larger screens, but want to have them hidden on smaller screens. In other words, the initial state for the element is not identical across screen sizes. This is where [x-cloak="mobile"] can be useful.

Note that this is useful if you are toggling display with Alpine (e.g. with x-show):

<div x-show="open" x-cloak="mobile"></div>
Enter fullscreen mode Exit fullscreen mode

If you are using Alpine to toggle CSS classes you may not need this as your CSS may already handle this:

<style>
    @media screen and (max-width: 768px) {
        .example:not(.active) {
            display: none;
        }
    }
</style>

<div class="example" :class="{'active': open}"></div>
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
makingthings profile image
James Grubb

Hi Hussein, I realised I did not get to thank you for your follow up post. I really appreciate your time and I am very grateful. Cheers, James.