AspectRatioBox#
child 를 고정 width:height 비율(ratio)로 제약하는 컨테이너입니다. Flutter AspectRatio
위젯과 동일하며, Web 에서는 padding-top 퍼센트 트릭 + position: relative + 절대 배치 콘텐츠 레이어로 같은 의미를 재현합니다. 이미지·미디어 임베드를 반응형으로 유지할 때 씁니다.
Live Preview#
class AspectRatioBoxDefaultExample extends StatelessComponent {
const AspectRatioBoxDefaultExample({super.key});
@override
Component build(BuildContext context) {
return div(
styles: Styles(raw: {'width': '280px', 'max-width': '100%'}),
[
AspectRatioBox(
ratio: 16 / 9,
child: Card(
child: div(
classes: 'flex items-center justify-center w-full h-full',
[Text('16 : 9').titleMedium],
),
),
),
],
);
}
}
class AspectRatioBoxDefaultExample extends StatelessWidget {
const AspectRatioBoxDefaultExample({super.key});
@override
Widget build(BuildContext context) {
return SizedBox(
width: 280,
child: AspectRatioBox(
ratio: 16 / 9,
child: Card(
child: Center(child: Text('16 : 9').titleMedium),
),
),
);
}
}
사용법#
// Flutter / Web 동일
AspectRatioBox(
ratio: 16 / 9,
child: Card(child: Center(child: Text('16 : 9').titleMedium)),
)
Props#
| 파라미터 | 타입 | 기본값 | 설명 |
|---|---|---|---|
child |
Widget / Component |
required | 비율-제약 박스 안에 배치되는 콘텐츠 |
ratio |
double |
required |
width / height 비율 (
16 / 9
등). 유한 양수여야 하며, 비정상 값은
CoreAspectRatioBoxStyle.defaultRatio
(기본
1.0
)로 폴백
|
너비는 부모가 정합니다 —
AspectRatioBox는 그 너비에서ratio에 맞는 높이를 산출합니다(또는 그 반대). 위 프리뷰는 280px 너비 안에서 16:9 박스를 보여줍니다.
스타일 시스템 (Style System)#
CoreAspectRatioBoxStyle 필드#
| 필드 | 타입 | 설명 |
|---|---|---|
defaultRatio |
double? |
Project-level fallback ratio (
width / height
) when the widget caller supplies a value that is not strictly positive.
null
defers to [defaultDefaultRatio] (square).
|
사용 가이드라인 (Usage Guidelines)#
✅ Do#
유한하고 양수인 ratio 를 명시적으로 전달
AspectRatioBox(
ratio: 16 / 9,
child: Image.network(url),
)
ratio 는 > 0 인 유한 값이어야 하며, 16 / 9 같은 리터럴 나눗셈으로 넘기면 의도한 비율이 그대로 유지됩니다.
❌ Don't#
계산된 값을 검증 없이 ratio 로 넘기지 않기
// ❌ height 가 0이면 무한대, width 가 0이면 0이 되는 값을 그대로 사용
AspectRatioBox(
ratio: width / height,
child: media,
)
비정상 값(0, 음수, 무한대)은 에러를 던지지 않고 CoreAspectRatioBoxStyle.defaultRatio(기본 1.0, 정사각형)로 조용히 폴백됩니다 — 의도한 비율이 아닌 정사각형 박스가 그려지는데도 원인을 알아채기 어렵습니다.
접근성 (Accessibility)#
역할 / Semantics#
양쪽 플랫폼 모두 아무 역할도 내보내지 않습니다. Flutter 는 AspectRatio 를 그대로 반환하며 Semantics
를 붙이지 않고, Web 은 비율을 지탱하는 spacer <div> 와 콘텐츠 <div> 를 감싼 <div>
를 그릴 뿐 role 이나 aria-* 를 설정하지 않습니다. 보조기술 입장에서 이 컴포넌트는 통과 지점이며, child
가 알리는 내용이 곧 전부입니다.
키보드#
없습니다. 양쪽 모두 키 핸들러가 없습니다.
포커스#
없습니다. 포커스를 받지 않고(Flutter FocusNode 없음 / Web tabindex 없음), 포커스 링을 그리지 않으며, 포커스를 가두거나 되돌리지 않습니다.
스크린 리더#
child 의 announcement 가 전부입니다. Web 의 spacer <div> 는 자식이 없어 읽을 텍스트를 만들지 않습니다 —
aria-hidden 이 붙어 있지는 않지만 비어 있어 결과적으로 조용합니다.
알려진 제약#
-
이름이나 역할이 필요하면 소비자가 직접 붙여야 합니다. Web 은
attributespassthrough 로role/aria-label을 넣을 수 있습니다. -
Flutter 생성자에는
attributes도semanticsLabel도 없어, 같은 일을 하려면 호출부에서AspectRatioBox를 자신의Semantics로 감싸야 합니다. 이 비대칭은 현재 코드 그대로입니다.
모든 컴포넌트에 공통으로 적용되는 축은 전역 접근성 축에 있습니다.