Alpine.js x-transition not working in LiveView for <template> tag

I have this code inside liveview in Phoenix 1.6:

      <div x-data="{ open: false }" x-on:click.outside="open = false" x-on:keydown.escape="open = false">
        <button x-on:click="open = !open">
          Click me
        </button>
        <div x-show="open" x-transition.opacity>
          <div>
            <ul>
              <li>Dogs</li>
              <li>Cats</li>
              <li>Snakes</li>
            </ul>
          </div>
        </div>
      </div>

And the transition fade in/out animation works.

But when I do this:

      <div x-data="{ open: false }" x-on:click.outside="open = false" x-on:keydown.escape="open = false">
        <button x-on:click="open = !open">
          Click me
        </button>
        <template x-show="open" x-transition.opacity>
          <div>
            <ul>
              <li>Dogs</li>
              <li>Cats</li>
              <li>Snakes</li>
            </ul>
          </div>
        </template>
      </div>

It doesn’t. In fact nothing shows up at all and I have to change x-show to x-if to at least be able to make the show hide work albeit without any fade in/out effect at all:

      <div x-data="{ open: false }" x-on:click.outside="open = false" x-on:keydown.escape="open = false">
        <button x-on:click="open = !open">
          Click me
        </button>
        <template x-if="open" x-transition.opacity>
          <div>
            <ul>
              <li>Dogs</li>
              <li>Cats</li>
              <li>Snakes</li>
            </ul>
          </div>
        </template>
      </div>

How can I make this transition to work on the <template> element?

I’d expect this to be unrelated to liveview. <template> is not a visible element in html and therefore is unlikely to support animations. See also: <template>: The Content Template element - HTML: HyperText Markup Language | MDN

So, do you think it is possible then to somehow trigger the animation on the <div> child element in <template>?
Any idea how to do that with Alpine.js?

did you try just putting it on the <div>?

yes, I have tried:

<template x-if="open">
          <div x-transition.opacity>
            <ul>
              <li>Dogs</li>
              <li>Cats</li>
              <li>Snakes</li>
            </ul>
          </div>
</template>

also

<template x-if="open">
          <div x-show="open" x-transition.opacity>
            <ul>
              <li>Dogs</li>
              <li>Cats</li>
              <li>Snakes</li>
            </ul>
          </div>
</template>

also

<template x-if="open">
          <div x-cloak x-transition.opacity>
            <ul>
              <li>Dogs</li>
              <li>Cats</li>
              <li>Snakes</li>
            </ul>
          </div>
</template>

but nothing works.

can you try this (which works for me)

<html>
  <head>
    <script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
  </head>
  <body>
    <div x-data="{ open: false, colors: ['Red', 'Orange', 'Yellow']  }">
      <button @click="open = ! open">Toggle</button>
      <template x-for="color in colors">
        <div>
          <span x-text="color" x-show="open" x-transition.duration.1000ms>
          </span>
        </div>
      </template>
    </div>
  </body>
</html>

Yes, your example works. But how could I implement it on mine to work? Could x-for make the difference?
Any idea how to make mine code work like yours? I have tried this:

      <div x-data="{ open: false }" x-on:click.outside="open = false" x-on:keydown.escape="open = false">
        <button x-on:click="open = !open">
          Click me
        </button>
        <template>
          <div>
            <ul x-show="open" x-transition.duration.1000ms>
              <li>Dogs</li>
              <li>Cats</li>
              <li>Snakes</li>
            </ul>
          </div>
        </template>
      </div>

follwing your example, but it is not working at all.

Thats odd, with this code I got the transitions I’d expect inside x-for an outgoing transition for test1 (inside template) and an ingoing transition for test2.

EDIT: wrong: still no animation inside template with x-if.

<html>
  <head>
    <script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
  </head>
  <body>
    <div x-data="{ open: false, colors: ['Red', 'Orange', 'Yellow']  }">
      <button @click="open = ! open">Toggle</button>
      <template x-for="color in colors">
        <div>
          <span x-text="color" x-show="open" x-transition.duration.1000ms>
          </span>
        </div>
      </template>
      <template x-if="open">
        <div x-transition.duration.1000ms>
          test1
        </div>
      </template>
      <div x-show="open" x-transition.duration.1000ms>
        test2
      </div>
    </div>
  </body>
</html>

you know, that you can just do

<div x-show="open" x-transition.opacity.duration.3000ms>
<ul>
    <li>Dogs</li>
    <li>Cats</li>
    <li>Snakes</li>
</ul>
</div>

I need templates though.

maybe you get help here: javascript - The <template> tag doesn't work with x-transition in Alpine.js - Stack Overflow

Any idea why x-for works for <template> tag?

I’ve had to wrap my template tags in raw tags to get them working.

Can you link to the <raw> tag on some website. I have never heard of those. Google is not showing anything relevant.

https://hexdocs.pm/phoenix_html/Phoenix.HTML.html#raw/1

https://surface-ui.org/builtincomponents/Raw

1 Like