Frame layout

프레임 레이아웃

Locks content with an unpredictable native ratio — a photo, a video — into a fixed aspect-ratio frame, cropping the overflow.

Also known as: Every Layout Frame
···
html
<div class="frame-box" id="fb">
  <div class="art"></div>
  <span class="badge" id="badge">16 / 9</span>
</div>
css
.frame-box{position:relative;width:min(72%,260px);aspect-ratio:16/9;border-radius:12px;overflow:hidden;
  border:1px solid var(--line);transition:aspect-ratio .9s cubic-bezier(.4,0,.2,1);background:var(--surface)}
.art{position:absolute;top:50%;left:50%;width:260px;height:260px;transform:translate(-50%,-50%);
  background:
    radial-gradient(circle at 50% 50%,transparent 0,transparent 30px,var(--accent) 31px,var(--accent) 46px,transparent 47px,transparent 70px,var(--accent-3) 71px,var(--accent-3) 84px,transparent 85px),
    conic-gradient(from 0deg,var(--accent-2),var(--accent),var(--accent-3),var(--accent-2))}
.badge{position:absolute;right:6px;bottom:6px;font:700 10px/1 ui-monospace,monospace;background:rgba(0,0,0,.55);
  color:#fff;padding:3px 7px;border-radius:4px}
js
const fb = document.getElementById('fb');
const badge = document.getElementById('badge');
const ratios = [
  ['16 / 9', '16 / 9'],
  ['1 / 1', '1 / 1'],
  ['3 / 4', '3 / 4'],
  ['21 / 9', '21 / 9'],
];
let i = 0;
setInterval(() => {
  const r = ratios[i % ratios.length];
  fb.style.aspectRatio = r[0];
  badge.textContent = r[1];
  i++;
}, 1900);

Give a container aspect-ratio: 16 / 9 and only its width needs setting — height is computed from the ratio automatically. The trouble is when the image or video inside has a different native ratio: stretch it (width: 100%; height: 100%) and it distorts; preserve its ratio (object-fit: contain) and the frame gets letterboxed with empty space.

object-fit: cover is the most common answer of the three. It keeps the native ratio but scales the content up until it completely fills the frame, then crops whatever overflows — much like overflow: hidden would. object-position controls which part survives the crop (for a portrait, usually top, or something like 50% 30% to favor the face). For a plain <div> background rather than an <img> or <video>, background-size: cover does the identical job.

Change the frame's own ratio later — a square thumbnail becomes a wide banner — and the content inside needs no code changes at all, because object-fit: cover recrops it automatically every time. Drop a grid of differently-sized source images into the same frame, and the grid still reads as visually even.

When to use

Essential whenever you can't control the source dimensions — user-uploaded photos, video thumbnails of mixed ratios — and still need them to line up evenly in a grid or card layout.