Aspect Ratio
Headless Aspect Ratio; covers CSS aspect-ratio, Radix UI AspectRatio, Reka UI AspectRatio.
|
|
| Package |
@vizejs/ui/aspect-ratio |
| Maturity |
stable |
| Own the source |
vize lib pull aspect-ratio |
| Requires |
— |
| Aliases |
aspect ratio, intrinsic ratio, responsive media box |
| Covers |
CSS aspect-ratio, Radix UI AspectRatio, Reka UI AspectRatio |
Minimal setup
Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).
vp install @vizejs/ui
Add the public import below to <script setup lang="ts">. Components provide behavior without styles; the preview uses optional Paper styles.
import { AspectRatio } from "@vizejs/ui/aspect-ratio";
Or copy the source into your project with vize lib pull aspect-ratio (see Source Distribution).
Try it
This is the basic example maintained with the component source, using the public package imports. The preview adds the optional Paper styles.
Open the interactive example · Styling these components
Copy the example
<!-- Widescreen 16:9 frame that keeps a video poster at a stable ratio while it loads. -->
<script setup lang="ts">
import { AspectRatio } from "@vizejs/ui/aspect-ratio";
</script>
<template>
<figure>
<AspectRatio :ratio="16 / 9">
<img
src="https://example.com/media/keynote-poster.jpg"
alt="Keynote stage before the opening talk"
width="1600"
height="900"
/>
</AspectRatio>
<figcaption>Opening keynote</figcaption>
</figure>
</template>
API
AspectRatio
Source: src/families/layout/aspect-ratio/aspect-ratio.vue
Props
| Prop |
Type |
Default |
Description |
as |
PrimitiveAs |
"div" |
Native element, custom element, or component to render. |
ratio |
number |
1 |
Positive finite width divided by height. Invalid values fall back to 1. |
Slots
| Slot |
Slot props |
Description |
default |
AspectRatioSlotState |
Renders the box contents with the normalized ratio state. |
Exposed
| Member |
Type |
Description |
element |
AspectRatioElement | null |
Rendered host element or component instance. |
ratio |
number |
Ratio used for the rendered box after validation. |
invalid |
boolean |
Whether the provided ratio fell back to the default square ratio. |
Behavior
Normative state x input -> outcome table for aspect-ratio.vue (@vizejs/ui/aspect-ratio).
Every row is proven by the named mounted-DOM test, SSR test, runtime
conformance check, or validation script. A row without a passing test or check
is a contract violation.
| # |
State |
Input |
Outcome |
Proven by |
| A1 |
default |
render |
renders <div data-vize-ui="aspect-ratio">, data-state="valid", and a square ratio |
renders a square headless host by default |
| A2 |
valid ratio |
render |
publishes the normalized ratio to data-vize-aspect-ratio and --vize-ui-aspect-ratio |
publishes the requested ratio through stable data and style hooks |
| A3 |
invalid ratio |
render |
falls back to ratio 1 and data-state="fallback" for non-positive or non-finite values |
falls back deliberately for non-positive and non-finite ratios |
| A4 |
as="section" |
render |
renders the requested semantic host and passes normalized ratio and invalid to the slot |
renders a semantic host and exposes normalized slot state |
| A5 |
any |
expose |
exposes element, normalized ratio, and invalid |
exposes the rendered element and live normalized ratio state |
| A6 |
SSR valid ratio |
isolated requests |
renders byte-identical intrinsic-ratio markup with the same data and style hooks |
renders byte-identical intrinsic ratio markup across isolated SSR requests |
| A7 |
SSR invalid ratio |
render |
renders fallback ratio markup without request-global state |
renders fallback ratio markup for invalid server input |
| A8 |
DOM/SSR/Vapor |
compile |
authored SFC compiles in every renderer lane without warnings or fallback |
scripts/check-renderers.ts |
| A9 |
root/subpath |
consumer bundle |
root and subpath consumers retain only AspectRatio, emit no CSS, and stay within gzip budget |
scripts/check-tree-shaking.mjs |
Props
| Prop |
Type |
Purpose |
Default |
as |
PrimitiveAs |
Native element, custom element, or component rendered as host. |
"div" |
ratio |
number |
Positive finite width divided by height. Invalid values use 1. |
1 |
Slots
| Slot |
Props |
Purpose |
Default |
default |
{ ratio: number; invalid: boolean } |
Render content inside the ratio host. |
none |
Expose
| Name |
Type |
Purpose |
Default |
element |
AspectRatioElement | null |
Rendered host element or component instance. |
null |
ratio |
number |
Ratio used for the rendered box after validation. |
1 |
invalid |
boolean |
Whether the provided ratio fell back to the default. |
false |
Data Attributes
| Attribute |
Values |
Purpose |
Default |
data-vize-ui |
"aspect-ratio" |
Stable family selector. |
always |
data-state |
"valid", "fallback" |
Ratio validation state. |
"valid" |
data-vize-aspect-ratio |
positive number string |
Normalized ratio used by the host style. |
"1" |
CSS Custom Properties
| Custom property |
Purpose |
Default |
--vize-ui-aspect-ratio |
Value read by the inline aspect-ratio declaration. |
"1" |
Styling Contract
AspectRatio is headless: it emits no stylesheet and no visual preset. The host
receives only the inline aspect-ratio: var(--vize-ui-aspect-ratio) declaration
and matching custom property required for intrinsic layout.