aspectfit

Aspect ratio fit and fill visualizer

See how an image fits, fills or crops inside a container, then copy the code. Choose one of seven content modes and resize the box: the drawing measures the empty bars and cropped edges, and the code panel writes CSS, UIKit, SwiftUI, Android View, Compose or Flutter.

Visualizer

The image as placed in the box

box empty space cropped off

Box

Or drag the corner handle. Keyboard: focus the handle and use the arrow keys.

Image
Anchor

Where leftover space or cropping goes. Center is every toolkit's default.

Content mode

The math for fit

Scale = min(400 ÷ 1200, 300 ÷ 800) = 0.3333. Drawn at 400 × 266.67, 16.67 empty above and below.

The code

Swift
let imageView = UIImageView(image: UIImage(named: "photo"))
imageView.frame = CGRect(x: 0, y: 0, width: 400, height: 300)
imageView.contentMode = .scaleAspectFit

One behavior, six spellings

The same seven ways of putting an image in a box exist in every toolkit, under different names. A dash means there is no built-in value; the visualizer's code panel writes a workaround.

BehaviorUIKit contentModeSwiftUICSS object-fitAndroid scaleTypeCompose ContentScaleFlutter BoxFit
Fit: whole image, empty bars.scaleAspectFit.scaledToFit()containfitCenterFitcontain
Fill: box covered, edges cropped.scaleAspectFill + clipsToBounds.scaledToFill() + .clipped()covercenterCropCropcover
Stretch: ratio ignored.scaleToFill.resizable()fillfitXYFillBoundsfill
No scaling.center, .top, .topLeft …Image without .resizable()nonecenterNonenone
Shrink only, never enlargeno built-in equivalentno built-in equivalentscale-downcenterInsideInsidescaleDown
Fit widthno built-in equivalentno built-in equivalentno built-in equivalentno built-in equivalentFillWidthfitWidth
Fit heightno built-in equivalentno built-in equivalentno built-in equivalentno built-in equivalentFillHeightfitHeight

Two formulas cover almost everything

Work out how much the image would have to scale to match the box's width, and how much to match its height:

Formulas
ratioX = boxWidth  / imageWidth
ratioY = boxHeight / imageHeight

fit:  scale = min(ratioX, ratioY)
fill: scale = max(ratioX, ratioY)

The smaller ratio guarantees nothing sticks out, so you get bars. The larger one guarantees nothing is left empty, so you get cropping. Stretch uses both ratios, one per axis, which is why it distorts. Multiply the image size by the scale for the drawn size; whatever is left over (or sticks out) is split according to the anchor, half and half by default.

The full walk-through, with the UIKit side of things, is in aspect fit vs aspect fill.

fit / contain
400300400266.67
fill / cover
400300450300
A 1200 × 800 image in a 400 × 300 box. Fit: scale 0.3333, 16.67 empty above and below. Fill: scale 0.375, 25 cropped from each side.

Each toolkit has a different default

Many "my image looks wrong" bugs come from the default, not from the mode someone chose. If you never set a mode, this is what you get:

ToolkitViewDefaultEffect
UIKitUIImageView.scaleToFillstretches
SwiftUIImagenatural size until .resizable()ignores the frame's size
CSS<img> / <video>fill / containimg stretches, video letterboxes
Android ViewImageViewfitCenteraspect fit
ComposeImageContentScale.Fitaspect fit
FlutterImage / FittedBoxscaleDown / containsmall images stay small / aspect fit

Guides

Fit for clothes, too

The rest of this site is about fitting pictures into boxes. The same team builds FitInView, an AI virtual try-on for the other kind of fit. Upload a photo of yourself and a photo or shop link of a garment, and FitInView generates an image of you wearing it. It helps when you are about to order a jacket online and want to see it on you first.

Your first try-on is included with a free account. No card needed. Your photos are private to your account, and you can delete them.

Original photo: a woman in a plain white t-shirt against a gray-blue backdrop
AI try-on example: the same woman wearing an indigo chore jacket
AI try-on example, made with FitInView's try-on: the original photo and the try-on with the indigo chore jacket, split by a divider. Drag the slider or use the arrow keys to compare.

Questions

What is the difference between aspect fit and aspect fill?

Both keep the image's aspect ratio. Aspect fit scales the image by the smaller of the two ratios (box width ÷ image width, box height ÷ image height), so the whole image is visible and empty bars appear where the shapes differ. Aspect fill scales by the larger ratio, so the box is completely covered and the parts that stick out are cropped.

Is scaleAspectFill the same as object-fit: cover?

Yes, they compute the same size and position: UIKit's scaleAspectFill, CSS object-fit: cover, SwiftUI's scaledToFill(), Android's centerCrop, Compose's ContentScale.Crop and Flutter's BoxFit.cover all scale by the larger ratio and center the result. They differ in clipping: in UIKit and SwiftUI you must clip the overflow yourself.

Which mode stretches the image?

UIKit scaleToFill (the UIImageView default), SwiftUI resizable() without an aspect modifier, CSS object-fit: fill (the initial value), Android fitXY, Compose ContentScale.FillBounds and Flutter BoxFit.fill. They scale width and height separately, so the image is distorted whenever the box has a different shape.

How do I calculate the letterbox size?

Compute scale = min(boxWidth / imageWidth, boxHeight / imageHeight), then the drawn size is the image size times the scale. The leftover on each axis is box size minus drawn size; centered, half goes to each side. A 1200 × 800 image in a 400 × 300 box is drawn at 400 × 266.67, leaving 16.67 above and below.

Does the visualizer upload my image?

No. Your image is read by your browser and never leaves your device. The page has no analytics and makes no network requests for your files.