Magic Flip Cards: Lösung eines häufigen Größenproblems
Veröffentlicht: 2022-03-10Wie stehen die Chancen, dass Ihr nächster Kunde das Wort interaktiv verwendet, wenn er sein Projekt vorstellt? Meiner Erfahrung nach lautet die Antwort 100 % , daher suche ich immer nach robusten CSS-Techniken, die mir helfen, die verschiedenen Funktionen und Effekte bereitzustellen, die bei der Diskussion dieses Ziels auftauchen.
Ein kleines Stück Interaktivität, um das ich immer wieder gebeten werde, sind Flip Cards – Inhaltsblöcke, die sich drehen, wenn man sie bewegt oder antippt, um Inhalte auf ihrer Rückseite zu enthüllen. Es ist ein netter Effekt, der zum spielerischen Surfen anregt, und eine weitere Möglichkeit, mehr Informationen anzuzeigen, ohne von der Seite wegzunavigieren. Das Standardverfahren hat jedoch ein Problem, wenn es darum geht, unterschiedliche Karteninhaltslängen zu berücksichtigen.
In diesem Tutorial werden wir ein Flip-Card-Grid erstellen, das dieses Problem mit einigen CSS-Grundlagen löst – Transformationen, Flex und Grid. Sie müssen mit diesen vertraut sein, und es ist hilfreich, CSS-Positionierungstechniken gut zu verstehen. Wir werden abdecken:
- Wie Flip-Karten normalerweise mit absoluter Positionierung implementiert werden;
- Das Größenproblem, das die absolute Positionierung einführt; und
- Eine allgemeine Lösung für die automatische Größenanpassung von überlagerten Inhalten.
Erstellen einer einfachen Flip-Karte
Mit einer guten modernen Browserunterstützung für dreidimensionale Transformationen ist das Erstellen einer einfachen Flip-Karte relativ einfach. Die übliche Methode besteht darin, die Vorder- und Rückseite der Karte in einen übergeordneten Behälter zu legen und die Rückseite absolut so zu positionieren, dass sie der Größe der Vorderseite entspricht. Fügen Sie der Rückseite eine X-Achsen-Transformation hinzu, damit sie umgekehrt erscheint, fügen Sie der Karte selbst beim Hover eine weitere hinzu, und wir sind im Geschäft.
.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); }
Was könnte schiefgehen?
Unsere Standardlösung hat jedoch ein großes Problem: Sie funktioniert nicht, wenn die Rückseite mehr Platz benötigt, als die Vorderseite bietet. Der Karte eine große, feste Größe zu geben, ist eine Lösung, aber dieser Ansatz wird auch garantiert irgendwann für einige Bildschirmgrößen fehlschlagen.
Design-Kompositionen verfügen natürlich über ordentlich aussehende Kästchen mit perfekt passendem Text. Zu Beginn der Entwicklung kann es jedoch schwierig sein, ein Seiten- und Kartenlayout zu erhalten, das für den tatsächlichen Inhalt geeignet ist. Und wenn Sie dynamische Inhalte von einem CMS anzeigen, kann es unmöglich sein! Selbst bei Wort- oder Zeichenbeschränkungen gibt es oft keine Lösung, die auf allen Geräten zuverlässig funktioniert.
Wir sollten immer danach streben, Layout-Implementierungen zu erstellen, die ein breites Spektrum an Inhaltslängen tolerieren. Aber es ist nicht einfach! Ich hatte oft Gelegenheit, auf feste Größen und Positionen zurückzugreifen, sei es aufgrund von Zeitdruck, unzureichender Browserunterstützung, einem schwachen Referenzdesign oder einfach meiner eigenen Unerfahrenheit.
Im Laufe der Jahre habe ich gelernt, dass ein guter iterativer Prozess und ein gesunder Dialog mit dem Designer bei der Auseinandersetzung mit diesen Problemen sehr hilfreich sein können, und oft kann man sich irgendwo in der Mitte treffen, um ein robustes Layout mit etwas Interaktivität zu erhalten. Aber zurück zur eigentlichen Aufgabe – ist sie machbar?
In andere Richtungen denken
Tatsächlich ist es möglich, die Größe der Karten sowohl auf der Vorder- als auch auf der Rückseite zu bestimmen, und es ist nicht so schwierig, wie es zunächst scheint. Wir müssen nur methodisch und hartnäckig sein!
Das Problem einschränken
Beginnen wir damit, eine Liste der Anforderungen an unser Layout zu erstellen. Der Versuch, genau aufzuschreiben, was Sie wollen, mag wie eine lästige Pflicht erscheinen, aber es ist eine großartige Möglichkeit, Einschränkungen aufzudecken, die vereinfacht werden können, um ein Problem zu lösen. Sagen wir:
- Wir möchten eine oder mehrere rechteckige Karten sehen, die in einem einspaltigen oder mehrspaltigen Raster angeordnet sind;
- Wir möchten, dass die Karten beim Bewegen oder Tippen umgedreht werden, um einen zweiten Inhaltssatz auf der Rückseite anzuzeigen.
- Wir möchten, dass die Karten immer groß genug sind, um den gesamten Vorder- und Rückseiteninhalt zu zeigen, unabhängig von der Länge oder dem Stil des Inhalts; und
- Im Fall von mehreren Spalten möchten wir idealerweise, dass alle Karten die gleiche Größe haben, damit die Reihen gut ausgerichtet sind.
Wenn wir diese Anforderungen durchdenken, können wir ein paar Dinge bemerken, die das Problem vereinfachen:
- Wenn die Karten in einem Raster dargestellt werden, haben wir eine Beschränkung ihrer Breite – das heißt, ihre Breite ist eher eine Funktion des Ansichtsfensters oder des Rastercontainers als ihr eigener Inhalt;
- Da wir die Breite einer Karte kennen (zumindest als Prozentsatz ihrer übergeordneten Karte), haben wir nach der horizontalen Dimension aufgelöst und müssen nur die Höhe der Karte erweitern, um sie an die größere ihrer Vorder- oder Rückseite anzupassen. und
- Wenn wir das tun können und jede Karte vertikal ihre eigene Größe hat, können wir CSS Grids
grid-auto-rows
verwenden, um alle Kartenreihen so hoch wie die höchste Karte zu machen.
Den Kartentrick herausfinden
Wie können wir also die Karten selbst skalieren? Jetzt haben wir unser Problem vereinfacht, wir sind in Reichweite der Lösung.
Vergessen Sie für einen Moment die Idee, Inhalte über andere Inhalte zu legen, und konzentrieren Sie sich auf unsere neue Anforderung: ein Elternteil, das so groß ist wie sein größtes Kind. Das ist leicht! Mithilfe von Spalten können wir bewirken, dass ein übergeordnetes Element auf die Höhe seines größten untergeordneten Elements erweitert wird. Dann müssen wir nur noch ein wenig Fingerspitzengefühl anwenden, um die Kinder auszurichten:
- Stellen Sie die Kinder so ein, dass sie die gleiche Breite wie ihre Eltern haben
- Lassen Sie das zweite Kind nach rechts überlaufen
- Verwandeln Sie es nach links wieder an seinen richtigen Platz
.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); }
Wenn dieser Ansatz offensichtlich erscheint, seien Sie versichert, dass ich viele Stunden damit verbracht habe, einige wirklich schreckliche Ideen durchzugehen, bevor ich darüber nachdachte. Zuerst hatte ich geplant, eine versteckte doppelte Version des Textes auf der Rückseite auf die Vorderseite zu drucken, um die Karte auf die richtige Größe zu erweitern. Und als ich daran dachte, den Spaltenüberlauf zu verwenden, beschnitt ich ursprünglich die rechte Spalte mit overflow:hidden
und transformierte sie erst im letzten Moment, als der Hover begann, da ich noch nicht realisiert hatte, dass ich sie einfach transformiert lassen könnte von Anfang an und verwenden Sie eine andere Methode wie opacity
oder backface-visibility
, um sie nach Bedarf ein- und auszuschalten.
Mit anderen Worten, offensichtliche Lösungen sind das Ergebnis harter Arbeit! Wenn Sie das Gefühl haben, dass Sie sich wegen eines Layoutproblems stundenlang den Kopf gegen den Schreibtisch geschlagen haben, ist es wichtig, einen Schritt zurückzutreten und zu entscheiden, ob Sie die Zeit Ihres Kunden sinnvoll verbringen: ob Sie ihm vorschlagen, das Design zu ändern, und ob die Lösung in Ruhe als Lernübung zu verfolgen, wenn der Druck weg ist. Aber wenn Sie auf einfache Methoden kommen, fühlen Sie sich nie dumm, weil es lange gedauert hat . Sehen wir uns nun unsere Komplettlösung an.
.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); }
Gibt es Vorbehalte?
Die Lösung funktioniert im Allgemeinen gut, mit nur ein paar kleinen Einschränkungen, die zu beachten sind:
- Die Karten müssen in einem Rasterlayout oder in einem anderen Kontext vorliegen, in dem ihre Breite nicht vom Inhalt abhängt.
- Karten benötigen eine Art Inhalts
card-body
), damit sich der Hover-Bereich während Animationen nicht ändert. Wenn die Karte selbst animiert ist, sehen Sie einige Störungen, wenn die Animation schnell stoppt und neu startet. - Stile wie Hintergründe und Kastenschatten werden am besten direkt auf der Vorder- und Rückseite platziert, da alle Effekte auf der Karte selbst nicht animiert werden. Achten Sie auf Gestaltungen wie Kastenschatten auf dem Kartenkörper, da diese natürlich auf den Kopf gestellt werden.
- Für die Vorder- und Rückseite von Karten muss die
box-sizing
Eigenschaft aufborder-box
gesetzt werden, wenn sie ihre eigene Polsterung haben, aufgrund ihrermin-width
, sonst werden sie überlaufen. - Safari erfordert immer noch
-webkit-backface-visibility
in seiner vom Hersteller vorangestellten Form.
Etwas Polnisch hinzufügen
Nachdem wir das schwierige Problem gelöst haben, schauen wir uns ein paar Optimierungen an, die wir vornehmen können, damit die gesamte Interaktion so reibungslos wie möglich funktioniert.
Überprüfen Sie zuerst, ob sich die Karten beim Wenden überlappen. Dies hängt davon ab, ob Sie mehrere Spalten verwenden, von der Breite des Spaltenstegs, der Ausrichtung des Umdrehens und dem Perspektivenwert der Karte, aber es ist wahrscheinlich, dass es passiert. Sie können die Dauer der Animation verlängern, um die Dinge klarer zu sehen. Beim Schweben sieht es unnatürlich aus, dass die schwebende Karte unter ihren späteren Nachbarn umgedreht wird, also müssen wir sie mit z-index
oben platzieren. Einfach genug, aber pass auf! Wir müssen warten, bis die ausgehende Animation abgeschlossen ist, bevor wir den z-index
wiederherstellen. transition-delay
:
.card { transition: z-index; transition-delay: var(--time); z-index: 0; &:hover { transition-delay: 0s; z-index: 1; } }
Ziehen Sie als Nächstes in Betracht, einen aktiven Status für die Karten zu erstellen. Normalerweise versuche ich, Karten wie diese mit einem relevanten Ort zu verknüpfen – auch wenn dies nicht vom Designer angegeben ist – da sich Elemente mit Hover-Effekten wie diesem sehr leicht antippen lassen, sodass es gut ist, Lesern, die ihr Glück versuchen, ein Ziel zu bieten. Ich mag eine kurze, subtile Skalierungstransformation, da sie ziemlich gut funktioniert, unabhängig davon, ob die zweite Hälfte der Animation durch das Laden der Zielseite abgeschnitten wird oder nicht (ich würde es jedoch begrüßen, wenn Browser In-Flight-Animationen vor der Navigation sauber abschließen Ich bin mir sicher, dass dies in der Praxis viel schwieriger umzusetzen wäre, als es sich anhört).
Dies ist auch eine großartige Gelegenheit, darüber nachzudenken, wie zugänglich die Rückseiteninhalte unserer Karten sind. Unser Markup ist prägnant und übersichtlich, daher haben wir Screenreader und andere Anwendungsfälle behandelt, die das Styling ignorieren, aber wie sieht es mit Tastaturbenutzern aus? Wenn wir die Karten selbst zu Ankern machen, erhalten sie den Fokus, wenn Tastaturbenutzer durch die Seite navigieren. Lassen Sie uns den Schwebezustand der Karte als Fokuszustand wiederverwenden, und der hintere Inhalt wird während des Durchsuchens der Tastatur natürlich angezeigt.
.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); } }
Vergessen Sie schließlich nicht, dass die Karte jetzt automatisch an ihren Inhalt angepasst wird. Sie können so ziemlich alle Ausrichtungs- und Abstandstechniken verwenden, die Sie innerhalb der vorderen und hinteren Container mögen. Verwenden Sie die Flex-Ausrichtung, um Titel zu zentrieren, Füllen hinzuzufügen und sogar ein weiteres Raster in die Karte einzufügen. Das ist das Schöne an guten Layoutlösungen, die mit ihrem Inhalt skalieren – reduzierte Kopplung von Kindern an Eltern und die Modularität, die es Ihnen ermöglicht, sich auf eine Sache nach der anderen zu konzentrieren.
.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; }
Einpacken
Ich hoffe, Sie finden diese CSS-Technik nützlich! Warum probieren Sie nicht einige Variationen der Animation aus, wie z. B. einen Skalierungseffekt oder eine einfache Überblendung? Die Technik ist auch nicht auf den Formfaktor der Karte beschränkt. Es kann überall dort eingesetzt werden, wo die Verantwortung für die vertikale Dimensionierung auf mehr als ein Element fällt. Stellen Sie sich eine Magazin-Website vor, die große Fotos mit überlagerten Bildunterschriften enthält – Sie könnten sie verwenden, um sowohl Bilder mit hohen Seitenverhältnissen als auch langen dynamischen Text aufzunehmen.
Denken Sie vor allem daran, welche Vorteile es hat, wenn Sie sich etwas Zeit nehmen, um ernsthaft darüber nachzudenken, ob es eine Möglichkeit gibt, ein Design zu implementieren, das so aussieht, als würde es nur mit fester Größe und Position funktionieren. Oft ist es immer am besten, und egal wie knifflig das Problem zunächst erscheinen mag, alle Ihre Anforderungen aufzuschreiben, etwas Zeit für die Erstellung eines minimalen Testfalls einzuplanen und ihn methodisch durchzugehen.