#not work with transition on layout

4 messages · Page 1 of 1 (latest)

misty wingBOT
#

Hi @rough hare. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

I notice you're having issues with transitions in your Astro component. The problem appears to be related to how you're implementing the toggle functionality for your service cards.

When using Astro's view transitions, you need to use the <ClientRouter /> component and the appropriate transition directives to enable smooth transitions between elements. Your current implementation is using direct DOM manipulation with style.display, which won't work with Astro's view transitions system.

Here's how you can modify your component to work with Astro's view transitions:

  1. First, make sure you have the <ClientRouter /> component in your layout or head component:
---
import { ClientRouter } from 'astro:transitions';
---
<head>
  <!-- other head elements -->
  <ClientRouter />
</head>
  1. Then, modify your service component to use transition directives instead of directly manipulating the DOM:
---
const { data } = Astro.props;
---

<article class="service">
    <div class="service__header" transition:name={`service-header-${data.title}`}>
        {data.title}
    </div>
    <div class="service__body" transition:name={`service-body-${data.title}`}>
        <button class="service__cta">
            <svg class="icon" width="48" height="48">
                <use xlink:href="#arr-t-r"></use>
            </svg>
        </button>
       
        <div class="service__icon">
            <img src={data.icon} alt={data.title} width="40" height="40" />
        </div>
        <div class="service__title">
            {data.title}
        </div>
        <div class="service__desc">
            {data.desc}
        </div>
    </div>
</article>
#

<script>
document.addEventListener('astro:page-load', () => {
document.querySelectorAll('.service').forEach((service, index) => {
const header = service.querySelector('.service__header');
const body = service.querySelector('.service__body');

        // Set initial state using classes instead of inline styles
        if (index === 0) {
            header.classList.add('hidden');
            body.classList.remove('hidden');
        } else {
            header.classList.remove('hidden');
            body.classList.add('hidden');
        }

        // Toggle visibility on header click
        header.addEventListener('click', () => {
            header.classList.add('hidden');
            body.classList.remove('hidden');
        });

        // Toggle visibility on body click
        body.addEventListener('click', () => {
            header.classList.remove('hidden');
            body.classList.add('hidden');
        });
    });
});

</script>

<style>
.hidden {
display: none;
}
</style>


The key changes are:

1. Added `transition:name` directives to create named transitions for each element
2. Changed from inline style manipulation to class toggling
3. Made sure the script runs after page load with the `astro:page-load` event

For more complex animations, you can also use the `transition:animate` directive with built-in animations like "fade" or "slide" as described in the [View Transitions guide](<https://docs.astro.build/en/guides/view-transitions/#built-in-animation-directives>).
#

Remember that the script needs to run after each page navigation when using view transitions, which is why we're using the astro:page-load event listener instead of the standard DOMContentLoaded event. This ensures your toggle functionality works properly with Astro's client-side navigation system.

If you need more control over the animation timing or behavior, you can also create custom animations as described in the Astro documentation.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: