매직 플립 카드: 일반적인 크기 조정 문제 해결

게시 됨: 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의 Pen "[Magic Flip Cards 1: The Standard Implementation](https://codepen.io/smashingmag/pen/JjdPJvo)" 참조)

절대 위치 지정을 사용한 표준 플립 카드 구현(Dan Halliday의 Pen "Magic Flip Cards 1: The Standard Implementation" 참조)

무엇이 잘못될 수 있습니까?

그러나 우리의 표준 솔루션에는 큰 문제가 있습니다. 뒷면이 앞면이 제공하는 것보다 더 많은 공간이 필요할 때 작동하지 않습니다. 카드에 고정된 큰 크기를 제공하는 것이 하나의 솔루션이지만 이 접근 방식은 일부 화면 크기 세트에서 어느 시점에서 실패할 수도 있습니다.

더 긴 백 콘텐츠로 표준 플립 카드 구현이 실패하는 방법
이것이 표준 플립 카드 구현이 더 긴 백 콘텐츠로 실패하는 방식입니다. (큰 미리보기)

디자인 구성 요소는 자연스럽게 완벽하게 맞는 텍스트와 함께 깔끔한 모양의 상자를 특징으로 합니다. 그러나 개발을 시작할 때 실제 콘텐츠에 맞는 페이지와 카드 레이아웃을 얻는 것이 어려울 수 있습니다. 그리고 CMS에서 동적 콘텐츠를 표시할 때 불가능할 수 있습니다! 단어 또는 문자 제한이 있더라도 모든 장치에서 안정적으로 작동하는 솔루션은 없는 경우가 많습니다.

표준 플립 카드 구현이 더 긴 백 콘텐츠로 실패하는 방법(Dan Halliday의 Pen "[Magic Flip Cards 2: How Absolute Positioning Fails](https://codepen.io/smashingmag/pen/QWbLMLz)" 참조)

더 긴 뒷면 콘텐츠로 표준 플립 카드 구현이 실패하는 방법(Dan Halliday의 Pen "Magic Flip Cards 2: How Absolute Positioning Fails" 참조)

광범위한 콘텐츠 길이를 허용하는 레이아웃 구현을 만들기 위해 항상 노력해야 합니다. 하지만 쉽지 않다! 시간 제약, 불충분한 브라우저 지원, 약한 참조 디자인 또는 내 자신의 경험 부족으로 인해 고정 크기와 위치를 사용하는 경우가 종종 있었습니다.

수년에 걸쳐 저는 이러한 문제를 해결할 때 디자이너와 좋은 반복 프로세스와 건전한 대화가 많은 도움이 될 수 있다는 것을 배웠고, 종종 중간에서 만나 약간의 상호 작용이 있는 강력한 레이아웃을 얻을 수 있습니다. 그러나 당면한 과제로 돌아가서 - 할 수 있습니까?

틀을 깨고 생각하라

사실 앞뒷면 내용을 기준으로 카드의 크기를 정하는 것이 가능하며, 처음에 보이는 것만큼 어렵지 않습니다. 우리는 체계적이고 끈기 있기만 하면 됩니다!

문제 제한

레이아웃의 요구 사항 목록을 만드는 것으로 시작하겠습니다. 원하는 것을 정확하게 기록하는 것은 귀찮은 일처럼 보일 수 있지만 문제를 해결하기 위해 단순화할 수 있는 제약 조건을 발견하는 좋은 방법입니다. 의 말을하자:

  • 단일 열 또는 다중 열 그리드로 배열된 하나 이상의 직사각형 카드를 보고 싶습니다.
  • 우리는 카드가 호버 또는 탭에서 뒤집혀 뒷면에 두 번째 콘텐츠 세트가 표시되기를 원합니다.
  • 우리는 카드가 콘텐츠 길이나 스타일에 관계없이 항상 앞면과 뒷면의 모든 내용을 표시할 수 있을 만큼 충분히 커야 합니다. 그리고
  • 여러 열의 경우 이상적으로는 모든 카드의 크기가 같아야 행이 잘 정렬됩니다.

이러한 요구 사항을 고려하여 문제를 단순화하는 몇 가지 사항을 확인할 수 있습니다.

  • 카드가 그리드에 표시될 경우 너비에 대한 제약이 있습니다. 즉, 너비는 자체 콘텐츠가 아니라 뷰포트 또는 그리드 컨테이너의 기능입니다.
  • 우리가 카드의 너비(적어도 부모의 백분율로)를 알고 있다는 점을 감안할 때 수평 차원을 해결했으며 카드의 높이가 앞면 또는 뒷면의 더 큰 부분에 맞게 확장되도록 하면 됩니다. 그리고
  • 그렇게 할 수 있고 각 카드가 세로로 자체 크기라면 CSS Grid의 grid-auto-rows 를 사용하여 모든 행의 카드를 가장 높은 카드만큼 높이 만들 수 있습니다.

카드 트릭 알아내기

그렇다면 카드의 크기를 어떻게 조정합니까? 이제 우리는 문제를 단순화했으며 솔루션에 도달했습니다.

다른 콘텐츠 위에 콘텐츠를 올려야 한다는 생각은 잠시 잊고, 가장 키가 큰 자식만큼 키가 큰 부모라는 새로운 요구 사항에 집중하세요. 그건 쉽습니다! 열을 사용하여 부모가 가장 큰 자식의 높이로 확장되도록 할 수 있습니다. 그런 다음, 아이들을 정렬하기 위해 약간의 교활함을 사용하면 됩니다.

  1. 자식을 부모와 같은 너비로 설정
  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의 "[Magic Flip Cards 3: 고정 수평 오버플로에 의한 수직 크기 조정](https://codepen.io/smashingmag/pen/ExjYvjP)" 펜 참조)

고정 수평 오버플로에 의한 수직 크기 조정(Dan Halliday의 "Magic Flip Cards 3: 고정 수평 오버플로에 의한 수직 크기 조정" 펜 참조)

이 접근 방식이 명백해 보인다면 생각하기 전에 정말 끔찍한 아이디어를 겪으면서 많은 시간을 보냈다는 것을 안심하십시오. 처음에는 카드를 올바른 크기로 확장하기 위해 앞면 내부에 뒷면 텍스트의 숨겨진 복제 버전을 인쇄할 계획이었습니다. 열 오버플로를 사용할 생각을 했을 때 원래 overflow:hidden 을 사용하여 오른쪽 열을 자르고 호버가 시작된 마지막 순간에만 변환했습니다. 처음부터 opacity 또는 backface-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의 Pen "[Magic Flip Cards 4: The Complete Solution](https://codepen.io/smashingmag/pen/xxGKLZO)" 참조)

완전한 매직 플립 카드 솔루션(Dan Halliday의 Pen "Magic Flip Cards 4: The Complete Solution" 참조)

주의 사항이 있습니까?

이 솔루션은 일반적으로 잘 작동하지만 몇 가지 주의 사항을 염두에 두어야 합니다.

  • 카드는 그리드 레이아웃이나 너비가 콘텐츠에 종속되지 않는 다른 컨텍스트에 있어야 합니다.
  • 카드에는 애니메이션 중에 호버 영역이 변경되지 않도록 일종의 콘텐츠 래퍼( 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); } }

마지막으로, 이제 카드가 콘텐츠에 맞게 자동으로 크기가 조정되므로 전면 및 후면 컨테이너 내부에서 원하는 정렬 및 간격 기술을 거의 사용할 수 있다는 점을 잊지 마십시오. 플렉스 정렬을 사용하여 제목을 가운데에 맞추고 패딩을 추가하고 카드 내부에 다른 그리드를 넣을 수도 있습니다. 이것은 콘텐츠에 따라 확장되는 좋은 레이아웃 솔루션의 장점입니다. 즉, 자녀와 부모의 결합이 감소하고 한 번에 한 가지에만 집중할 수 있는 모듈성이 있습니다.

 .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 기술이 유용하기를 바랍니다! 배율 효과 또는 간단한 크로스 페이드와 같은 애니메이션 변형을 시도해 보는 것은 어떻습니까? 이 기술은 카드 폼 팩터에만 국한되지 않습니다. 수직 크기 조정에 대한 책임이 둘 이상의 요소에 속하는 모든 곳에서 사용할 수 있습니다. 캡션이 겹친 큰 사진이 포함된 잡지 웹사이트를 상상해 보십시오. 이 웹사이트를 사용하여 가로 세로 비율이 긴 이미지와 긴 동적 텍스트를 모두 수용할 수 있습니다.

무엇보다 고정된 크기와 위치에서만 작동하는 것처럼 보이는 디자인을 구현할 수 있는 방법이 없을까를 곰곰이 생각해보는 시간을 가질 때의 이점을 기억하세요. 종종 문제가 처음에 아무리 까다로워 보일지라도 모든 요구 사항을 기록하고 최소한의 테스트 케이스를 만드는 데 시간을 들이고 체계적으로 단계별로 진행하는 것이 항상 최선의 방법입니다.