Magic Flip Cards : résoudre un problème de dimensionnement courant
Publié: 2022-03-10Quelles sont les chances que votre prochain client utilise le mot interactif lors de la présentation de son projet ? D'après mon expérience, la réponse est 100% , donc je suis toujours à la recherche de techniques CSS robustes pour m'aider à fournir les différentes fonctionnalités et effets qui apparaissent lors de la discussion de cet objectif.
Un petit élément d'interactivité que l'on me demande de mettre en œuvre encore et encore est les cartes à retourner - des blocs de contenu qui se retournent lorsqu'ils sont survolés ou tapés pour révéler le contenu sur leur verso. C'est un effet soigné qui encourage la navigation ludique et une autre façon d'afficher plus d'informations sans quitter la page. Mais la méthode standard a un problème lorsqu'il s'agit de s'adapter à différentes longueurs de contenu de carte.
Dans ce didacticiel, nous allons créer une grille de cartes à retourner qui résout ce problème avec certaines bases CSS - transformations, flex et grille. Vous devrez vous familiariser avec ceux-ci, et cela vous aidera à avoir une bonne compréhension des techniques de positionnement CSS. Nous couvrirons :
- Comment les flip cards sont généralement implémentées en utilisant le positionnement absolu ;
- Le problème de dimensionnement introduit par le positionnement absolu ; et
- Une solution générale pour le dimensionnement automatique du contenu superposé.
Création d'une carte à rabat de base
Avec une bonne prise en charge des navigateurs modernes pour les transformations en trois dimensions, la création d'une carte à retourner de base est relativement simple. La méthode habituelle consiste à placer les faces avant et arrière de la carte dans un conteneur parent et à positionner absolument la face arrière afin qu'elle corresponde à la taille de la face avant. Ajoutez une transformation sur l'axe des x à la face arrière pour la faire apparaître inversée, ajoutez-en une autre à la carte elle-même au survol, et nous sommes en affaires.
.cards { display: grid; } .card { perspective: 40rem; } .card-body { transform-style: preserve-3d; transition: var(--time) transform; .card:hover & { transform: rotateX(-180deg); } } .card-front, .card-back { backface-visibility: hidden; } .card-back { position: absolute; top: 0; right: 0; bottom: 0; left: 0; transform: rotateX(-180deg); }
Qu'est-ce qui pourrait mal se passer?
Notre solution standard a cependant un gros problème : elle ne fonctionne pas lorsque la face arrière a besoin de plus d'espace que la face avant n'en offre. Donner à la carte une grande taille fixe est une solution, mais cette approche est également garantie d'échouer à un moment donné pour un ensemble de tailles d'écran.
Les compositions de conception comportent naturellement des boîtes soignées avec du texte qui s'adapte parfaitement. Mais au début du développement, il peut être difficile d'obtenir une disposition de page et de carte qui fonctionne pour le contenu réel. Et lors de l'affichage de contenu dynamique depuis un CMS, cela peut être impossible ! Même avec des limites de mots ou de caractères, il n'existe souvent aucune solution qui fonctionne de manière fiable sur tous les appareils.
Nous devons toujours nous efforcer de créer des implémentations de mise en page qui tolèrent une large gamme de longueurs de contenu. Mais ce n'est pas facile ! J'ai souvent eu l'occasion de recourir à une taille et à une position fixes, que ce soit en raison de contraintes de temps, d'une prise en charge insuffisante du navigateur, d'une conception de référence faible ou simplement de ma propre inexpérience.
Au fil des ans, j'ai appris qu'un bon processus itératif et un dialogue sain avec le concepteur peuvent beaucoup aider à résoudre ces problèmes, et souvent vous pouvez vous rencontrer quelque part au milieu pour obtenir une mise en page robuste avec une certaine interactivité. Mais revenons à la tâche à accomplir - est-ce possible ?
Sortir des sentiers battus
En fait, il est possible de dimensionner les cartes en fonction du contenu recto et verso, et ce n'est pas aussi difficile qu'il n'y paraît au premier abord. Il suffit d'être méthodique et persévérant !
Contraindre le problème
Commençons par faire une liste des exigences de notre mise en page. Essayer d'écrire précisément ce que vous voulez peut sembler une corvée, mais c'est un excellent moyen de découvrir des contraintes qui peuvent être simplifiées pour résoudre un problème. Disons:
- Nous voulons voir une ou plusieurs cartes rectangulaires, disposées dans une grille à une ou plusieurs colonnes ;
- Nous voulons que les cartes se retournent au survol ou au toucher pour révéler un deuxième ensemble de contenu sur la face arrière ;
- Nous voulons que les cartes soient toujours assez grandes pour afficher tout leur contenu recto et verso, quelle que soit la longueur ou le style du contenu ; et
- Dans le cas de plusieurs colonnes, idéalement, nous voulons que toutes les cartes aient la même taille afin que les lignes s'alignent bien.
En réfléchissant à ces exigences, nous pouvons remarquer quelques éléments qui simplifient le problème :
- Si les cartes doivent être présentées dans une grille, nous avons une contrainte sur leur largeur - c'est-à-dire que leurs largeurs sont des fonctions de la fenêtre ou du conteneur de grille plutôt que de leur propre contenu ;
- Étant donné que nous connaissons la largeur d'une carte (en pourcentage de son parent, au moins), nous avons résolu la dimension horizontale et nous avons juste besoin que la hauteur de la carte s'étende pour s'adapter au plus haut de sa face avant ou arrière ; et
- Si nous pouvons le faire et que chaque carte est dimensionnée verticalement, nous pouvons utiliser les
grid-auto-rows
de CSS Grid pour que toutes les rangées de cartes soient aussi hautes que la carte la plus haute.
Comprendre le tour de carte
Alors, comment dimensionner soi-même les cartes ? Maintenant que nous avons simplifié notre problème, nous sommes à portée de la solution.
Oubliez un instant l'idée de mettre du contenu au-dessus d'un autre contenu et concentrez-vous sur notre nouvelle exigence : un parent aussi grand que son enfant le plus grand. C'est facile! En utilisant des colonnes, nous pouvons amener un parent à se développer à la hauteur de son enfant le plus grand. Ensuite, il suffit d'employer un petit tour de passe-passe pour aligner les enfants :
- Définir les enfants pour qu'ils aient la même largeur que leur parent
- Laisser le deuxième enfant déborder vers la droite
- Transformez-le vers la gauche à sa place
.cards { display: grid; } .card-body { display: flex; } .card-front, .card-back { min-width: 100%; mix-blend-mode: multiply; // Preview both faces } .card-back { transform: translate(-100%, 0); }
Si cette approche semble évidente, rassurez-vous, j'ai passé de nombreuses heures à passer en revue des idées vraiment terribles avant d'y penser. Au début, j'avais prévu d'imprimer une version en double cachée du texte de la face arrière à l'intérieur de la face avant pour agrandir la carte à la bonne taille. Et quand j'ai pensé à utiliser le débordement de colonne, je recadrais à l'origine la colonne de droite en utilisant overflow:hidden
, et je ne la transformais qu'au dernier moment lorsque le survol a commencé, car je n'avais pas encore réalisé que je pouvais juste le garder transformé depuis le début et utilisez une autre méthode telle que l' opacity
ou backface-visibility
pour l'activer et la désactiver au besoin.
En d'autres termes, les solutions évidentes sont le résultat d'un travail acharné ! Si vous avez l'impression de vous être cogné la tête contre votre bureau pendant des heures à propos d'un problème de mise en page, il est important de prendre du recul et de décider si vous passez le temps de votre client à bon escient : s'il faut lui suggérer de modifier le design, et si pour rechercher la solution à votre rythme en tant qu'exercice d'apprentissage lorsque la pression est relâchée. Mais quand vous trouvez des méthodes simples, ne vous sentez jamais stupide car cela a pris beaucoup de temps . Passons maintenant en revue notre solution complète.
.cards { display: grid; } .card { perspective: 40rem; } .card-body { display: flex; transform-style: preserve-3d; transition: var(--time) transform; .card:hover & { transform: rotateX(-180deg); } } .card-front, .card-back { backface-visibility: hidden; min-width: 100%; } .card-back { transform: rotateX(-180deg) translate(-100%, 0); }
Y a-t-il des mises en garde ?
La solution fonctionne généralement bien, avec juste quelques mises en garde mineures à garder à l'esprit :
- Les cartes doivent être présentes dans une disposition en grille ou dans un autre contexte où leurs largeurs ne dépendent pas du contenu.
- Les cartes nécessitent un wrapper de contenu quelconque (notre
card-body
) afin que la zone de survol ne change pas pendant les animations. Si la carte elle-même est animée, vous verrez des problèmes lorsque l'animation s'arrête et redémarre rapidement. - Les styles tels que les arrière-plans et les ombres de boîte sont mieux placés directement sur les faces avant et arrière, car les effets sur la carte elle-même ne seront pas animés. Méfiez-vous des styles tels que les ombres de boîte sur le corps de la carte, car elles seront naturellement retournées.
- Les faces avant et arrière des cartes ont besoin que leur propriété
box-sizing
soit définie surborder-box
si elles ont leur propre rembourrage, en raison de leur exigencemin-width
minimale, sinon elles déborderont. - Safari nécessite toujours
-webkit-backface-visibility
, sous sa forme préfixée par le fournisseur.
Ajouter du polonais
Maintenant que nous avons résolu le problème difficile, examinons quelques ajustements que nous pouvons apporter pour que toute l'interaction fonctionne aussi bien que possible.
Tout d'abord, vérifiez si les cartes se chevauchent lors du retournement. Cela dépendra si vous utilisez plusieurs colonnes, la largeur de la gouttière de la colonne, l'orientation du retournement et la valeur de perspective de la carte, mais cela est susceptible de se produire. Vous pouvez augmenter la durée de l'animation pour voir les choses plus clairement. Lors du survol, il semble anormal que la carte survolée se retourne sous ses voisins ultérieurs, nous devons donc la placer au-dessus en utilisant z-index
. Assez facile, mais attention ! Nous devons attendre que l'animation sortante soit terminée avant de restaurer le z-index
. Saisissez transition-delay
:
.card { transition: z-index; transition-delay: var(--time); z-index: 0; &:hover { transition-delay: 0s; z-index: 1; } }
Ensuite, envisagez de créer un état actif pour les cartes. J'essaie généralement de faire en sorte que des cartes comme celles-ci renvoient à un endroit pertinent - même si cela n'est pas spécifié par le concepteur - car les éléments avec des effets de survol comme celui-ci semblent très exploitables, il est donc bon de fournir une destination aux lecteurs qui tentent leur chance. J'aime une transformation d'échelle courte et subtile, car cela fonctionne raisonnablement bien, que la seconde moitié de l'animation soit coupée ou non par le chargement de la page de destination (j'aimerais que les navigateurs terminent proprement les animations en vol avant la navigation, bien que Je suis sûr que ce serait beaucoup plus difficile à mettre en œuvre dans la pratique qu'il n'y paraît).
C'est aussi une excellente occasion de réfléchir à l'accessibilité du contenu du verso de nos cartes. Notre balisage est concis et bien ordonné. Nous avons donc couvert les lecteurs d'écran et d'autres cas d'utilisation qui ignorent le style, mais qu'en est-il des utilisateurs de clavier ? Si nous allons faire des cartes elles-mêmes des ancres, elles recevront l'attention lorsque les utilisateurs du clavier naviguent sur la page. Réutilisons l'état de survol de la carte comme état de mise au point, et le contenu arrière apparaîtra naturellement lors de la navigation au clavier.
.card { transition: z-index, transform calc(var(--time) / 4); transition-delay: var(--time), 0s; z-index: 0; &:hover { transition-delay: 0s; z-index: 1; } &:active { transform: scale(0.975); } } .card-body { .card:hover &, .card:focus & { transform: rotateX(-180deg); } }
Enfin, n'oubliez pas que maintenant la carte s'adapte automatiquement à son contenu, vous pouvez utiliser à peu près toutes les techniques d'alignement et d'espacement que vous aimez à l'intérieur des conteneurs avant et arrière. Utilisez l'alignement flexible pour centrer les titres, ajouter du rembourrage et même placer une autre grille à l'intérieur de la carte. C'est la beauté des bonnes solutions de mise en page qui évoluent avec leur contenu - un couplage réduit des enfants aux parents et la modularité qui vous permet de vous concentrer sur une chose à la fois.
.card-front, .card-back { display: flex; align-items: center; background-color: white; box-shadow: 0 5px 10px black; border-radius: 0.25rem; padding: 1.5rem; }
Emballer
J'espère que vous trouverez cette technique CSS utile ! Pourquoi ne pas essayer quelques variations sur l'animation, comme un effet d'échelle ou un simple fondu enchaîné ? La technique ne se limite pas non plus au facteur de forme des cartes. Il peut être utilisé partout où la responsabilité du dimensionnement vertical incombe à plus d'un élément. Imaginez un site Web de magazine contenant de grandes photographies avec des légendes superposées - vous pouvez l'utiliser pour accueillir à la fois des images avec des rapports d'aspect élevés et un long texte dynamique.
Surtout, rappelez-vous les avantages de prendre du temps pour vraiment réfléchir à la possibilité de mettre en œuvre une conception qui semble ne fonctionner qu'avec une taille et une position fixes. Souvent, il y en a, et peu importe à quel point le problème peut sembler délicat au début, écrire toutes vos exigences, réserver du temps pour créer un cas de test minimal et le parcourir méthodiquement est toujours le meilleur pari.