Aspect Ratio
Container that enforces a consistent width-to-height ratio on its content, ideal for images, videos, and embedded media.
<arc-aspect-ratio> Overview
>
AspectRatio is a layout primitive that constrains its children to a specified width-to-height proportion using the CSS `aspect-ratio` property. Pass a ratio string like `"16/9"`, `"4/3"`, or `"1/1"` and the container will maintain that shape regardless of the available width. Slotted children (images, videos, iframes) are automatically sized to fill the container with `object-fit: cover`, ensuring no letterboxing or stretching.
This component solves the common problem of content layout shift (CLS) caused by media loading. By reserving the exact space an image or video will occupy before it loads, AspectRatio prevents the jarring page reflows that hurt both user experience and Core Web Vitals scores. The container's width is always 100% of its parent, and the height is derived from the ratio, so it works seamlessly in fluid grid layouts.
The ratio prop accepts any valid `W/H` format including decimal values like `"2.35/1"` for cinematic widescreen. If an invalid format is provided, the component falls back to `16/9`. The container applies the theme's medium border radius and clips overflow, so rounded corners on media come free without additional styling.Guidelines
When to use
- Use AspectRatio around images and videos to prevent layout shift during page load
- Choose standard ratios that match your media: `16/9` for video, `4/3` for photos, `1/1` for avatars or thumbnails
- Place AspectRatio inside grid or flex containers where the width is determined by the layout
- Use decimal ratios like `2.35/1` for cinematic or ultrawide content when needed
- Combine with lazy loading on images for optimal performance — the space is reserved before the image loads
When not to use
- Do not use AspectRatio when the content has its own intrinsic dimensions and layout shift is not a concern
- Do not place text-heavy content inside AspectRatio — it clips overflow and does not scroll
- Do not set both a fixed height and AspectRatio on the same element — they will conflict
- Do not use ratio values with zero in the denominator (e.g. `16/0`) — the component falls back to 16/9
- Avoid nesting multiple AspectRatio components — the inner one will be constrained by both ratios unpredictably
Features
- Enforces a consistent aspect ratio using the CSS `aspect-ratio` property with a `W/H` string prop
- Slotted children automatically sized to fill with `width: 100%`, `height: 100%`, and `object-fit: cover`
- Prevents content layout shift (CLS) by reserving space before media loads
- Supports any valid ratio including standard formats (`16/9`, `4/3`, `1/1`) and decimals (`2.35/1`)
- Falls back to `16/9` if the ratio string is invalid or malformed
- Applies `border-radius: var(--radius-md)` with overflow clipping for rounded media corners
- Full-width container that fills its parent, making it ideal for responsive grid cells
- Lightweight wrapper with no JavaScript interaction — purely CSS-driven layout
Preview
16 / 9
Usage
<arc-aspect-ratio ratio="16/9">
<img src="/hero.jpg" alt="Hero banner" />
</arc-aspect-ratio>
<!-- Square thumbnail -->
<arc-aspect-ratio ratio="1/1">
<img src="/avatar.jpg" alt="User avatar" />
</arc-aspect-ratio> import { AspectRatio } from '@arclux/arc-ui-react';
export default function Example() {
return (
<>
<AspectRatio ratio="16/9">
<img src="/hero.jpg" alt="Hero banner" />
</AspectRatio>
{/* Square thumbnail */}
<AspectRatio ratio="1/1">
<img src="/avatar.jpg" alt="User avatar" />
</AspectRatio>
</>
);
} <script setup>
import { AspectRatio } from '@arclux/arc-ui-vue';
</script>
<template>
<AspectRatio ratio="16/9">
<img src="/hero.jpg" alt="Hero banner" />
</AspectRatio>
<!-- Square thumbnail -->
<AspectRatio ratio="1/1">
<img src="/avatar.jpg" alt="User avatar" />
</AspectRatio>
</template> <script>
import { AspectRatio } from '@arclux/arc-ui-svelte';
</script>
<AspectRatio ratio="16/9">
<img src="/hero.jpg" alt="Hero banner" />
</AspectRatio>
<!-- Square thumbnail -->
<AspectRatio ratio="1/1">
<img src="/avatar.jpg" alt="User avatar" />
</AspectRatio> import { Component } from '@angular/core';
import { AspectRatio } from '@arclux/arc-ui-angular';
@Component({
imports: [AspectRatio],
template: `
<arc-aspect-ratio ratio="16/9">
<img src="/hero.jpg" alt="Hero banner" />
</arc-aspect-ratio>
<!-- Square thumbnail -->
<arc-aspect-ratio ratio="1/1">
<img src="/avatar.jpg" alt="User avatar" />
</arc-aspect-ratio>
`,
})
export class MyComponent {} import { AspectRatio } from '@arclux/arc-ui-solid';
export default function Example() {
return (
<>
<AspectRatio ratio="16/9">
<img src="/hero.jpg" alt="Hero banner" />
</AspectRatio>
{/* Square thumbnail */}
<AspectRatio ratio="1/1">
<img src="/avatar.jpg" alt="User avatar" />
</AspectRatio>
</>
);
} import { AspectRatio } from '@arclux/arc-ui-preact';
export default function Example() {
return (
<>
<AspectRatio ratio="16/9">
<img src="/hero.jpg" alt="Hero banner" />
</AspectRatio>
{/* Square thumbnail */}
<AspectRatio ratio="1/1">
<img src="/avatar.jpg" alt="User avatar" />
</AspectRatio>
</>
);
} <!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-aspect-ratio — requires aspect-ratio.css + tokens.css (or arc-ui.css) -->
<div class="arc-aspect-ratio">
<div
class="aspect-ratio"
style="aspect-ratio: _aspect Ratio;"
>
<div class="aspect-ratio__inner">
AspectRatio
</div>
</div>
</div> <!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-aspect-ratio — self-contained, no external CSS needed -->
<div class="arc-aspect-ratio" style="display: block">
<div
style="position: relative; width: 100%; overflow: hidden; border-radius: 10px"
style="aspect-ratio: _aspect Ratio;"
>
<div style="width: 100%; height: 100%">
AspectRatio
</div>
</div>
</div> API
-
ratiostring'16/9' - Aspect ratio as a `W/H` string. Supports integers and decimals. Falls back to `16/9` if invalid.