Skip to content
Navigation

Aspect Ratio

A box locked to a ratio computed at runtime. For a ratio you know while writing the code, use Tailwind's aspect-* utilities instead — they are better.

Added 14 October 2026

React

Codecomponents/react/aspect-ratio-demo.tsx
import {AspectRatio} from '@stroeer-labs/design-library/react';

// Ratios a booking UI actually deals with: an ad format's canvas is width/height from data, which is the
// only case this component is for. A static ratio should just use Tailwind's `aspect-video` / `aspect-[4/3]`.
const formats = [
    {name: 'Billboard', ratio: 3456 / 1152},
    {name: 'City Light', ratio: 1152 / 1728},
    {name: 'Mobile banner', ratio: 320 / 50},
];

export function AspectRatioDemo() {
    return (
        <div className="space-y-6">
            <div className="space-y-2">
                <p className="text-xs font-medium text-muted-foreground">Runtime ratios from ad-format dimensions</p>
                <div className="grid max-w-md gap-4">
                    {formats.map((format) => (
                        <div key={format.name} className="space-y-1.5">
                            <p className="font-mono text-xs tabular-nums text-muted-foreground">
                                {format.name} — {format.ratio.toFixed(2)}
                            </p>
                            <AspectRatio
                                ratio={format.ratio}
                                className="flex items-center justify-center rounded-md border border-border bg-muted text-xs text-muted-foreground"
                            >
                                {format.name}
                            </AspectRatio>
                        </div>
                    ))}
                </div>
            </div>
        </div>
    );
}

Angular

Codecomponents/angular/aspect-ratio-demo.ts
import {Component} from '@angular/core';
import {HlmAspectRatioImports} from '@stroeer-labs/design-library/angular';

// Mirrors the React demo — see it for why a static ratio should use Tailwind's `aspect-*` instead.
@Component({
    selector: 'dl-aspect-ratio-demo',
    standalone: true,
    imports: [HlmAspectRatioImports],
    template: `
        <div class="space-y-6">
            <div class="space-y-2">
                <p class="text-xs font-medium text-muted-foreground">Runtime ratios from ad-format dimensions</p>
                <div class="grid max-w-md gap-4">
                    @for (format of formats; track format.name) {
                        <div class="space-y-1.5">
                            <p class="font-mono text-xs tabular-nums text-muted-foreground">
                                {{ format.name }} — {{ format.ratio.toFixed(2) }}
                            </p>
                            <hlm-aspect-ratio
                                [ratio]="format.ratio"
                                class="flex items-center justify-center rounded-md border border-border bg-muted text-xs text-muted-foreground"
                            >
                                {{ format.name }}
                            </hlm-aspect-ratio>
                        </div>
                    }
                </div>
            </div>
        </div>
    `,
})
export class AspectRatioDemoComponent {
    protected readonly formats = [
        {name: 'Billboard', ratio: 3456 / 1152},
        {name: 'City Light', ratio: 1152 / 1728},
        {name: 'Mobile banner', ratio: 320 / 50},
    ];
}