Groo Design

Aspect Ratio

폭이 정해지면 비율로 높이가 정해지는 상자 하나. 모서리 · 윤곽 · 바탕 · 불러오는 동안 · 대체 그림이 없고, 자식 하나가 상자를 채운다. 동영상 · 지도 · 바깥 페이지처럼 그림이 아니면서 비율만 지키면 되는 자리에 쓴다 — 사진 · 카드 그림 · 규정 그림은 Image Frame 이다(그 안의 비율 상자가 이것이다).

구조는 당근 SEED Aspect Ratio(Apache-2.0)를 따른다 — "가로(width)가 정해지면 비율에 따라 세로(height)가 자동으로 결정되는 레이아웃 컨테이너", 기본 4:3, 자식 하나, 모서리 0. SEED 에는 이 부품의 디자인 문서가 없고 React 문서뿐이다. 비율은 Image Frame 과 같은 여덟 가지다 — 맨 아래 "SEED 와 다른 점"(2026-10-04 사용자 결정). 옛 Aspect Ratio(Radix · 권장 16:9 · 4:3 · 1:1 · 3:4 · 21:9 · 2:1 · 자식이 모서리 · 바탕을 맡음)를 대신한다.

수치 원본은 aspect-ratio.yaml이다. 수치 표 자리([표: …])와 그림 자리([그림: …])는 사이트가 그 파일로 그린다 — GitHub 에서는 그 파일 · 그림 코드로 가는 링크로 보인다.

4:3 — 기본지도 미리보기
16:9안내 동영상
card 1.586카드 촬영 — 카드 모양 자리
라이트
4:3 — 기본지도 미리보기
16:9안내 동영상
card 1.586카드 촬영 — 카드 모양 자리
다크
비율 상자 — 4:3 기본 · 16:9 동영상 · 카드 1.586 — 라이트 · 다크

직접 골라 보기

비율과 부모 폭을 고르면 스펙대로 그린 상자와 그 코드가 바뀐다. 폭을 바꾸면 높이가 비율대로 따라간다.

부모 폭 312 → 높이 234.0(폭 ÷ 4 / 3) · 모서리 0 · 바탕 없음(점선은 상자의 자리)
비율 ratio
자식
모드

상자는 모서리 · 바탕 · 윤곽이 없다 — 자식 하나가 상자를 채운다. 그림(사진 · 카드 그림)은 Image Frame 이다.

import { AspectRatio } from "@/components/ui/aspect-ratio"

<AspectRatio>
  <video src={guide.url} controls preload="metadata" className="size-full object-cover" aria-label="자산 연결 안내 동영상" />
</AspectRatio>

Anatomy

ⓐ Root — 폭은 부모, 높이는 폭 ÷ 비율ⓑ Child — 자식 하나가 상자를 채운다

16:9 상자(폭 320 → 높이 180.0). 모서리 · 바탕 · 윤곽이 없다 — 점선은 상자의 자리다

비율 상자와 그 상자를 채운 자식 하나
부위설명
ⓐ Root비율 상자 — 폭은 부모, 높이는 폭 ÷ 비율. 모서리 · 바탕이 없다.
ⓑ Child자식 하나 — 상자를 채운다. 동영상은 가운데를 남겨 자른다(cover).

부위

부위설명
root비율 상자 — 폭은 부모, 높이는 폭 ÷ 비율. 모서리 · 테두리 · 바탕이 없다
child자식 하나 — 상자를 채운다(absolute · inset 0). 동영상은 cover

Properties

Ratio

비율은 여덟 가지다 — SEED 의 일곱(1:1 · 2:1 · 16:9 · 4:3 · 6:7 · 4:5 · 2:3)과 카드 1.586. 기본은 4:3 이다. 이 밖의 비율(옛 3:4 · 21:9 · 황금비 같은 숫자)을 만들지 않는다 — 비율이 늘면 한 화면의 그림 · 상자가 제각각이 된다.

YAML 의 비율 값은 모두 "W / H" 글이다("1 / 1" · "16 / 9" · "1.586 / 1") — 브라우저가 계산값으로 쓰는 꼴(getComputedStyle 의 aspect-ratio)이라 검사기가 글 그대로 맞추고, 앱은 / 로 나눠 W ÷ H 를 쓴다.

1:1
1 / 1112 × 112.0정사각
2:1
2 / 1112 × 56.0넓은 띠
16:9
16 / 9112 × 63.0동영상
4:3
4 / 3(기본)112 × 84.0사진(기본)
6:7
6 / 7112 × 130.7조금 세로
4:5
4 / 5112 × 140.0세로
2:3
2 / 3112 × 168.0긴 세로
card
1.586 / 1112 × 70.6groo — 카드 모양 자리
같은 폭에 여덟 비율

비율

ratio비율설명
1:11 / 1정사각 — 지도 미리보기 · 정사각 동영상
2:12 / 1넓은 띠
16:916 / 9 — ≈ 1.78동영상 · 바깥 페이지(iframe)
4:3 (기본)4 / 3 — ≈ 1.33 — 기본(SEED)기본(SEED)
6:76 / 7 — ≈ 0.86조금 세로
4:54 / 5 — 0.8세로
2:32 / 3 — ≈ 0.67긴 세로
card1.586 / 1 — ISO 카드 85.6 × 53.98카드 1.586 — 카드 모양 자리(카드 그림이 아닌 것 — 카드 그림은 Image Frame)

공통

부위속성값비고
root너비부모 폭부모가 폭을 정한다 — 부모 폭이 0 이면 상자도 0
root높이폭 ÷ 비율웹 CSS aspect-ratio · 앱 AspectRatio — 내용이 오기 전에 자리를 잡는다
root모서리0px모서리가 없다 — 둥근 그림 틀은 Image Frame
root배경transparent바탕 · 테두리 · 그림자가 없다
root넘침hidden넘친 자식을 자른다
child자식 자리0pxabsolute — 상자를 채운다. 자식은 하나
child자식 맞춤coverimg · video — 가운데를 남겨 자른다(SEED). 지도 · iframe 은 상자 크기 그대로

State

상태는 enabled 하나다 — 상자일 뿐이라 누르지 않고 초점이 서지 않는다. 누르면 무언가 되는 자리는 감싼 버튼 · 링크가 상태를 가진다.

Guidelines

그림은 Image Frame, 그 밖이 Aspect Ratio

사진 · 카드 그림 · 규정 그림처럼 그림 파일을 보이는 자리는 Image Frame 이다 — 모서리(폭으로) · 투명 윤곽 · 불러오는 동안의 스켈레톤 · 대체 그림 · 그림 위 배지를 함께 가진다. Aspect Ratio 에 <img> 를 넣고 모서리 · 바탕을 손으로 두르면 그 넷이 화면마다 갈린다(지금 카드 그림 모서리가 12 · 6 · 4 · 8 로 갈린 까닭이다). Aspect Ratio 는 동영상 · 지도 · 바깥 페이지 · 차트처럼 비율만 지키면 되는 자리에 쓴다.

  • 데일리 플러스신용 · 신한카드
  • 트래블로그체크 · 하나카드
  • NH올원 Pay체크 · NH농협카드
이렇게 — 카드 그림은 Image Frame(폭으로 고른 모서리 · 윤곽 · 대체 그림), 동영상은 Aspect Ratio
  • 데일리 플러스신용 · 신한카드
  • 트래블로그체크 · 하나카드
  • NH올원 Pay체크 · NH농협카드
이렇게 하지 않는다 — Aspect Ratio 에 그림을 넣고 모서리를 손으로 둘렀다 — 줄마다 12 · 6 · 4, 윤곽 · 대체 그림이 없다
카드 그림은 Image Frame · 동영상은 Aspect Ratio — Aspect Ratio 에 그림을 넣고 모서리를 손으로 두른 화면

한 목록 · 격자는 한 비율

같은 목록 · 격자 안에서는 비율을 하나로 맞춘다 — 칸마다 비율이 다르면 줄 높이가 들쭉날쭉해진다. 한 화면 전체에 쓰는 비율의 수는 정하지 않는다 — 상세 위 16:9 · 아래 1:1 격자 · 카드 1.586 이 한 화면에 함께 날 수 있다.

사진 1사진 2사진 3사진 4
이렇게 — 한 격자는 4:3 하나 — 줄 높이가 고르다
사진 1사진 2사진 3사진 4
이렇게 하지 않는다 — 칸마다 1:1 · 16:9 · 4:5 · 2:1 — 줄 높이가 들쭉날쭉하다
한 격자는 한 비율 · 칸마다 다른 비율

코드

레시피 recipes/shadcn/components/ui/aspect-ratio.tsx 를 쓴다 — AspectRatio 는 ratio("1:1" · "2:1" · "16:9" · "4:3" · "6:7" · "4:5" · "2:3" · "card", 기본 "4:3")와 자식 하나를 받는다. 폭은 부모가 정하고, 그 밖은 div 속성이다. 앱은 AspectRatio(aspectRatio: …) 에 같은 여덟 값을 쓴다. 아래 미리보기는 스펙 값으로 그린 모습이다.

동영상 — 16:9

안내 동영상 16:9
import { AspectRatio } from "@/components/ui/aspect-ratio"

<AspectRatio ratio="16:9">
  <video src={guide.url} controls preload="metadata" className="size-full object-cover" aria-label="자산 연결 안내 동영상" />
</AspectRatio>

Behavior

인터랙션동작
부모 폭이 바뀜높이가 비율대로 다시 정해진다
내용이 오기 전상자가 먼저 자리를 잡는다 — 내용이 와도 줄이 밀리지 않는다
누르기 · 키보드없다 — 자식(동영상 · 지도)의 동작이다

Accessibility

기준검증
WCAG 1.1.1 Non-text Content상자는 역할 · 이름이 없다 — 자식이 말한다(동영상의 aria-label · 자막, 지도의 이름)
WCAG 1.4.10 Reflow부모 폭이 줄면 높이가 비율대로 줄어든다 ✓
WCAG 2.5.8 Target Size — Minimum(AA ≥ 24×24)해당 없음 — 누르지 않는다
WCAG 2.5.5 Target Size — Enhanced(AAA ≥ 44×44)해당 없음 — 누르지 않는다
ARIA없다(SEED 와 같다 — 자식이 말한다)

Do / Don't

✅ Do

  • 동영상 · 지도 · 바깥 페이지처럼 그림이 아닌 자리의 비율.
  • 여덟 비율 안에서 — 같은 목록 · 격자는 하나로.
  • 부모가 폭을 정한다.

❌ Don't

  • 사진 · 카드 그림을 Aspect Ratio 로 — 모서리 · 윤곽 · 대체 그림이 빠진다(Image Frame 이다).
  • 상자에 모서리 · 바탕 · 테두리를 손으로 두르기.
  • 3:4 · 21:9 · 임의의 숫자 비율.

Specification

aspect-ratio.yaml 의 규칙을 하나도 빼지 않고 조건마다 그린다 — 웹 · 앱이 Aspect Ratio 를 만들 때 이 값을 그대로 쓴다. 조건이 없는 Base 가 모든 조합에 걸리고, 뒤의 규칙이 앞의 같은 값을 덮는다.

Base

부위상태속성값
rootenabled높이height폭 ÷ 비율웹 CSS aspect-ratio · 앱 AspectRatio — 내용이 오기 전에 자리를 잡는다
너비width부모 폭부모가 폭을 정한다 — 부모 폭이 0 이면 상자도 0
모서리radius0px모서리가 없다 — 둥근 그림 틀은 Image Frame
배경backgroundtransparent바탕 · 테두리 · 그림자가 없다
넘침overflowhidden넘친 자식을 자른다
childenabled자식 맞춤objectFitcoverimg · video — 가운데를 남겨 자른다(SEED). 지도 · iframe 은 상자 크기 그대로
자식 자리inset0pxabsolute — 상자를 채운다. 자식은 하나

ratio=1:1

부위상태속성값
rootenabled비율aspectRatio1 / 1

ratio=2:1

부위상태속성값
rootenabled비율aspectRatio2 / 1

ratio=16:9

부위상태속성값
rootenabled비율aspectRatio16 / 9≈ 1.78

ratio=4:3

부위상태속성값
rootenabled비율aspectRatio4 / 3≈ 1.33 — 기본(SEED)

ratio=6:7

부위상태속성값
rootenabled비율aspectRatio6 / 7≈ 0.86

ratio=4:5

부위상태속성값
rootenabled비율aspectRatio4 / 50.8

ratio=2:3

부위상태속성값
rootenabled비율aspectRatio2 / 3≈ 0.67

ratio=card

부위상태속성값
rootenabled비율aspectRatio1.586 / 1ISO 카드 85.6 × 53.98

SEED 와 다른 점

  • 비율을 여덟 가지로 묶는다 — SEED React 는 아무 숫자나 받는다(Figma 의 Image Frame 은 일곱 가지다). groo 는 그 일곱에 카드 1.586 을 더해 Image Frame 과 같은 여덟 가지만 쓴다.
  • 그림에는 쓰지 않는다 — SEED 도 그림은 Image Frame 이지만 Aspect Ratio 예제에 <img> 를 넣는다. groo 는 그림을 모두 Image Frame 으로 그린다.

Migration notes

2026-10-22 — 한 목록 · 격자는 한 비율

"한 화면에 쓰는 비율은 한두 가지다"(31dbaa9 — 10-04 이미지 비교 페이지에 없다)를 걷고, 까닭(줄 높이가 들쭉날쭉)이 닿는 "같은 목록 · 격자 안에서는 하나로" 만 남겼다 — 한 화면 전체의 비율 수는 정하지 않는다(남은 규칙 R6). 사용자 결정 — https://claude.ai/artifact/Mag1tEv51MdQHdy1o8hY3L. 값 변경 없음.

2026-10-08 — 비율 값을 "W / H" 글 하나로

YAML 이 1 · 2 · 1.586 은 숫자로, 16 / 9 · 4 / 3 · 6 / 7 · 4 / 5 · 2 / 3 은 글로 읽혀(YAML 은 나누기를 하지 않는다) 제품 검사기가 여덟 중 숫자 셋만 쟀다(desk-front #428). 화면은 같았고 잃은 것은 검사뿐이다. 여덟 모두 브라우저 계산값과 같은 꼴의 글("1 / 1" · "2 / 1" · "16 / 9" · "4 / 3" · "6 / 7" · "4 / 5" · "2 / 3" · "1.586 / 1")로 적었다 — 검사기는 글 그대로 맞춘다(제품의 재는 법도 숫자 비교에서 글 비교로 바꾼다). 사용자 결정 — 비교 페이지 4.

2026-10-04 — SEED Aspect Ratio 로 다시 쓴다

사용자가 이미지 비교 페이지의 "따라오는 것" 에서 정했다 — 비율은 SEED 일곱 + 카드 1.586, 기본 4:3, 3:4 · 21:9 는 걷는다. 그림은 새로 둔 Image Frame 이 맡는다. 옛 스펙(Radix AspectRatio · 권장 비율 여섯 · 자식이 모서리 radius-md · 바탕 surface-input · object-fit 을 정함)은 aspect-ratio.history/v-pre-seed-image.* 다.

옛새
권장 16:9 · 4:3 · 1:1 · 3:4 · 21:9 · 2:1, 숫자 자유1:1 · 2:1 · 16:9 · 4:3 · 6:7 · 4:5 · 2:3 · 카드 1.586, 기본 4:3
이미지 · 카드 썸네일 · 아바타 격자의 비율그림은 Image Frame, 사람은 Avatar — 이 부품은 그림이 아닌 자리만
자식이 모서리 8 · 바탕 · fit 을 정함상자는 모서리 0 · 바탕 없음, 동영상은 cover

제품은 앱 적용 단계에서 옮긴다(2026-10-03 조사).

  • groo 의 이 부품을 쓰는 곳이 없다 — Desk 웹은 CSS aspect-ratio 를 손으로 쓴다(카드 그림 틀 pages/card-benefit/ui/CardBenefitPage.tsx:191-226 · CardBenefitDetailDialog.tsx:92-101, 스켈레톤 셋, 통계의 정사각 pages/stats/ui/StatsPage.tsx:1790). 앱은 Flutter AspectRatio 를 여덟 곳에 쓴다 — 카드 그림(features/card/presentation/card_benefit_detail_sheet.dart:308 · 625 · 진입 없는 card_detail_screen.dart:64 · 261), 별숲 그림(features/constellation/presentation/my_sky_card.dart:145 · night_sky_hero.dart:119), 통계(features/stats/presentation/stats_screen.dart:926 · 1709). 카드 그림은 Image Frame 으로, 그림이 아닌 통계 · 나의 별숲 자리(1:1)는 이 부품의 여덟 비율로 옮긴다. 별숲 히어로 안의 별자리 상자(1.45)는 그림 안 좌표 상자라 이 부품의 대상이 아니다 — 그림이 정한다(바깥 히어로는 높이 168 / 208 고정, 2026-10-21 사용자 결정 — 03-G 결정 6 A — 4:3 으로 맞추거나 아홉째 비율을 더하지 않는다).
  • 옛 스펙의 "기존 aspect-ratio.tsx 는 Radix 그대로" 는 레시피 이야기였다 — 제품에는 그 부품이 없었다.

이 페이지