Skip to content

update x-cloak CSS to allow conditional disabling#4712

Closed
browner12 wants to merge 1 commit intoalpinejs:mainfrom
browner12:AB-improved-cloaking
Closed

update x-cloak CSS to allow conditional disabling#4712
browner12 wants to merge 1 commit intoalpinejs:mainfrom
browner12:AB-improved-cloaking

Conversation

@browner12
Copy link
Contributor

change the suggested x-cloak CSS to specifically only target the boolean x-cloak attribute or the attribute with an empty string value (x-cloak="").

this means we will no longer target the attribute when it has a non-empty string value (x-cloak="off").

the benefit this gives is we can conditionally disable the cloaking for elements we know will be visible immediately. this prevents a "blip in" from the hidden to visible state.

Here is a Blade example to show how it would work:

<div
    x-show="jsCondition"
    x-cloak="{{ $condition ? 'off' : '' }}"
>Alpine Rocks</div>

this works because, given these elements:

<div x-cloak></div>
<div x-cloak=""></div>
<div x-cloak="off"></div>

we get this behavior:

CSS Selector Matches
[x-cloak] all three
[x-cloak=""] first two only
[x-cloak="off"] third only

This is already possible by conditionally showing the x-cloak, but I think this solution provides a better looking code.

<div
    x-show="jsCondition"
    @if($condition)
        x-cloak
    @endif
>Alpine Rocks</div>

change the suggested `x-cloak` CSS to specifically only target the boolean `x-cloak` attribute or the attribute with an empty string value (`x-cloak=""`).

this means we will no longer target the attribute when it has a non-empty string value (`x-cloak="off"`).

the benefit this gives is we can conditionally disable the cloaking for elements we know will be visible immediately. this prevents a "blip in" from the hidden to visible state.

Here is a Blade example to show how it would work:

```blade
<div
    x-show="jsCondition"
    x-cloak="{{ $condition ? 'off' : '' }}"
>Alpine Rocks</div>
```
@calebporzio
Copy link
Collaborator

PR Review: #4712 — update x-cloak CSS to allow conditional disabling

Type: Docs
Verdict: Close

What's happening (plain English)

  1. Today, Alpine's docs tell you to add [x-cloak] { display: none !important; } to your CSS. This hides any element with x-cloak until Alpine loads and removes the attribute.
  2. This PR changes the recommended CSS to [x-cloak=""] { display: none !important; } — a more specific selector that matches x-cloak (boolean) and x-cloak="" but not x-cloak="off".
  3. The idea: in server-rendered frameworks (like Laravel Blade), you could do x-cloak="{{ $visible ? 'off' : '' }}" to skip cloaking for elements you know will be visible, avoiding a flash.
  4. No Alpine source code is changed — this is entirely a CSS selector convention change in the docs.

Other approaches considered

  1. @if conditional in Blade — Already works today: @if(!$visible) x-cloak @endif. The contributor acknowledges this. It's slightly more verbose but completely explicit and doesn't require changing the global CSS convention.
  2. A dedicated Alpine feature — Alpine could add a modifier like x-cloak.conditional or check the attribute value before removing it. This would be a real feature rather than a CSS trick, but it adds complexity to Alpine's core for a niche use case.
  3. Do nothing — The @if approach already solves this cleanly.

Changes Made

No changes made.

Test Results

Docs-only PR — no tests to run. CI passes.

Code Review

The docs change itself is well-written and the CSS attribute selector trick is technically correct. However:

  • This changes the recommended default CSS for every Alpine user. The current [x-cloak] selector is simple, obvious, and universally understood. The proposed [x-cloak=""] requires understanding CSS attribute selector matching rules (that boolean attributes implicitly have an empty string value). That's a cognitive tax on every new user who reads the docs.
  • The benefit is extremely niche. This only helps server-rendered apps where you want conditional cloaking, and the existing @if approach already handles it cleanly.
  • Zero community engagement — no reactions, no comments, no reviews in ~2 months. This suggests low demand.
  • Alpine doesn't actually do anything with the value. The x-cloak directive (packages/alpinejs/src/directives/x-cloak.js:4) unconditionally removes the attribute regardless of its value. The "feature" lives entirely in the user's CSS, making it fragile — users would need to remember to use the specific CSS selector, and any existing [x-cloak] selectors in their projects would defeat the mechanism.

Security

No security concerns identified.

Verdict

Close. This is a clever CSS trick, but it's not the right trade-off for Alpine's docs. It makes the default recommendation more complex for all users to benefit a niche use case that's already solvable with @if($condition) x-cloak @endif. The "feature" also lives entirely in userland CSS — Alpine itself is unaware of it — which makes it fragile and surprising.

If someone really wants this pattern, they can use [x-cloak=""] in their own project's CSS. It doesn't need to be the official recommendation.


Reviewed by Claude

@calebporzio calebporzio closed this Feb 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants