Fermer

mars 6, 2025

Un retournement de cartes avec vent arrière

Un retournement de cartes avec vent arrière


Apprenez à créer une animation de flip de carte 3D à l’aide de Tailwind CSS.

CSS a parcouru un long chemin au cours des 10 dernières années. Il est maintenant plus facile que jamais de créer des animations 3D. Le vent de queue facilite encore cela en incluant votre CSS directement dans vos attributs de classe.

Flip de carte animée. l'avant est bleu et l'arrière est vert

Tl;

Cela nécessite un JavaScript minimal pour créer des animations. Tailwind 4 ajoutera des fonctions d’espace 3D, mais vous pouvez y parvenir aujourd’hui avec des valeurs arbitraires dans Tailwind 3 ou en utilisant des plugins de vent arrière externes. La création d’une carte rotative n’a jamais été plus simple.

Configuration du vent arrière et du framework

Cette démo peut fonctionner dans n’importe quel cadre, bien que j’utilise Sveltekit pour la simplicité. Après avoir installé Tailwind, nous utiliserons des classes d’assistance.

  • npm i -D tailwind-merge clsx
  • Fusion de vent arrière Vous permet de compiler les classes que vous utilisez et d’éliminer celles que vous n’avez pas lorsque vous passez des classes entre les composants.
  • clsx est un petit utilitaire vous permettant de construire des conditions de classe HTML.

Ensemble, ces deux éléments ont été normalisés pour créer le cn fonction dans de grands cadres d’interface utilisateur comme shadcn.

// lib/utils.ts

import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";

export function cn(...inputs: ClassValue[]) {
	return twMerge(clsx(inputs));
}

Composants

Nous avons besoin d’un dos et d’un composant avant à afficher.

Devant

<div
	class="flex h-full w-full flex-col items-center justify-center rounded-xl border bg-blue-700 text-white"
>
	Front
</div>


Dos

<div
	class="flex h-full w-full flex-col items-center justify-center rounded-xl bg-emerald-700 text-white"
>
	Back
</div>

Vous pouvez utiliser les classes que vous souhaitez formater la carte, mais vous aurez besoin du size-full ou les deux w-full et h-full Pour s’assurer que la carte est complètement couverte.

Conteneur de bouton de base

Parce que nous retournerons la carte en cliquant, la meilleure pratique pour l’accessibilité est d’utiliser un button élément pour éviter la confusion avec les lecteurs d’écran.

<button type="button" onclick={() => {}} class="size-96 outline-none">
	<div class="relative size-full">
		<div class="absolute inset-0 size-full">
			<Front />
		</div>
		<div class="absolute inset-0 size-full">
			<Back />
		</div>
	</div>
</button>
  • Nous voulons type="button" Pour assurer une action de clic et non une rafraîchissement de page.
  • Nous ajouterons un onclick action plus tard.
  • Chrome ajoute une bordure supplémentaire pour les boutons standard sur des événements sélectionnés, nous supprimons donc cela avec outline-none.
  • Nous avons un récipient extérieur avec un relative Position d’affichage, avec deux absolute et inset-0 Conteneurs enfants, pour le dimensionnement exact lorsque nous utilisons nos transitions 3D.
  • Nous voulons size-full sur les trois div Éléments pour correspondre à nos tailles de cartes maximales.

Ajouter l’effet 3D

<button type="button" onclick={() => {}} class="size-96 outline-none [perspective:100rem]">
	<div class={cn('relative size-full transition duration-500 [transform-style:preserve-3d]')}>
		<div class="absolute inset-0 size-full [backface-visibility:hidden]">
			<Front />
		</div>
		<div
			class="absolute inset-0 size-full [backface-visibility:hidden] [transform:rotateY(180deg)]"
		>
			<Back />
		</div>
	</div>
</button>
  • Nous ajoutons [perspective:50rem] pour définir la perspective de l’espace 3D Root. L’équivalent du vent arrière est perspective-midrange.
  • Nous ajoutons [transform-style:preserve-3d] Pour confirmer que les éléments enfants seront toujours dans l’espace 3D. L’équivalent du vent arrière est transform-3d.
  • Nous ajoutons [backface-visibility:hidden] aux deux côtés de la carte pour cacher l’autre côté de l’élément lorsque chaque côté est visible. L’équivalent du vent arrière est backface-hidden.
  • Nous ajoutons [transform:rotateY(180deg)] à l’arrière de la carte pour régler l’arrière comme arrière. L’équivalent du vent arrière est rotate-y-180.

Si vous utilisez une ancienne version du vent arrière, vous préférez peut-être le Tailwind-3Dtransform-Pluginentre autres. Cependant, je préfère mettre le CSS directement dans la classe avec [] Jusqu’à ce que le vent arrière 4 soit stable et largement utilisé.

Le flip

Pour retourner la carte, nous avons besoin d’un état avant et arrière. La meilleure façon de représenter cela est avec un booléen qui peut être réactif.

const card = $state({
	showBack: false,
	flip() {
		this.showBack = !this.showBack;
	}
});

J’utilise un $state() variable dans svelte, mais cela pourrait facilement être traduit par useState ou d’autres types de signal() fonctions, selon votre cadre.

  • Nous retournons la carte avec card.flip().
  • Nous devons ajouter dynamiquement [transform:rotateY(180deg)] à notre élément racine lorsque nous voulons retourner. Rappelez-vous que c’est rotate-y-180 dans le vent arrière 4.
  • Nous pouvons ajouter transition duration-1000 pour avoir un deuxième effet d’animation.
<button type="button" onclick={() => card.flip()} class="size-96 outline-none [perspective:50rem]">
	<div
		class={cn(
			'relative size-full transition duration-1000 [transform-style:preserve-3d]',
			card.showBack && '[transform:rotateY(180deg)]'
		)}
	>
		<div class="absolute inset-0 size-full [backface-visibility:hidden]">
			<Front />
		</div>
		<div
			class="absolute inset-0 size-full [backface-visibility:hidden] [transform:rotateY(180deg)]"
		>
			<Back />
		</div>
	</div>
</button>

Remarquez que nous ajoutons programmatiquement la rotation grâce à notre nifty cn() fonction utilitaire.

card.showBack && '[transform:rotateY(180deg)]'

Bonus: retourner avec la barre d’espace

Si nous essayons de montrer le dos de la carte pour étudier une carte flash, et que nous voulons retourner la carte avec une touche, nous devons appeler le flip() fonction de cette touche.

useKey

Nous pouvons écouter manuellement une touche avec l’écouteur de l’événement JS, mais nous pouvons également faciliter cela.

import { onMount } from 'svelte';

export function useKey(
    key: string | string[],
    callback: (event: KeyboardEvent) => void,
    options: {
        event?: 'keydown' | 'keyup' | 'keypress',
        preventDefault?: boolean,
    } = {}
) {
    const {
        event="keydown",
        preventDefault = false,
    } = options;

    function handler(e: KeyboardEvent) {
        const keys = Array.isArray(key) ? key : [key];
        if (keys.includes(e.key)) {
            if (preventDefault) {
                e.preventDefault();
            }
            callback(e);
        }
    }

    onMount(() => {
        addEventListener(event, handler);
        return () => {
            removeEventListener(event, handler);
        };
    });
}

J’ai modifié useKey Pour travailler avec Svelte, mais il existe des packages et des modèles pré-écrits pour la plupart des frameworks:

Retourner avec de l’espace

useKey(' ', () => card.flip());

C’est ça!

Beau, non?




Source link