Skip to content
Kappa
Aspect Ratio
@dicehub/kappav0.4.2

Aspect Ratio

Keeps media and content inside a predictable width-to-height ratio.

Astronaut helmet with a reflective visor
<script setup>
import { AspectRatio } from "@dicehub/kappa/components/aspect-ratio";
</script>

<template>
  <AspectRatio :ratio="16 / 9" class="ratio-box">
    <img
      src="/illustrations/aspect-ratio-astronaut.webp"
      alt="Astronaut helmet with a reflective visor"
      class="ratio-box__image"
    />
  </AspectRatio>
</template>

<style scoped>
.ratio-box { inline-size: min(100%, 34rem); overflow: hidden; border: 1px solid var(--kappa-line); border-radius: 0.75rem; background: var(--kappa-tint); }
.ratio-box__image { display: block; inline-size: 100%; block-size: 100%; object-fit: cover; }
</style>

Installation

Aspect Ratio is part of the main Kappa package. It uses the native CSSaspect-ratio property and adds no runtime dependency beyond Vue.

Barrel

import { AspectRatio } from "@dicehub/kappa";

Granular

import { AspectRatio } from "@dicehub/kappa/components/aspect-ratio";

Usage

Pass a positive ratio as width divided by height. Give the child a full width and height when it is media, then use object-fit: cover or another content policy that matches the surface.

Astronaut helmet with a reflective visor
<script setup>
import { AspectRatio } from "@dicehub/kappa/components/aspect-ratio";
</script>

<template>
  <AspectRatio :ratio="4 / 3" class="ratio-box">
    <img
      src="/illustrations/aspect-ratio-astronaut.webp"
      alt="Astronaut helmet with a reflective visor"
      class="ratio-box__image"
    />
  </AspectRatio>
</template>

<style scoped>
.ratio-box { inline-size: min(100%, 34rem); overflow: hidden; border: 1px solid var(--kappa-line); border-radius: 0.75rem; background: var(--kappa-tint); }
.ratio-box__image { display: block; inline-size: 100%; block-size: 100%; object-fit: cover; }
</style>

Composition

Rendered structure
AspectRatio <div style="aspect-ratio">
└── default slot

The single ratio prop sets the native CSS aspect-ratio value. Ark UI Vue has no matching primitive, so Kappa keeps this layout helper native and unopinionated.

Examples

Square

Use :ratio="1 / 1" for avatars, thumbnails, and tile-based content.

Astronaut helmet with a reflective visor
<script setup>
import { AspectRatio } from "@dicehub/kappa/components/aspect-ratio";
</script>

<template>
  <AspectRatio :ratio="1 / 1" class="ratio-box ratio-box--square">
    <img
      src="/illustrations/aspect-ratio-astronaut.webp"
      alt="Astronaut helmet with a reflective visor"
      class="ratio-box__image"
    />
  </AspectRatio>
</template>

<style scoped>
.ratio-box { inline-size: min(100%, 34rem); overflow: hidden; border: 1px solid var(--kappa-line); border-radius: 0.75rem; background: var(--kappa-tint); }
.ratio-box--square { max-inline-size: 16rem; }
.ratio-box__image { display: block; inline-size: 100%; block-size: 100%; object-fit: cover; }
</style>

Portrait

Use :ratio="9 / 16" for posters and mobile-oriented media.

Astronaut helmet with a reflective visor
<script setup>
import { AspectRatio } from "@dicehub/kappa/components/aspect-ratio";
</script>

<template>
  <AspectRatio :ratio="9 / 16" class="ratio-box ratio-box--portrait">
    <img
      src="/illustrations/aspect-ratio-astronaut.webp"
      alt="Astronaut helmet with a reflective visor"
      class="ratio-box__image"
    />
  </AspectRatio>
</template>

<style scoped>
.ratio-box { inline-size: min(100%, 34rem); overflow: hidden; border: 1px solid var(--kappa-line); border-radius: 0.75rem; background: var(--kappa-tint); }
.ratio-box--portrait { max-inline-size: 12rem; }
.ratio-box__image { display: block; inline-size: 100%; block-size: 100%; object-fit: cover; }
</style>

Custom Ratio

Use any positive finite number when a standard media ratio does not fit the content.

Astronaut helmet with a reflective visor
<script setup>
import { AspectRatio } from "@dicehub/kappa/components/aspect-ratio";
</script>

<template>
  <AspectRatio :ratio="3 / 2" class="ratio-box">
    <img
      src="/illustrations/aspect-ratio-astronaut.webp"
      alt="Astronaut helmet with a reflective visor"
      class="ratio-box__image"
    />
  </AspectRatio>
</template>

<style scoped>
.ratio-box { inline-size: min(100%, 34rem); overflow: hidden; border: 1px solid var(--kappa-line); border-radius: 0.75rem; background: var(--kappa-tint); }
.ratio-box__image { display: block; inline-size: 100%; block-size: 100%; object-fit: cover; }
</style>

Accessibility

  • Aspect Ratio is a layout wrapper. Give images meaningful alternative text.
  • Keep interactive controls keyboard reachable inside the ratio root.
  • Do not use the wrapper as a replacement for a heading or landmark.
  • Choose a content policy for overflow. For media, object-fit: cover is often appropriate.
  • Invalid or missing runtime values resolve to a square to keep a stable layout.

API Reference

AspectRatio

Renders a native div. Native attributes, data attributes, styles, classes, and events pass to the root.

PropTypeDefaultDescription
rationumber— (required)Width divided by height. Invalid runtime values resolve to 1 (square).

Slots

SlotDescription
defaultContent rendered inside the ratio-constrained root.

Data Slots

SlotElementDescription
aspect-ratiodivNative ratio-constrained root.

Data Attributes

AttributeValueDescription
data-ratiopositive finite numberResolved ratio used by the component, including the invalid-value fallback.

Exports

ExportDescription
AspectRatioNative CSS aspect-ratio wrapper.
AspectRatioPropsPublic ratio prop and native attribute contract.
AspectRatioSlotsDefault content slot contract.
ASPECT_RATIO_DEFAULT_RATIOSquare runtime fallback for invalid ratios.
isAspectRatioPositive finite ratio type guard.
resolveAspectRatioSafe ratio resolver with a square fallback.