Cropper.js Aspect Ratio Presets — Free JS Snippet

Cropper.js Aspect-Ratio Presets for Social Posts · Forms · Plain HTML, CSS & JS · Live preview

CategoryForms

What's included

Features

Six presets: 1:1, 4:5, 16:9, 9:16, 1.91:1 and free-form
Presets defined as data — ratio plus exact output pixels
setAspectRatio(NaN) implements the unlocked "Free" mode
Export resampled to the platform size with getCroppedCanvas
Live selection size in original pixels from the crop event
Proportional outline icons generated from each ratio
aria-pressed on the active preset for assistive technology
Generated sample photo, no image files needed

About this UI Snippet

Cropper.js Aspect-Ratio Presets — HTML, CSS & JavaScript

Screenshot of the Cropper.js Aspect-Ratio Presets for Social Posts snippet rendered live

Every social platform wants a different rectangle. Instagram takes 1:1 or 4:5, YouTube thumbnails are 16:9, Stories and Reels are 9:16 and link previews use the roughly 1.91:1 Open Graph shape. Marketers and editors reframe the same photo several times a week, and a tool that makes them do it with a free-form box and a calculator is a tool they stop using. A preset bar turns that into one click per destination.

Cropper.js supports this directly: aspectRatio in the options locks the crop box to a ratio, and setAspectRatio() changes it at runtime. Passing NaN removes the lock entirely, which is how the "Free" preset is implemented — an easy detail to miss, because the documentation describes NaN as "free ratio" rather than showing a constant. Each preset in the snippet is data — a ratio plus the exact pixel size the platform expects — so adding a destination means adding a line to an array, not writing new logic.

There is an important distinction between the crop and the export. The crop box selects a region of the original, whatever its pixel size; the export decides the output resolution. Calling getCroppedCanvas({ width, height }) resamples the selection to the preset's dimensions, so a 2400 × 1600 source cropped for a 1080 × 1350 portrait post comes out at exactly 1080 × 1350 with high-quality smoothing. The live line under the preview shows the selection size in source pixels through the crop event, which is what warns you when a selection is so small that upscaling will look soft.

The preset buttons draw a proportional outline icon for each ratio, computed from the ratio itself, and use aria-pressed so the active preset is exposed to assistive technology as well as shown visually. The result panel demonstrates the final canvas at its real dimensions, scaled down for display. In a production tool the canvas would be sent on with toBlob() and a fetch upload rather than displayed.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Ask an AI assistant like Claude to add a file picker or drag-and-drop for loading real photos, a JPEG quality slider with a live size estimate, or a batch export that renders every preset at once.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build an aspect-ratio preset cropper with Cropper.js 1.6 loaded from a CDN (script and CSS).

Requirements:
- Define presets as data: Instagram square 1:1 (1080x1080), portrait 4:5 (1080x1350), YouTube 16:9 (1280x720), Story 9:16 (1080x1920), link preview 1.91:1 (1200x630) and a Free preset using NaN.
- Render a button per preset with a proportional outline icon and aria-pressed for the active one; clicking calls setAspectRatio().
- Show the selection size in source pixels from the crop event, and the target output size.
- Export with getCroppedCanvas({ width, height, imageSmoothingQuality: 'high' }) and show the result with its dimensions.
- Generate the sample image on a canvas so no files are required.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Source Code

<div class="sp-wrap">
  <div class="sp-presets" id="spPresets" role="group" aria-label="Aspect ratio presets"></div>
  <div class="sp-stage"><img id="spImg" alt="Photo to crop"></div>
  <div class="sp-foot">
    <div class="sp-info">
      <b id="spName">Instagram square</b>
      <span id="spSize">Output 1080 &times; 1080</span>
      <span id="spSel">Selection -</span>
    </div>
    <button type="button" class="sp-go" id="spGo">Export crop</button>
  </div>
  <div class="sp-result" id="spResult" hidden><canvas id="spCanvas"></canvas><span id="spResText"></span></div>
</div>

Step by step

How to Use

  1. 1
    Choose a presetClick Instagram portrait, YouTube thumbnail, Story or Link preview. The crop box snaps to that ratio.
  2. 2
    Adjust the cropDrag the box or its handles to frame the subject; the ratio stays locked.
  3. 3
    Read the sizesThe footer shows the output size for the preset and the selection size in original pixels.
  4. 4
    ExportPress Export crop to render the selection at the platform's exact pixel dimensions.
  5. 5
    Go freeChoose Free to remove the ratio lock and draw any shape you like.

Real-world uses

Common Use Cases

Social media scheduling tools
Reframe one photo for every channel in seconds. For round profile pictures see the avatar cropper.
CMS featured-image fields
Enforce the exact hero and thumbnail proportions a theme requires.
SHOP
Marketplace listing photos
Guide sellers to square or portrait crops that fit product grids.
Learning ratio versus resolution
Shows the difference between choosing a region and choosing an output size.

Got questions?

Frequently Asked Questions

Call setAspectRatio(NaN). NaN means a free ratio, so the crop box can take any shape.

The crop selects a region of the original. getCroppedCanvas with width and height then scales that region to the size you want to publish.

It tells you how many original pixels you have. A very small selection exported at 1080 pixels will be upscaled and look soft.

Add an object to the PRESETS array with its ratio and output width and height. The buttons and icons are generated from it.

Call canvas.toBlob() with a type and quality, then send the blob in a FormData body with fetch.

Yes. Cropper.js supports touch dragging and pinch to zoom on the crop area.

Yes. Use the JSX, Vue, Angular or Tailwind export buttons on this page to convert the markup and styles. The behaviour comes from Cropper.js, so in a framework project install it with npm install cropperjs instead of the CDN tag, create it in useEffect / onMounted / ngAfterViewInit once the image has loaded, and release it with destroy() when the component unmounts.