Containers
AspectRatio
Reserva proporção para imagens, embeds e placeholders — antídoto para CLS.
Overview
AspectRatio reserva uma proporção fixa em pixels antes do
conteúdo carregar. É o antídoto contra Cumulative Layout Shift
(CLS) em imagens responsivas, embeds (YouTube/Vimeo), e
placeholders de skeleton — quando o asset chega, ele entra no
espaço já reservado, sem empurrar o restante da página.
A escolha do ratio é semântica:
| Ratio | Uso típico |
|---|---|
16/9 | Hero de blog, embed de vídeo, OG image. |
4/3 | Foto clássica, screenshot mais alto. |
1/1 | Avatar grande, OG quadrado, NFT-style cards. |
3/4 | Pôster de filme, vertical photography. |
Veja [[ui/layout/cumulative-layout-shift]] para a fundamentação do CLS e como AspectRatio fecha esse buraco.
Preview
Hero 16/9 — proporção reservada antes do conteúdo.
16 / 9 — hero / video
Anatomy
<AspectRatio ratio={16 / 9}>
<img src="..." className="h-full w-full object-cover" />
</AspectRatio>A criança ocupa 100% do container — use object-cover em
imagens para preservar a proporção sem distorcer.
Subcomponents
| Componente | Descrição |
|---|---|
AspectRatio | Wrapper único. Prop ratio (number, ex.: 16 / 9). |
Usage
import { AspectRatio } from "@kalvner/kds/containers/aspect-ratio";
import Image from "next/image";
export function PostHero() {
return (
<AspectRatio ratio={16 / 9}>
<Image
src="/hero.jpg"
alt="Capa do post"
fill
className="rounded-md object-cover"
/>
</AspectRatio>
);
}Variants
4 / 3
Clássico fotográfico.
4 / 3 — clássico fotográfico
1 / 1
Avatar grande, OG image.
1 / 1 — avatar / OG
3 / 4
Pôster, vertical photo.
3 / 4 — pôster
States
Skeleton placeholder
Espaço reservado durante o carregamento.
Composition
Blog hero
Hero 16/9 acima da headline e do meta.
Hero — 16/9
Engenharia
Por que tokens primitivos vivem dentro de @theme
Como Tailwind v4 e shadcn dividem responsabilidades entre cor crua e intenção semântica.
When to use
- Imagens responsivas com largura variável e altura derivada (heroes, thumbnails, OG previews).
- Embeds de iframe — YouTube, Vimeo, Loom, Stripe checkout.
- Skeleton placeholders para espaços que vão receber mídia.
- Em qualquer card com média que carregam tarde (lazy / on-scroll).
When not to use
- Quando o elemento já tem dimensões fixas em pixels (
w-32 h-32). - Para layouts onde a altura é determinada pelo conteúdo textual (Stack, Grid).
- Em SVGs inline com
viewBox— eles já são intrinsecamente proporcionais. - Para charts com altura fixa (ex.:
h-64) — Charts já reservam espaço.
Best practices
object-coverouobject-contain. Sem isso, imagens esticam para preencher e distorcem.fillno Next Image. Combine<AspectRatio ratio={...}>com<Image fill ...>para Next/Image responsivo.sizesno Next Image. Quando usarfill, sempre forneçasizes("100vw" ou breakpoint-based) para o browser pré-carregar a versão certa.- Skeleton + AspectRatio. Para carregamento de mídia, mostre um Skeleton no slot — não deixe vazio. Vazio pisca ao virar imagem.
- Aprovado para iframes. YouTube embeds funcionam dentro de
AspectRatio sem o hack do
padding-top: 56.25%.
Accessibility
| Concern | Comportamento |
|---|---|
| Semântica | É um <div> puro; herda semântica do conteúdo (img, iframe, video). |
| Alt text | Sempre forneça alt na imagem ou title+aria-label no iframe. AspectRatio não substitui isso. |
| Reduced motion | Embeds com auto-play devem respeitar prefers-reduced-motion no nível do player. |
Related
- [[ui/layout/cumulative-layout-shift]] — fundamentação do CLS.
ScrollArea— quando o conteúdo extrapola e precisa scrollar.Card— frequente container ao redor de hero + texto.