Start
//

Editor Toolkit

ef-fit-scale Tutorial

This guide walks through using ef-fit-scale to make fixed-size compositions responsive. Each step builds on the previous one.

Step 1: Basic Scaling

The simplest use case — wrapping a fixed-size element so it scales to fit its container.

<div class="w-full h-[300px] border border-gray-300 rounded overflow-hidden bg-gray-100">
<ef-fit-scale class="w-full h-full">
<div class="w-[1920px] h-[1080px] bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center text-white text-4xl font-bold">
1920 × 1080
</div>
</ef-fit-scale>
</div>

The inner box scales to fit while maintaining its 16:9 aspect ratio. Resize your browser window to see the scaling update automatically.

Step 2: Different Aspect Ratios

ef-fit-scale handles any aspect ratio — the content always scales to fit entirely within the container.

<div class="flex flex-col gap-4">
<div class="w-full h-[200px] border border-gray-300 rounded overflow-hidden bg-gray-100">
<ef-fit-scale class="w-full h-full">
<div class="w-[1080px] h-[1080px] bg-gradient-to-br from-pink-500 to-red-500 flex items-center justify-center text-white text-2xl font-bold">
1080 × 1080 (1:1)
</div>
</ef-fit-scale>
</div>
<div class="w-full h-[200px] border border-gray-300 rounded overflow-hidden bg-gray-100">
<ef-fit-scale class="w-full h-full">
<div class="w-[1080px] h-[1920px] bg-gradient-to-br from-green-500 to-teal-500 flex items-center justify-center text-white text-2xl font-bold">
1080 × 1920 (9:16)
</div>
</ef-fit-scale>
</div>
</div>

Square and portrait content both scale to fit entirely within their containers, preserving aspect ratio.

Step 3: Content Detection

ef-fit-scale automatically finds the first content child element and ignores non-content elements like <style> and <script> tags.

<div class="w-full h-[300px] border border-gray-300 rounded overflow-hidden bg-gray-100">
<ef-fit-scale class="w-full h-full">
<style>/* This style tag is ignored */</style>
<div class="w-[1920px] h-[1080px] bg-gradient-to-br from-cyan-500 to-blue-500 flex items-center justify-center text-white text-2xl font-bold">
Content Element
</div>
</ef-fit-scale>
</div>

The <style> tag is skipped. Only the <div> is treated as the content to scale.

Step 4: Scaling an Entire Composition

ef-fit-scale scales an entire element tree as a unit — all internal proportions and relationships are preserved.

<div class="w-full h-[300px] border border-gray-300 rounded overflow-hidden bg-gray-900">
<ef-fit-scale class="w-full h-full">
<div class="w-[1920px] h-[1080px] bg-black flex items-center justify-center relative">
<div class="w-[80%] h-[60%] bg-gradient-to-br from-blue-600 to-purple-600 rounded-lg flex items-center justify-center text-white text-4xl font-bold">
Composition
</div>
<div class="absolute bottom-8 left-8 text-white text-xl opacity-60">Lower third</div>
</div>
</ef-fit-scale>
</div>

The entire composition — including nested elements and their relative positions — scales as a unit.

Step 5: Using with ef-timegroup

In a real composition, wrap an ef-timegroup to make the canvas responsive.

<div class="w-full h-[300px] bg-gray-900 rounded overflow-hidden">
<ef-fit-scale class="w-full h-full">
<ef-timegroup mode="contain" class="w-[1920px] h-[1080px] bg-black">
<ef-video src="https://assets.editframe.com/bars-n-tone.mp4" class="size-full object-contain"></ef-video>
</ef-timegroup>
</ef-fit-scale>
</div>

The ef-timegroup declares the canonical composition dimensions. ef-fit-scale handles adapting those to any container size.

How the Scale Calculation Works

ef-fit-scale uses contain logic — the same as object-fit: contain. It picks the scale factor that makes the content fit entirely within the container:

const containerRatio = containerWidth / containerHeight;
const contentRatio = contentWidth / contentHeight;
const scale = containerRatio > contentRatio
? containerHeight / contentHeight // container is wider — height is the limiting dimension
: containerWidth / contentWidth; // container is taller — width is the limiting dimension

After scaling, content is centered:

const scaledWidth = contentWidth * scale;
const scaledHeight = contentHeight * scale;
const translateX = (containerWidth - scaledWidth) / 2;
const translateY = (containerHeight - scaledHeight) / 2;

The resulting transform applied to the content element is:

transform: translate(Xpx, Ypx) scale(S);
transform-origin: top left;

Accessing the Scale Value

Read the current scale calculation at any time:

const fitScale = document.querySelector('ef-fit-scale');
console.log(fitScale.scaleInfo);
// {
// scale: 0.4166,
// containerWidth: 800,
// containerHeight: 600,
// contentWidth: 1920,
// contentHeight: 1080
// }

This is useful when you need to convert pointer coordinates from screen space to composition space (divide by scale).

Pausing Scale Updates

Pause recalculation during animations or transitions to avoid layout thrashing:

const fitScale = document.querySelector('ef-fit-scale');
fitScale.paused = true; // stop recalculating
// ... run your animation ...
fitScale.paused = false; // resume — recalculates immediately

Or via attribute:

<ef-fit-scale paused>
<!-- Scale calculations paused -->
</ef-fit-scale>

Common Pitfall: Zero-Dimension Container

If the container has height: 0, the content will be invisible. Ensure parent elements have resolved heights:

html, body, .editor-root {
height: 100%;
}

ef-fit-scale logs a console warning when it detects a zero-dimension container.