You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Alpine.js+Bulma开发菜单时,无法实现关闭反向动画

Alpine.js + Bulma 侧边导航关闭动画修复方案

论坛里很多人可能会吐槽我用Alpine.js时不用Tailwind CSS自找麻烦,但这次实践就是要证明Alpine.js能适配任意CSS框架,不局限于某一个。我选了Bulma框架,因为它比Bootstrap或Tailwind更易用。我做了个个性化导航菜单,点击按钮能完美从右侧滑入,但关闭菜单的反向动画实现不了,这只是美观需求。

原代码

HTML & Alpine

<body x-data="{ isOpen: false }" x-cloak>
    <div x-show="isOpen" >
        <div id="side_navbar" x-transition:enter="slide_In">
            <img id="close_icon" x-transition:enter="slide_Out" class="is-pulled-right m-4" src="close_icon.svg" width="32px" @click=" isOpen = false ">
            <ul class="side_navbar-items mx-2 my-6 pt-1">
                <li><a class="side_navbar-item mb-4">link</a></li>
                <li><a class="side_navbar-item mb-4">link</a></li>
            </ul>
        </div><!-- side_navbar -->
    </div><!-- x-show component isOpen -->

<nav class="navbar" role="navigation" aria-label="main navigation">
  <div class="navbar-brand">
    <!-- navbar items, navbar burger... -->
    <a class="navbar-item" href="#">
      <img src="Grouplogo.svg">
    </a>

    <a role="button" class="site-menu " width="32px" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample" @click=" isOpen = !isOpen">
    <img src="burger_icon.svg">
  </a>

  </div><!-- navbar-brand -->

 <div id="navbarBasicExample" class="navbar-menu">

  <div class="navbar-menu">
    <!-- navbar start, navbar end -->
    <div class="navbar-end">

        <div class="navbar-item has-text-weight-medium ">
        <a class="navbar-item">link</a>
        <a class="navbar-item">link</a>
       
    </div><!-- navbar-end -->

    </div><!-- x-show component isOpen -->
</nav>

Custom CSS

#side_navbar{
    background-color: #57219C;
    color: #fffeff;
    z-index: 100;
    position: absolute;
    right: 0;
    top: 0;
    min-width: 20em;
    min-height: 100%;
    animation-name: slide_In;
    animation-duration: 0.1s;
}

@keyframes slide_In {
  from {
    margin-right: -200px;
    opacity: 0;
  }

  to {
    margin-right: 0;
    opacity: 1;
  }
}


@keyframes slide_Out {
  from {
    margin-right: 0;
  }

  to {
    margin-right: 200px;
  }
}

问题原因

  1. 直接给#side_navbar绑定CSS动画,与Alpine.js的x-transition机制冲突,导致关闭时无法触发反向动画。
  2. 关闭动画错误绑定在关闭按钮上,而非侧边栏容器本身。
  3. 使用margin-right控制位移,性能不如transform,且动画逻辑不符合侧边栏滑出的需求。

修复后的代码

修改后的HTML & Alpine

<body x-data="{ isOpen: false }" x-cloak>
    <!-- 给x-show容器添加x-transition控制进入/离开动画 -->
    <div x-show="isOpen" x-transition:enter="slide-in" x-transition:leave="slide-out">
        <div id="side_navbar">
            <img id="close_icon" class="is-pulled-right m-4" src="close_icon.svg" width="32px" @click="isOpen = false">
            <ul class="side_navbar-items mx-2 my-6 pt-1">
                <li><a class="side_navbar-item mb-4">link</a></li>
                <li><a class="side_navbar-item mb-4">link</a></li>
            </ul>
        </div>
    </div>

    <nav class="navbar" role="navigation" aria-label="main navigation">
        <div class="navbar-brand">
            <a class="navbar-item" href="#">
                <img src="Grouplogo.svg">
            </a>
            <a role="button" class="site-menu" width="32px" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample" @click="isOpen = !isOpen">
                <img src="burger_icon.svg">
            </a>
        </div>
        <div id="navbarBasicExample" class="navbar-menu">
            <div class="navbar-end">
                <div class="navbar-item has-text-weight-medium">
                    <a class="navbar-item">link</a>
                    <a class="navbar-item">link</a>
                </div>
            </div>
        </div>
    </nav>
</body>

修改后的Custom CSS

#side_navbar{
    background-color: #57219C;
    color: #fffeff;
    z-index: 100;
    position: absolute;
    right: 0;
    top: 0;
    min-width: 20em;
    min-height: 100%;
}

/* 进入动画类 */
.slide-in {
    animation: slide_In 0.3s ease forwards;
}

/* 离开动画类 */
.slide-out {
    animation: slide_Out 0.3s ease forwards;
}

@keyframes slide_In {
  from {
    /* 使用transform实现位移,性能更优 */
    transform: translateX(100%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

@keyframes slide_Out {
  from {
    transform: translateX(0);
    opacity: 1;
  }
  to {
    transform: translateX(100%);
    opacity: 0;
  }
}

修复说明

  1. 移除#side_navbar上直接绑定的CSS动画,交给Alpine.js的x-transition控制元素的进入/离开状态。
  2. 将x-transition:enter和x-transition:leave绑定到x-show的容器上,分别对应进入和离开的动画类。
  3. 用transform: translateX()替代margin-right控制侧边栏位移,提升动画流畅度。
  4. 调整动画时长到0.3s,让过渡效果更自然。

内容的提问来源于stack exchange,提问作者Graeme Robinson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 21:13:11