マジックフリップカード:一般的なサイジングの問題を解決する

公開: 2022-03-10
簡単な要約↬この記事では、Dan Hallidayが、アニメーション化されたフリップカードを作成するための標準的なアプローチを確認し、サイズの問題を解決する改善された方法を紹介します。

次のクライアントがプロジェクトを紹介するときにインタラクティブという言葉を使用する可能性はどのくらいありますか? 私の経験では、答えは100%なので、この目標について話し合うときに出てくるさまざまな機能や効果を提供するのに役立つ堅牢なCSS手法を常に探しています。

私が何度も実装するように求められている双方向性の小さな部分は、フリップカードです。これは、ホバーまたはタップすると裏側のコンテンツを表示するために回転するコンテンツのブロックです。 これは、遊び心のあるブラウジングを促進する優れた効果であり、ページから離れることなくより多くの情報を表示する別の方法です。 ただし、さまざまなカードコンテンツの長さに対応する場合、標準的な方法には問題があります。

このチュートリアルでは、いくつかのCSSの基本(変換、フレックス、グリッド)でその問題を解決するフリップカードグリッドを作成します。 これらに精通している必要があり、CSSポジショニングテクニックをよく理解するのに役立ちます。 カバーします:

  • フリップカードは通常、絶対測位を使用してどのように実装されますか。
  • 絶対測位がもたらすサイジングの問題。 と
  • オーバーレイされたコンテンツの自動サイズ設定の一般的なソリューション。
ジャンプした後もっと! 以下を読み続けてください↓

基本的なフリップカードの作成

3次元変換に対する最新のブラウザサポートにより、基本的なフリップカードの作成は比較的簡単です。 通常の方法は、表と裏のカード面を親コンテナに配置し、前面のサイズと一致するように背面を絶対に配置することです。 裏面にx軸変換を追加して反転して表示し、ホバー時にカード自体に別の変換を追加すると、ビジネスが始まります。

 .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); } 

絶対測位を使用した標準のフリップカードの実装(Dan Hallidayによるペン「[MagicFlip Cards 1:The StandardImplementation](https://codepen.io/smashingmag/pen/JjdPJvo)」を参照)

絶対測位を使用した標準のフリップカードの実装(Dan Hallidayによるペン「MagicFlip Cards 1:TheStandardImplementation」を参照)

何がうまくいかないのでしょうか?

ただし、標準ソリューションには大きな問題があります。前面が前面よりも多くのスペースを必要とする場合は機能しません。 カードに大きな固定サイズを与えることは1つの解決策ですが、そのアプローチは、画面サイズのセットによってはある時点で失敗することも保証されています。

バックコンテンツが長くなると、標準のフリップカードの実装がどのように失敗するか
これは、標準のフリップカードの実装が長いバックコンテンツで失敗する方法です。 (大プレビュー)

デザインコンプは、自然に見栄えの良いボックスと完全にフィットするテキストを備えています。 しかし、開発を開始するとき、実際のコンテンツに適したページとカードのレイアウトを取得するのは難しい場合があります。 また、CMSから動的コンテンツを表示する場合、それは不可能な場合があります。 単語や文字の制限があっても、すべてのデバイスで確実に機能するソリューションがない場合がよくあります。

バックコンテンツが長くなると、標準のフリップカードの実装がどのように失敗するか(Dan Hallidayによるペン「[MagicFlip Cards 2:How Absolute PositioningFails](https://codepen.io/smashingmag/pen/QWbLMLz)」を参照)

バックコンテンツが長くなると、標準のフリップカードの実装がどのように失敗するか(Dan Hallidayによるペン「MagicFlip Cards 2:How Absolute PositioningFails」を参照)

幅広いコンテンツの長さに耐えるレイアウトの実装を作成するように常に努力する必要があります。 しかし、それは簡単ではありません! 時間の制約、不十分なブラウザサポート、弱い参照デザイン、または私自身の経験不足などの理由で、固定のサイズと位置を使用することに戻る機会がよくありました。

何年にもわたって、これらの問題を解決する際には、優れた反復プロセスとデザイナーとの健全な対話が大いに役立つことを学びました。多くの場合、途中で会って、インタラクティブ性のある堅牢なレイアウトを取得できます。 しかし、目前のタスクに戻りましょう—それは実行できますか?

箱の外で考える

実際、表と裏の両方のコンテンツに基づいてカードのサイズを設定すること可能であり、最初に思われるほど難しくはありません。 整然と粘り強くする必要があります!

問題の抑制

レイアウトの要件のリストを作成することから始めましょう。 必要なものを正確に書き留めようとすると、雑用のように見えるかもしれませんが、問題を解決するために単純化できる制約を明らかにするための優れた方法です。 まあ言ってみれば:

  • 1列または複数列のグリッドに配置された1つまたは複数の長方形のカードを見たいと思います。
  • カードをホバーまたはタップして裏返し、裏面に2番目のコンテンツセットを表示します。
  • カードは、コンテンツの長さやスタイルに関係なく、常に前面と背面のすべてのコンテンツを表示できる大きさにする必要があります。 と
  • 複数の列の場合、理想的には、行がうまく整列するように、すべてのカードを同じサイズにする必要があります。

これらの要件を検討すると、問題を単純化するいくつかのことに気付くことができます。

  • カードがグリッドで表示される場合、幅に制約があります。つまり、カードの幅は、独自のコンテンツではなく、ビューポートまたはグリッドコンテナの関数です。
  • カードの幅(少なくとも親のパーセンテージとして)がわかっているので、水平方向の寸法を解き、カードの高さを前面または背面の背の高い方に合わせて拡大する必要があります。 と
  • それが可能で、各カードが垂直方向に自己サイズである場合、CSSグリッドのgrid-auto-rowsを使用して、カードのすべての行を最も高いカードと同じ高さにすることができます。

カードトリックを理解する

では、どのようにしてカードのサイズを自分で決めるのでしょうか。 これで問題が単純化され、解決策が届きました。

コンテンツを他のコンテンツの上に置くという考えを少しの間忘れて、私たちの新しい要件、つまり最も背の高い子供と同じくらい背が高い親に焦点を合わせます。 それは簡単です! 列を使用して、親を最も高い子の高さまで拡張させることができます。 次に、子供たちを揃えるために少し手先の早業を採用する必要があります。

  1. 子を親と同じ幅に設定します
  2. 2番目の子が右にオーバーフローするのを許可します
  3. 左方向に変形して適切な場所に戻します
.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); } 

固定水平オーバーフローによる垂直サイジング(Dan Hallidayによるペン「[マジックフリップカード3:固定水平オーバーフローによる垂直サイジング](https://codepen.io/smashingmag/pen/ExjYvjP)」を参照)

固定水平オーバーフローによる垂直サイジング(Dan Hallidayによるペン「マジックフリップカード3:固定水平オーバーフローによる垂直サイジング」を参照)

このアプローチが明白であると思われる場合は、それを考える前に、私がいくつかの本当にひどいアイデアを検討するのに何時間も費やしたので安心してください。 最初は、カードを正しいサイズに拡大するために、前面のテキストの非表示の複製バージョンを前面の内側に印刷することを計画していました。 そして、列オーバーフローを使用することを考えたとき、私は元々、 overflow:hiddenを使用して右側の列をトリミングし、ホバーが開始された最後の瞬間にのみ変換していました。最初から、 opacitybackface-visibilityなどの別の方法を使用して、必要に応じてオンとオフを切り替えます。

言い換えれば、明らかな解決策はハードワークの結果です! レイアウトの問題で何時間も机に頭をぶつけてきたような気がする場合は、一歩下がって、クライアントの時間を賢く費やしているかどうかを判断することが重要です。つまり、クライアントがデザインを変更することを提案するかどうか、プレッシャーがなくなったときの学習演習として、自分の時間で解決策を追求すること。 しかし、簡単な方法を思いついたときは、時間がかかったので決して愚かではありません。 それでは、完全なソリューションを確認しましょう。

 .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); } 

完全なマジックフリップカードソリューション(Dan Hallidayによるペン「[MagicFlip Cards 4:The Complete Solution](https://codepen.io/smashingmag/pen/xxGKLZO)」を参照)

完全なマジックフリップカードソリューション(Dan Hallidayによるペン「マジックフリップカード4:完全なソリューション」を参照)

警告はありますか?

このソリューションは一般的にうまく機能しますが、覚えておくべきいくつかの小さな注意点があります。

  • カードは、グリッドレイアウト、または幅がコンテンツに依存しないその他のコンテキストで存在する必要があります。
  • カードには、アニメーション中にホバー領域が変化しないように、ある種のコンテンツラッパー( card-body )が必要です。 カード自体がアニメーション化されている場合、アニメーションが急速に停止して再開するため、グリッチが発生します。
  • カード自体への影響はアニメーション化されないため、背景やボックスシャドウなどのスタイリングは、前面と背面に直接配置するのが最適です。 カード本体のボックスシャドウなどのスタイリングには注意してください。当然、逆さまになります。
  • カードの前面と背面には、 min-width要件があるため、独自のパディングがある場合はボックスbox-sizing設定プロパティをborder-boxに設定する必要があります。そうでない場合、カードはオーバーフローします。
  • Safariには、ベンダープレフィックス形式-webkit-backface-visibilityが引き続き必要です。

ポーランド語を追加する

これで難しい問題は解決しました。インタラクション全体を可能な限りスムーズに機能させるために行うことができるいくつかの調整を見てみましょう。

まず、裏返し中にカードが重なっていないか確認します。 これは、複数の列を使用しているかどうか、列のガターの幅、フリップの方向、およびカードの遠近法の値によって異なりますが、発生する可能性があります。 アニメーションの長さを長くして、物事をよりはっきりと見ることができます。 ホバーすると、ホバーしたカードが後の隣のカードの下で反転するのは不自然に見えるため、 z-indexを使用してカードを上に配置する必要があります。 簡単ですが、気を付けてください! z-indexを復元する前に、送信アニメーションが完了するまで待つ必要があります。 transition-delay入力してください:

 .card { transition: z-index; transition-delay: var(--time); z-index: 0; &:hover { transition-delay: 0s; z-index: 1; } }

次に、カードのアクティブ状態を作成することを検討してください。 このようなホバー効果のある要素は非常にタップしやすいので、運試しをする読者に目的地を提供するのは良いことです。 アニメーションの後半が宛先ページの読み込みによって途切れる場合でも、短くて微妙なスケール変換が適切に機能するので、私は短くて微妙なスケール変換が好きです(ただし、ブラウザーがナビゲーションの前に実行中のアニメーションをきれいに完了することを望んでいます。実際に実装するのは、思ったよりはるかに難しいと思います)。

これは、カードのバックコンテンツがどれほどアクセスしやすいかを考える絶好の機会でもあります。 マークアップは簡潔で整理されているため、スクリーンリーダーや、スタイルを無視するその他のユースケースについて説明しましたが、キーボードユーザーはどうでしょうか。 カード自体をアンカーにする場合、キーボードユーザーがページをタブで移動すると、カードにフォーカスが移ります。 カードのホバー状態をフォーカス状態として再利用してみましょう。キーボードのブラウジング中にバックコンテンツが自然に表示されます。

 .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); } }

最後に、カードがコンテンツに合わせて自動的に拡大縮小されることを忘れないでください。前面と背面のコンテナ内で、好きな配置と間隔のテクニックをほぼすべて使用できます。 フレックスアライメントを使用してタイトルを中央に配置し、パディングを追加し、カード内に別のグリッドを配置します。 これは、コンテンツに合わせて拡張できる優れたレイアウトソリューションの美しさです。つまり、子と親の結合が減り、一度に1つのことに集中できるモジュール性があります。

 .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; }

まとめ

このCSSテクニックがお役に立てば幸いです。 スケール効果や単純なクロスフェードなど、アニメーションのバリエーションを試してみませんか? テクニックはカードのフォームファクターにも限定されません。 垂直方向のサイズ設定の責任が複数の要素に及ぶ場合は、どこでも使用できます。 キャプションがオーバーレイされた大きな写真を掲載している雑誌のウェブサイトを想像してみてください。これを使用して、アスペクト比の高い画像と長いダイナミックテキストの両方に対応できます。

何よりも、固定されたサイズと位置でのみ機能するように見えるデザインを実装する方法があるかどうかを真剣に考えることの利点を覚えておいてください。 多くの場合、問題が最初はどんなに難しいように見えても、すべての要件を書き留め、最小限のテストケースを作成するために時間を取って、それを系統的に進めることが常に最善の策です。