AspectRatioBox | CoUI
LogoCoUI

AspectRatioBox

child 를 고정 width:height 비율 박스로 제약하는 컨테이너

AspectRatioBox#

child 를 고정 width:height 비율(ratio)로 제약하는 컨테이너입니다. Flutter AspectRatio 위젯과 동일하며, Web 에서는 padding-top 퍼센트 트릭 + position: relative + 절대 배치 콘텐츠 레이어로 같은 의미를 재현합니다. 이미지·미디어 임베드를 반응형으로 유지할 때 씁니다.

Live Preview#

Web
16 : 9
Flutter
Loading Flutter...
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 은 attributes passthrough 로 role / aria-label 을 넣을 수 있습니다.
  • Flutter 생성자에는 attributessemanticsLabel 도 없어, 같은 일을 하려면 호출부에서 AspectRatioBox 를 자신의 Semantics 로 감싸야 합니다. 이 비대칭은 현재 코드 그대로입니다.

모든 컴포넌트에 공통으로 적용되는 축은 전역 접근성 축에 있습니다.