All posts
8 min read

Why is there blank space around the images in my Shopify theme?

Blank space inside an image frame is almost never a broken image. The frame gets its height from your CSS and the photo gets its height from the file, and if nothing tells the photo to take the frame's height, the difference between the two shows as empty container. The rule people reach for, object-fit: cover, does not fix this on its own: with no height to fit into, cover has nothing to do and changes nothing.

Everything below is measured rather than remembered. On 6 September 2026 we read the CSS of the 20 distinct theme designs stored in our own research directory, counted every image rule in them, and then measured a page that is live on this site right now and gets it wrong in two places. The numbers, including the two defects of our own, are all here.

Which of the four image faults do I actually have?

They look similar in a screenshot and they have completely different causes. Select the image, open Computed styles, and read two values: the image's own height, and the height of the element wrapping it.

What you seeWhat the boxes sayCause
Photo sits at the top of its frame with empty colour underneath Image box is shorter than its wrapper The image was never given a height. This is the common one
Photo looks squashed or stretched Image box matches the wrapper exactly Both dimensions were forced and no object-fit was set
Photo fills the frame but the subject is cut off Image box matches the wrapper exactly object-fit: cover is working. The frame's ratio is wrong for your photography
Flat grey or beige rectangle, no photo at all Image box is 0 by 0, or there is no image element No image was ever uploaded, or the file 404s. See the last section

The first three are all the same underlying situation seen from different angles: a frame with a height of its own, holding an image that does not know about it.

Why does object-fit: cover not fix it by itself?

object-fit describes what a replaced element should do when its box and its content disagree about shape. If the box has no height of its own, there is no disagreement to resolve. The browser sizes the image at its intrinsic ratio, the declaration sits there doing nothing, and the frame's background shows through below the photo.

Four combinations, and only one of them works:

CSS on the imageWhat renders in a frame with a fixed ratio
width: 100% onlyCorrect shape, wrong height. Empty container below the photo
width: 100%; object-fit: coverIdentical to the row above. Cover is inert without a height
width: 100%; height: 100%Fills the frame, photo distorted to fit
width: 100%; height: 100%; object-fit: coverFills the frame, photo cropped rather than distorted

The pair that works is three declarations, not one:

.card__media { aspect-ratio: 4 / 5; overflow: hidden; }
.card__media img { display: block; width: 100%; height: 100%; object-fit: cover; }

We know this pattern well because we wrote it into the instructions our own generator follows, after hitting the fault repeatedly. The instruction says, in as many words, that height: 100% is the part themes forget. That did not stop it happening again.

The same bug, live on this site, measured today

The free live preview at Peg Lane has three image frames on the page. One is correct and two are not. Measured in a headless browser at a 1440px viewport on 6 September 2026:

FrameFrame ratioFrame boxImage boxComputed object-fitEmpty
lp-shot16 / 71084 x 4741084 x 474cover0px
lp-does__img5 / 4512 x 410512 x 279fill130px
lp-final__img1 / 1514 x 514514 x 280fill234px

At a 390px phone viewport the same two frames leave 85px and 152px. It is not a desktop only problem, it just scales with the frame.

The cause is visible in the served markup. The theme source writes <img class="lp-img" ... width="1100" height="880">, and the CSS rule that fills the frame is written against that class. What the preview actually serves is <img src="./assets/hero-1.png" loading="lazy">. The class was dropped somewhere in the render path, so the rule has nothing to match, and the computed object-fit falls back to its default of fill while the image keeps its own height. The declaration is in the stylesheet. It is simply not reaching the element.

That is worth knowing generally: a rule you can read in your stylesheet is not evidence that it applied. Read the value off the element, not off the file.

What aspect ratios do theme frames actually use?

Across the 20 designs we read on 6 September 2026 there are 114 fixed aspect-ratio declarations, using 24 distinct values, in 19 of the 20 designs. Only one design sizes its images without ratios at all. So the situation the pattern above describes is not an edge case, it is what nearly every theme does.

RatioDeclarationsShape
4 / 532Portrait
1 / 117Square
3 / 411Portrait
4 / 39Landscape
16 / 108Landscape
5 / 45Landscape
18 other values32Mixed

Grouped by shape that is 55 portrait, 42 landscape and 17 square. Ten of the 24 values carry a decimal, such as 4 / 3.4 and 16 / 10.5, which is a designer tuning a frame by eye to about a tenth of a unit. Those are fine as CSS. They are a problem only if you expect a photo library to match them.

How much of a photo does cover throw away?

Our bundled photography is 100 files across 12 niches at exactly three intrinsic sizes: 1408 x 768, 1024 x 1024 and 1280 x 896. Put each of those into the most common frames and object-fit: cover discards this much of the picture:

Frame1408 x 768 photo1024 x 1024 photo1280 x 896 photo
4 / 556% cropped20% cropped44% cropped
1 / 145% croppednothing cropped30% cropped
3 / 459% cropped25% cropped48% cropped
16 / 1013% cropped38% cropped11% cropped

This is the honest cost of the fix. Making a wide photo fill a 4 / 5 frame means more than half of it is now outside the frame, and which half survives is decided by object-position, which defaults to the centre. If your product sits on the left of the shot, it is gone. The choice is between a frame ratio near your photography's ratio, or shooting to the frame, or setting object-position per image. There is no setting that keeps the whole photo and fills the box.

Why do my images have no width and height attributes?

Separate problem, same element, and it is the one Shopify's own tooling will tell you about. shopify theme check has a rule called ImgWidthAndHeight that flags any <img> without both attributes, because without them the browser cannot reserve space before the file arrives and the page jumps as images load.

The split in our own repository is stark, and the reason is worth reading:

SourceImage tagsWith both width and height
Our hand maintained Liquid sections5453
The 20 AI authored design pages2400

Two caveats so this is not read as more than it is. The 240 are design pages, which is an intermediate artifact, and the Liquid our pipeline emits from them does set the attributes, so the shipped themes are not at 0. And the 53 out of 54 is not virtue, it is a repair: theme check flagged 33 tags across 11 of our files in July 2026 and we added the attributes then. The single remaining exception is an image built in JavaScript for a modal that opens after the page has settled, where there is no layout left to shift.

If you are writing the markup yourself, Shopify's image_tag filter sets both attributes for you from the image object, which is why it is worth using even when a plain tag would be shorter. The attributes are layout hints only. They do not fight the CSS above, because height: 100% overrides an attribute.

How do I find every unfilled image on my store at once?

Open your storefront, open the browser console, and paste this. It reports any image that is shorter than the element wrapping it.

document.querySelectorAll('img').forEach(img => {
  const box = img.getBoundingClientRect();
  if (!box.width) return;
  const frame = img.parentElement;
  const f = frame.getBoundingClientRect();
  const gap = Math.round(f.height - box.height);
  if (gap > 4) {
    console.log(gap + 'px unfilled', frame.className || frame.tagName,
      'frame ' + Math.round(f.width) + 'x' + Math.round(f.height),
      'image ' + Math.round(box.width) + 'x' + Math.round(box.height),
      'object-fit: ' + getComputedStyle(img).objectFit);
  }
});

Run against our own preview page it prints exactly two lines, the two frames in the table above, and stays quiet about the one that is correct:

130px unfilled lp-does__img frame 512x410 image 512x279 object-fit: fill
234px unfilled lp-final__img frame 514x514 image 514x280 object-fit: fill

Two things to know before you trust it. It compares each image to its immediate parent, so an image whose parent is a link that also wraps a caption will report a gap that is really just the caption. Read the class name it prints and check that the element is a media frame. And it only sees the current viewport, so run it wide and narrow, because a frame's ratio is fixed while its width is not.

What if the frame is empty rather than under filled?

A flat rectangle with no photo in it at all is a different fault, and there are three common versions.

  • Nothing was uploaded. Sections built around an image_picker setting render a placeholder until a merchant picks a file in the theme editor. A newly installed theme showing beige boxes where the photography goes is usually this, and it is not damage. On one of our own paid renders it was 4 out of 4 image fields.
  • The file 404s. A section referencing an asset the theme does not actually ship gets a broken image, and if the theme also has an onerror handler that hides the tag, you get a clean empty box with no clue in the interface. We shipped exactly that once by writing .png where the files were .svg: it was on 150 themes at once, and it was invisible until a structural check compared every image reference against the files in the ZIP. The Network tab is where this shows up, as a red row.
  • The tag never became a tag. If a filter in the image line is not supported by whatever is rendering the page, the URL can come through as plain text inside the media container, which then looks like a styled empty box. Viewing source is the fastest way to tell an empty box from a missing tag.

If whole sections rather than single images are blank, it is a different question again, and we wrote it up separately in why a Shopify homepage is blank after installing a theme.

The order to check things in

  1. Right click the empty area and choose Inspect. Confirm there is an <img> element there at all.
  2. Read the image's rendered height and its parent's rendered height. If the parent is taller, this is the fill problem.
  3. Read the computed object-fit on the image, not the declaration in your stylesheet. If it says fill, your rule is not matching the element, and the usual reason is a class that is not on the tag.
  4. Add height: 100% alongside the existing width: 100% and object-fit: cover, in a rule you have confirmed matches.
  5. Look at what the crop now cuts. If the subject is out of frame, change the frame ratio or set object-position, rather than reverting the fill.
  6. Run the console snippet at a wide and a narrow window, and check the Network tab for 404s on image files.

We check this pair automatically on every theme we generate, because our own output produced the fault first and our own preview page still carries two instances of it. If you would rather start from a theme where the image frames are already filled, the free theme gallery has live previews you can inspect yourself before downloading anything, and the sideways scroll write up covers the other half of the box model problems that show up on a phone. The same habit of reading the computed value rather than the declaration also settles the other quiet theme fault, which is a color setting that saves and changes nothing.

Frequently asked questions

Why is there blank space around the images in my Shopify theme?

Because the frame around the image has a height of its own, set by CSS, and the image still has the height of the file. If nothing tells the image to take the frame's height, the difference shows as empty container, usually below the photo. Select the image, read its rendered height and its parent's rendered height, and if the parent is taller you have found it. The fix is to give the image both width 100 percent and height 100 percent, with object-fit cover.

Why does object-fit cover not fix an image that is not filling its box?

Because object-fit only does something when the element's box and the image's natural shape disagree. If you set width 100 percent and no height, the browser gives the image its natural height, the box and the content agree, and the declaration has nothing to resolve. Cover needs a height to fit into. The working pattern is three declarations on the image: width 100 percent, height 100 percent, and object-fit cover.

My stylesheet has object-fit cover but the image still is not filling. Why?

The rule is probably not matching the element. On our own live preview page, measured 6 September 2026, the theme source writes an image tag with a class and the rule is written against that class, but the served markup has no class attribute at all, so the computed object-fit falls back to its default of fill and the image keeps its own height. Read the computed value on the element rather than the declaration in the file. A rule you can see in your CSS is not evidence that it applied.

How much of a photo gets cropped when I make it fill the frame?

It depends on how far apart the two shapes are. A 1408 by 768 landscape photo in a 4 by 5 portrait frame loses 56 percent of the picture, and in a 3 by 4 frame it loses 59 percent. A square photo in a 4 by 5 frame loses 20 percent, and in a square frame it loses nothing. Which part survives is set by object-position, which defaults to the centre, so a product sitting on the left of a wide shot can disappear entirely.

What aspect ratios do Shopify theme image frames normally use?

There is no single convention. Across the 20 theme designs we measured on 6 September 2026 there were 114 fixed aspect-ratio declarations using 24 distinct values, split 55 portrait, 42 landscape and 17 square. The most common single value was 4 by 5, at 32 declarations, followed by 1 by 1 at 17 and 3 by 4 at 11. Ten of the 24 values carried a decimal, such as 4 by 3.4, which is a frame tuned by eye rather than to a standard.

Do Shopify images need width and height attributes?

Yes. The shopify theme check rule ImgWidthAndHeight flags any image tag that lacks both, because without them the browser cannot reserve space before the file downloads and the page jumps as images load. The attributes do not conflict with the CSS that makes an image fill its frame, because a height declaration overrides an attribute. Shopify's image_tag filter sets both for you from the image object, which is the easiest way to comply.

Why does my Shopify theme show grey boxes instead of photos?

An empty rectangle is a different fault from an under filled one. The three common causes are that no image has been picked yet in the theme editor, so the section renders its placeholder, that the file the theme references 404s and an error handler hides the broken tag, or that the image line did not render as an image tag at all and the URL came through as text. Check the Network tab for a red row, and view source to tell an empty box from a missing tag.

Generate a theme that looks like your brand

A complete Shopify 2.0 theme with conversion features built in, ready in minutes. No credit card required.

Generate my theme free

No Shopify store yet? Start one here, then bring the theme. Themr may earn a commission if you start a paid plan; it does not change what you pay.