如何在纯 HTML/JS 中应用 Tailwind UI 动画

Posted

技术标签:

【中文标题】如何在纯 HTML/JS 中应用 Tailwind UI 动画【英文标题】:How to apply Tailwind UI animation in plain HTML/JS 【发布时间】:2021-12-29 03:07:42 【问题描述】:

我正在尝试使用示例 tailwindui.com 组件。 他们在 cmets 中定义了动画部分,但我无法弄清楚我应该如何在我的代码中使用这些动画部分。我正在使用普通的 html/js,并且不希望为此使用任何框架/lib。

我在这里尝试显示/隐藏模式对话框。 背景覆盖的动画 doe 给出为

 <!--
      Background overlay, show/hide based on modal state.

      Entering: "ease-out duration-300"
        From: "opacity-0"
        To: "opacity-100"
      Leaving: "ease-in duration-200"
        From: "opacity-100"
        To: "opacity-0"
    --> 

我不知道如何将此信息编码到背景覆盖 div。

<div id="myModal" class="hidden fixed z-10 inset-0 overflow-y-auto" aria-labelledby="modal-title" role="dialog" aria-modal="true">
  <div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
    <!--
      Background overlay, show/hide based on modal state.

      Entering: "ease-out duration-300"
        From: "opacity-0"
        To: "opacity-100"
      Leaving: "ease-in duration-200"
        From: "opacity-100"
        To: "opacity-0"
    -->
    <div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>

这是我迄今为止尝试过的;

<style>
  .modalEntry animation:modal-in 1s;  
  .modalExit animation:modal-in 1s;

@keyframes modal-in 
    from opacity-0;
    to opacity-100;

@keyframes modal-out 
    from opacity-100;
    to opacity-0;

</style>

<button class="border border-red-500" onclick="toggleModal()">Toggle modal</button>

<!-- This example requires Tailwind CSS v2.0+ -->
<div id="myModal" class="hidden fixed z-10 inset-0 overflow-y-auto" aria-labelledby="modal-title" role="dialog" aria-modal="true">
  <div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
    <!--
      Background overlay, show/hide based on modal state.

      Entering: "ease-out duration-300"
        From: "opacity-0"
        To: "opacity-100"
      Leaving: "ease-in duration-200"
        From: "opacity-100"
        To: "opacity-0"
    -->
    <div class="fixed modalEntry inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>

    <!-- This element is to trick the browser into centering the modal contents. -->
    <span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>

    <!--
      Modal panel, show/hide based on modal state.

      Entering: "ease-out duration-300"
        From: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
        To: "opacity-100 translate-y-0 sm:scale-100"
      Leaving: "ease-in duration-200"
        From: "opacity-100 translate-y-0 sm:scale-100"
        To: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
    -->
    <div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
      <div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
        <div class="sm:flex sm:items-start">
          <div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10">
            <!-- Heroicon name: outline/exclamation -->
            <svg class="h-6 w-6 text-red-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
              <path stroke-linecap="round" stroke-linejoin="round" stroke- d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
            </svg>
          </div>
          <div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
            <h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">Deactivate account</h3>
            <div class="mt-2">
              <p class="text-sm text-gray-500">Are you sure you want to deactivate your account? All of your data will be permanently removed. This action cannot be undone.</p>
            </div>
          </div>
        </div>
      </div>
      <div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
        <button onclick="toggleModal()" type="button" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">Deactivate</button>
        <button onclick="toggleModal()" type="button" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">Cancel</button>
      </div>
    </div>
  </div>
</div>

<script>
  function toggleModal () 
        document.getElementById("myModal").classList.toggle("hidden");
  
</script>

为了便于测试,我已将其放入代码笔中。 https://codepen.io/rishavs/pen/BadMQaN?editors=1000

【问题讨论】:

【参考方案1】:

您不能使用“隐藏”类制作动画,因为 css 属性 display 不可动画。

动画类型 - 不可动画documentation

但是,要解决这个问题,您可以使用setTimeout 函数,它将帮助我们延迟切换类并避免动画/过渡中断。还需要创建两个类来覆盖初始类并使用 javascript 添加或删除它们。

#myModal.modalEntry 
  opacity: 1;

#box.animate 
  opacity: 1;
  transform: translateY(0) scale(1);
  transition: all 0.2s ease-in;

#myModal.modalEntry 
  opacity: 1;


#box.animate 
  opacity: 1;
  transform: translateY(0) scale(1);
  transition: all 0.2s ease-in;
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet" />
<button class="border border-red-500" onclick="toggleModal()">
      Toggle modal
    </button>

<!-- This example requires Tailwind CSS v2.0+ -->
<div id="myModal" class="
        fixed
        z-10
        inset-0
        overflow-y-auto
        ease-out
        duration-300
        hidden
        opacity-0
      " aria-labelledby="modal-title" role="dialog" aria-modal="true">
  <div class="
          flex
          items-end
          justify-center
          min-h-screen
          pt-4
          px-4
          pb-20
          text-center
          sm:block sm:p-0
        ">
    <!--
          Background overlay, show/hide based on modal state.

          Entering: "ease-out duration-300"
            From: "opacity-0"
            To: "opacity-100"
          Leaving: "ease-in duration-200"
            From: "opacity-100"
            To: "opacity-0"
        -->
    <div class="
            fixed
            modalEntry
            inset-0
            bg-gray-500 bg-opacity-75
            transition-opacity
          " aria-hidden="true"></div>

    <!-- This element is to trick the browser into centering the modal contents. -->
    <span class="
            hidden
            sm:inline-block sm:align-middle sm:h-screen
            ease-out
            duration-300
          " aria-hidden="true">&#8203;</span
        >

        <!--
          Modal panel, show/hide based on modal state.

          Entering: "ease-out duration-300"
            From: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
            To: "opacity-100 translate-y-0 sm:scale-100"
          Leaving: "ease-in duration-200"
            From: "opacity-100 translate-y-0 sm:scale-100"
            To: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
        -->

        <div
          id="box"
          class="
            inline-block
            align-bottom
            bg-white
            rounded-lg
            text-left
            overflow-hidden
            shadow-xl
            transform
            transition-all
            sm:my-8 sm:align-middle sm:max-w-lg sm:w-full
            ease-out
            duration-300
            opacity-0
            translate-y-4
            sm:translate-y-0 sm:scale-95
          "
        >
          <div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
            <div class="sm:flex sm:items-start">
              <div
                class="
                  mx-auto
                  flex-shrink-0 flex
                  items-center
                  justify-center
                  h-12
                  w-12
                  rounded-full
                  bg-red-100
                  sm:mx-0 sm:h-10 sm:w-10
                "
              >
                <!-- Heroicon name: outline/exclamation -->
                <svg
                  class="h-6 w-6 text-red-600"
                  xmlns="http://www.w3.org/2000/svg"
                  fill="none"
                  viewBox="0 0 24 24"
                  stroke="currentColor"
                  aria-hidden="true"
                >
                  <path
                    stroke-linecap="round"
                    stroke-linejoin="round"
                    stroke-
                    d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
                  />
                </svg>
              </div>
              <div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
                <h3
                  class="text-lg leading-6 font-medium text-gray-900"
                  id="modal-title"
                >
                  Deactivate account
                </h3>
                <div class="mt-2">
                  <p class="text-sm text-gray-500">
                    Are you sure you want to deactivate your account? All of
                    your data will be permanently removed. This action cannot be
                    undone.
                  </p>
                </div>
              </div>
            </div>
          </div>
          <div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
            <button
              onclick="toggleModal()"
              type="button"
              class="
                w-full
                inline-flex
                justify-center
                rounded-md
                border border-transparent
                shadow-sm
                px-4
                py-2
                bg-red-600
                text-base
                font-medium
                text-white
                hover:bg-red-700
                focus:outline-none
                focus:ring-2
                focus:ring-offset-2
                focus:ring-red-500
                sm:ml-3 sm:w-auto sm:text-sm
              "
            >
              Deactivate
            </button>
            <button
              onclick="toggleModal()"
              type="button"
              class="
                mt-3
                w-full
                inline-flex
                justify-center
                rounded-md
                border border-gray-300
                shadow-sm
                px-4
                py-2
                bg-white
                text-base
                font-medium
                text-gray-700
                hover:bg-gray-50
                focus:outline-none
                focus:ring-2
                focus:ring-offset-2
                focus:ring-indigo-500
                sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm
              "
            >
              Cancel
            </button>
          </div>
        </div>
      </div>
    </div>

    <script>
      function toggleModal() 
        const myModal = document.getElementById('myModal');
        const box = document.getElementById('box');

        const hasClass = myModal.classList.contains('modalEntry');

        if (hasClass) 
          box.classList.remove('animate');
          setTimeout(() => 
            myModal.classList.remove('modalEntry');
            box.classList.add('hidden');
          , 200);
          setTimeout(() => 
            myModal.classList.add('hidden');
          , 300);
         else 
          box.classList.remove('hidden');
          myModal.classList.remove('hidden');
          setTimeout(() => 
            box.classList.add('animate');
            myModal.classList.add('modalEntry');
          , 300);
        
      
    </script>

【讨论】:

以上是关于如何在纯 HTML/JS 中应用 Tailwind UI 动画的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 应用程序中使用 Tailwind-css

如何使用 Tailwind 将媒体查询应用于高度和宽度?

JSX 在纯 JavaScript 文件中工作,如何?

在 Vite2 中,如何在 tailwind.config.js 中导入 ESModule

Codahale Metrics:在纯 Java 中使用 @Timed 指标注释

如何在rails应用程序的tailwind css中导入font-awesome [关闭]