轉場

使用 CSS 類別控制條件渲染元素的轉場樣式,包括巢狀子轉場。

若要開始進行,請透過 npm 安裝 Headless UI

npm install @headlessui/react

若要以條件方式呈現元素,請將它包在 Transition 元件內,然後使用 show 屬性表示它的狀態為開啟或關閉。

接著,使用原生 CSS 轉場樣式 套用動畫,藉由鎖定 Transition 元件所公開的 data-closed 屬性,指定元素關閉時的樣式。

import { Transition } from '@headlessui/react'
import { useState } from 'react'

function Example() {
  const [open, setOpen] = useState(false)

  return (
    <>
      <button onClick={() => setOpen((open) => !open)}>Toggle</button>
      <Transition show={open}>
        <div className="transition duration-300 ease-in data-[closed]:opacity-0">I will fade in and out</div>
      </Transition>
    </>
  )
}

定義在 data-closed 屬性中的樣式會在轉場進入時作為起始點,以及轉場離開時作為結束點。

對於較複雜的轉場,你也可以使用 data-enterdata-leavedata-transition 屬性,在轉場的不同階段套用樣式。

使用 data-enterdata-leave 屬性,可以在進入和離開時套用不同的轉場樣式

import { Transition } from '@headlessui/react'
import clsx from 'clsx'
import { useState } from 'react'

function Example() {
  const [open, setOpen] = useState(false)

  return (
    <div className="relative">
      <button onClick={() => setOpen((open) => !open)}>Toggle</button>
      <Transition show={open}>
        <div
          className={clsx([
            // Base styles
            'absolute w-48 border transition ease-in-out',
            // Shared closed styles
            'data-[closed]:opacity-0',
            // Entering styles
            'data-[enter]:duration-100 data-[enter]:data-[closed]:-translate-x-full',
            // Leaving styles
            'data-[leave]:duration-300 data-[leave]:data-[closed]:translate-x-full',
          ])}
        >
          I will enter from the left and leave to the right
        </div>
      </Transition>
    </div>
  )
}

此範例結合 data-enterdata-closed 屬性,以指定進入轉場的起始點,並結合 data-leavedata-closed 屬性,以指定離開轉場的結束點。

它也使用 data-enterdata-leave 屬性,指定不同的進入和離開持續時間。

有時你會需要使用不同的動畫來轉場多個元素,但所有轉場都基於相同的狀態。例如,假設使用者點擊按鈕以開啟會從螢幕側滑進來的側邊欄,而你也需要同時淡入一個背景。

你可以透過用父層 Transition 元件包裹相關元素來執行此操作,並用 TransitionChild 元件包裹每個需要自己轉場樣式的子層,此元件會自動與父層 Transition 進行通訊,並繼承父層的 open 狀態。

import { Transition, TransitionChild } from '@headlessui/react'
import { useState } from 'react'

function Example() {
  const [open, setOpen] = useState(false)

  return (
    <>
      <button onClick={() => setOpen(true)}>Open</button>
      {/* The `show` prop controls all nested `TransitionChild` components. */}
<Transition show={open}>
{/* Backdrop */}
<TransitionChild>
<div className="fixed inset-0 bg-black/30 transition duration-300 data-[closed]:opacity-0" onClick={() => setOpen(false)} />
</TransitionChild>
{/* Slide-in sidebar */}
<TransitionChild>
<div className="fixed inset-y-0 left-0 w-64 bg-white transition duration-300 data-[closed]:-translate-x-full"> {/* ... */}
</div>
</TransitionChild>
</Transition> </> ) }

TransitionChild 元件與 Transition 元件具有完全相同的 API,但沒有 show 屬性,因為 show 值由父層控制。

父層 Transition 元件在卸載之前,會自動等待所有子層完成轉場,所以你不需要自己管理任何時間安排。

如果您希望在第一次呈現元素時轉場,請將appear道具設為true

如果您希望某些東西在初始頁面載入時轉場,或在其父級條件式呈現時,這是一個有用的功能。

import { Transition } from '@headlessui/react'
import { useState } from 'react'

function Example() {
  const [open, setOpen] = useState(true)

  return (
    <>
      <button onClick={() => setOpen((open) => !open)}>Toggle</button>
<Transition show={open} appear={true}>
<div className="transition duration-300 ease-in data-[closed]:opacity-0">I will fade in on initial render</div> </Transition> </> ) }

屬性預設說明
as片段
字串 | 組件

轉場應該呈現為的元素或組件。

show
布林

子項應該顯示或隱藏。

appearfalse
布林

轉場是否應在初始安裝上執行。

unmounttrue
布林

元素應根據顯示狀態取消安裝或隱藏。

beforeEnter
() => void

在我們開始 enter 轉場之前呼叫的回呼。

afterEnter
() => void

在我們完成 enter 轉場後呼叫的回呼。

beforeLeave
() => void

在我們開始 leave 轉場之前呼叫的回呼。

afterLeave
() => void

在我們完成 leave 轉場後呼叫的回呼。

屬性預設說明
as片段
字串 | 組件

轉場transition child的元素或組件。

appearfalse
布林

轉場是否應在初始安裝上執行。

unmounttrue
布林

元素應根據顯示狀態取消安裝或隱藏。

beforeEnter
() => void

在我們開始 enter 轉場之前呼叫的回呼。

afterEnter
() => void

在我們完成 enter 轉場後呼叫的回呼。

beforeLeave
() => void

在我們開始 leave 轉場之前呼叫的回呼。

afterLeave
() => void

在我們完成 leave 轉場後呼叫的回呼。

屬性說明
data-closed

在轉換進來之前和轉換出時出現。

data-enter

在轉換進來時出現。

data-leave

在轉換出時出現。

data-transition

在轉換進來或轉換出時出現。

如果您有興趣預先設計 Tailwind CSS 組件範例,請使用 Headless UI看看Tailwind UI - 由我們建立的一系列設計精良且製作精良的組件。

這是支援我們致力於此類開源專案的絕佳方式,並使我們能夠改進專案並持續維護。