Skip to content
Ndop UI

Aspect Ratio

Displays content within a chosen width-to-height ratio.

  • v1.0.0
  • SSR
  • Zoneless
  • 0.4 kB gzip
import { Component } from '@angular/core';
import { AspectRatio } from '@/ui/aspect-ratio/aspect-ratio';

/** An illustration kept at 16:9 whatever the width. */
@Component({
  selector: 'example-aspect-ratio-demo',
  imports: [AspectRatio],
  template: `
    <div
      ndAspectRatio
      [ratio]="16 / 9"
      class="w-full max-w-md overflow-hidden rounded-lg bg-muted"
    >
      <svg
        viewBox="0 0 160 90"
        role="img"
        aria-label="Hills under a setting sun"
        class="size-full"
      >
        <circle cx="112" cy="34" r="14" class="fill-primary/30" />
        <path d="M0 70 Q40 40 80 62 T160 52 V90 H0Z" class="fill-primary/20" />
        <path d="M0 80 Q50 58 100 76 T160 70 V90 H0Z" class="fill-primary/40" />
      </svg>
    </div>
  `,
})
export class AspectRatioDemoExample {}

Aspect Ratio keeps its content at a width-to-height ratio as the width changes, for images, video and maps. It sets the CSS aspect-ratio property from ratio, such as 16 / 9. Size the media inside to fill it.

Installation

npx @ndop/cli add aspect-ratio

Usage

import { AspectRatio } from '@/ui/aspect-ratio/aspect-ratio';
<div
  ndAspectRatio
  [ratio]="16 / 9"
  class="w-full max-w-md overflow-hidden rounded-lg bg-muted"
>
  <svg
    viewBox="0 0 160 90"
    role="img"
    aria-label="Hills under a setting sun"
    class="size-full"
  >
    <circle cx="112" cy="34" r="14" class="fill-primary/30" />
    <path d="M0 70 Q40 40 80 62 T160 52 V90 H0Z" class="fill-primary/20" />
    <path d="M0 80 Q50 58 100 76 T160 70 V90 H0Z" class="fill-primary/40" />
  </svg>
</div>

Examples

Aspect Ratio square

Square tiles in a grid.

  • Jan
  • Feb
  • Mar
  • Apr
  • May
  • Jun
import { Component } from '@angular/core';
import { AspectRatio } from '@/ui/aspect-ratio/aspect-ratio';

/** Square tiles in a grid that stay square as the grid resizes. */
@Component({
  selector: 'example-aspect-ratio-square',
  imports: [AspectRatio],
  template: `
    <ul class="grid w-full max-w-md grid-cols-3 gap-2">
      @for (tile of tiles; track tile) {
        <li
          ndAspectRatio
          class="grid place-items-center rounded-md bg-muted text-sm font-medium"
        >
          {{ tile }}
        </li>
      }
    </ul>
  `,
})
export class AspectRatioSquareExample {
  protected readonly tiles = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'];
}

Accessibility

Aspect Ratio has no keyboard interaction or focus handling of its own; it keeps the semantics of the element it's on.

API reference

AspectRatio

[ndAspectRatio]

Keeps its content at a width-to-height ratio, with the CSS aspect-ratio property. Put an image or media inside, sized to fill it.

AspectRatio binding Type Default
[ratio]
Width divided by height, such as 16 / 9.
number1
[class]
Extra classes, merged last so they win.
string''
Data attribute Values
data-slotaspect-ratio

Agent notes

Do

  • Put an img or video inside with class="size-full object-cover".
  • Give images a meaningful alt, or alt="" when they're decorative.
  • Use it to stop the page shifting while media loads.

Don't

  • Don't put text that can grow inside it; it will overflow.
  • Don't use it for things with a natural size, such as icons.