Aspect Ratio
aspect-ratiouiWraps content (typically images, video, or iframes) at a fixed width:height ratio so it never letterboxes or jumps as it loads. Common ratios: 16/9 for video, 1/1 for avatars, 4/3 for cards.
Installation
$pnpm dlx shadcn@latest add https://uipkge.dev/r/lit/aspect-ratio.json$npx shadcn@latest add https://uipkge.dev/r/lit/aspect-ratio.json$yarn dlx shadcn@latest add https://uipkge.dev/r/lit/aspect-ratio.json$bunx shadcn@latest add https://uipkge.dev/r/lit/aspect-ratio.jsonManifest:
https://uipkge.dev/r/lit/aspect-ratio.jsonInstalls to:src/uip/components/aspect-ratio/Examples
Loading interactive previews…
Loading interactive previews…
Props
| Name | Type / Values | Default | Required |
|---|---|---|---|
ratio | string | 1 | optional |
Schema
Type aliases from this item's source — use them to shape the data you pass in.
HTMLElementTagNameMapinterface HTMLElementTagNameMap {
'uip-aspect-ratio': UipAspectRatio
}
}Files installed (1)
src/uip/components/aspect-ratio/aspect-ratio.ts1.6 kB
import { LitElement, css, html } from 'lit' import { tailwind } from '../../lib/styles' import { ThemeController } from '../../lib/theme' const ratioConverter = { fromAttribute(value: string | null): number { if (!value) return 1 if (value.includes('/')) { const [w, h] = value.split('/').map((s) => parseFloat(s.trim())) if (w && h) return w / h } const num = parseFloat(value) return Number.isNaN(num) ? 1 : num }, toAttribute(value: number): string { return String(value) }, } /** * <uip-aspect-ratio> — displays content within a desired ratio. * * Uses CSS `aspect-ratio` on the host so outer utility classes (grid, flex, * rounded, overflow-hidden) apply directly to the sized container. */ export class UipAspectRatio extends LitElement { static styles = [ tailwind, css` :host { display: block; position: relative; width: 100%; aspect-ratio: var(--uip-aspect-ratio, 1 / 1); } `, ] static properties = { ratio: { converter: ratioConverter, reflect: true }, } ratio = 1 constructor() { super() new ThemeController(this) } connectedCallback() { super.connectedCallback() this.setAttribute('data-uipkge', '') this.setAttribute('data-slot', 'aspect-ratio') } willUpdate() { this.style.setProperty('--uip-aspect-ratio', String(this.ratio)) } render() { return html`<slot part="base"></slot>` } } customElements.get('uip-aspect-ratio') || customElements.define('uip-aspect-ratio', UipAspectRatio) declare global { interface HTMLElementTagNameMap { 'uip-aspect-ratio': UipAspectRatio } }
Raw manifest:https://uipkge.dev/r/lit/aspect-ratio.json