CSS transitions with LiveView and phx-update=prepend

Hi,

It seems that phx-update=“prepend” makes all currently existing DOM nodes re-enter the DOM. I would like to know how to avoid this behaviour with prepend (there is no problem with append) in order to add CSS transitions on those nodes when they enter the DOM.

I don’t know if it a known problem, but it seems due to how the JS code handles “prepend”.

I make a small demo of the problem:

git clone https://github.com/lud/liveview-transition-demo.git
cd liveview-transition-demo
make
mix phx.server

Is there a way to prevent that ?

Thank you

2 Likes

(just bumping up the topic)

I have a similar issue when using css transition on list items using phx-update="prepend".
For example I render 4 items in the list, where the item’s toggle button highlights the item by toggling a class.

  • When I toggle the first 2 items the transition is working properly (animates to red background). While the element is selected in the inspector, it updates the class on the selected element like expected.
  • When I toggle the last 2 items the transition is not working (instantly changes background without animation). While the element is selected in the inspector, it replaces the whole element instead of updating it.

Is there a logical explanation to this behaviour?

(tested this in MacOS Chrome and Safari)

<ul phx-update="prepend" id="items">
  <%= for item <- @items do %>
    <li id="item-<%= item.id %>"
        class="item <%= if item.highlight do "highlight" end %>">
      <button phx-click="toggle-highlight" phx-value-id="<%= item.id %>">
        toggle
      </button>
    <li>
  <% end %>
</ul>
.item {
  transition: background 0.5s;
}
.highlight {
  background: red;
}

FYI my live event updating the list looks like this:

def handle_event("toggle-highlight", %{"id" => item_id}, socket) do
  item = Repo.get(Item, item_id)
  
  {:ok, updated_item} = item
    |> Item.changeset(%{highlight: !item.highlight})
    |> Repo.update()

  socket = update(socket, :items, fn items -> [updated_item | items] end)

  {:noreply, socket}
end
1 Like

After some more digging I found that in my case the issue doesn’t seem to be related to the phx-update setting, but only occurs when using temporary_assigns. Updating items in the list without using temporary_assigns the transitions work for all items.

I’m still puzzled why, might be a bug?

Tested with phoenix_live_view ~> 0.17.5 in Chrome, Firefox and Safari.

Created an issue: