Use picture to switch between square and wide image files at a viewport breakpoint. Give each source its own dimensions and let CSS scale the selected image proportionally. This guide builds and tests a local example on a Mac.

How does picture switch between different aspect ratios?

Put a source element with a media condition before the fallback img inside picture. The browser selects the first eligible source whose condition matches, then selects an image from that source’s srcset. This is called art direction: supplying different compositions for different layouts. The HTML Standard explicitly supports this approach. HTML Standard: Images

Three parts work together: the source chooses the resource, dimension attributes describe that resource’s proportions, and CSS controls its displayed size. The selected source’s width and height can supply the aspect ratio used by the contained image. The picture element itself does not paint the image; its img does. HTML Standard: Embedded content

Choose the mechanism according to the result you need:

Your requirement Appropriate mechanism
Change the composition or aspect ratio at a breakpoint picture with a source using media
Offer different resolutions of the same composition srcset, with sizes when using width descriptors
Keep one file but crop it inside a fixed frame CSS sizing and object-fit: cover

These mechanisms address different decisions. Art direction determines which composition appears. Resolution selection lets the browser choose an appropriate candidate within a composition. CSS fitting determines how the selected resource occupies its frame. MDN documents these uses of picture and its relationship with srcset and fitting properties. MDN: The picture element

Create a complete local example on your Mac

The example uses two original SVG resources containing an orange circle and a teal rounded rectangle. The square version stacks them; the wide version places them side by side. Everything lives in one folder, with no external assets or JavaScript required for switching.

The authored resource contract is simple: below a viewport width of 700px, use a 600 × 600 square resource. At 700px and above, use a 1200 × 600 wide resource. The displayed image fills a content area with 16px on each side, up to a maximum width of 960px. These dimensions and the breakpoint are illustrative design choices.

Save the two shape resources

Create a folder named picture-demo. Use a plain-text code editor to create the following two files inside it, preserving their exact names and extensions. Each fenced block contains the complete file; copy the contents without the Markdown fence markers.

Save this as shapes-square.svg:

<svg xmlns="http://www.w3.org/2000/svg" width="600" height="600" viewBox="0 0 600 600">
  <rect width="600" height="600" fill="#fff5df"/>
  <circle cx="300" cy="180" r="100" fill="#de7b35"/>
  <rect x="150" y="340" width="300" height="160" rx="40" fill="#247d83"/>
</svg>

Save this as shapes-wide.svg:

<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="600" viewBox="0 0 1200 600">
  <rect width="1200" height="600" fill="#fff5df"/>
  <circle cx="320" cy="300" r="180" fill="#de7b35"/>
  <rect x="650" y="150" width="400" height="300" rx="60" fill="#247d83"/>
</svg>

Save the HTML page

Create index.html in the same folder. If you use TextEdit, choose File > New, then Format > Make Plain Text before pasting the code. Save the file with the .html extension and choose Use .html if prompted. Apple documents this workflow for creating HTML files. Apple: Work with HTML documents in TextEdit on Mac

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Shape study</title>
  <style>
    body { margin: 0; font-family: system-ui, sans-serif; }
    main { width: calc(100% - 32px); max-width: 960px; margin: 24px auto; }
    picture { display: block; }
    .study-image { display: block; width: 100%; height: auto; }
  </style>
</head>
<body>
  <main>
    <h1>Shape study</h1>
    <picture>
      <source media="(min-width: 700px)" srcset="shapes-wide.svg"
              width="1200" height="600">
      <img class="study-image" src="shapes-square.svg"
           width="600" height="600"
           alt="An orange circle and a teal rounded rectangle on cream.">
    </picture>
    <p>Resize the viewport to compare the two arrangements.</p>
  </main>
</body>
</html>

Open index.html in Safari. With a sufficiently wide viewport, the shapes should appear side by side. With a narrower viewport, they should stack. Keep all three files together: the two relative resource URLs resolve from the HTML file’s location.

The wide source uses srcset, even though it contains only one URL. Inside picture, source requires srcset; its src attribute is not allowed. Dimension attributes are integers without units, so use width="1200", not width="1200px". MDN: The source element

Why declare dimensions on both the source and fallback?

The fallback’s 600 × 600 dimensions describe the square resource. The wide source’s 1200 × 600 dimensions describe the wide resource. Supplying both pairs allows a supporting browser to establish the selected image’s proportions before downloading it. Reusing the square dimensions for the wide source would provide the wrong initial ratio. HTML Standard: Source dimension attributes

The CSS then sets the image width to the available content width while leaving height automatic. That automatic dimension lets the image’s proportions determine its height. The CSS sizing draft describes how a preferred aspect ratio participates in automatic sizing; explicitly fixing both dimensions removes that flexibility. CSS Box Sizing Module Level 4

For this example, the layout can be checked with a small calculation:

image width = min(viewport width - 32, 960)
square height = image width
wide height = image width / 2
Viewport width in CSS pixels Selected resource Calculated image size
500 shapes-square.svg 468 × 468
699 shapes-square.svg 667 × 667
700 shapes-wide.svg 668 × 334
1000 shapes-wide.svg 960 × 480

These are calculated expectations for the supplied CSS, assuming no scrollbar width reduces the available content area. The SVG syntax, resource names, declared dimensions and arithmetic were checked programmatically; the example was not rendered in a browser during preparation.

Notice the large height change between 699px and 700px. That follows directly from switching from a square to a wide composition. It is expected during resizing. A second jump after loading, while the viewport stays fixed, calls for checking the declared dimensions and any overriding CSS.

Test the breakpoint precisely in Safari

Safari’s Responsive Design Mode lets you resize the page viewport independently of your desktop window. In Safari’s Advanced settings, enable Show features for web developers. Open the example, then choose Develop > Enter Responsive Design Mode, or press Control-Command-R. WebKit documents the setting, shortcut and resizable preview. WebKit: Simplified Responsive Design Mode

Test 699px and 700px first, then a comfortably narrow and wide viewport. Check that the composition changes at the intended boundary, the orange shape remains circular, and the paragraph below the image follows its changing height. Reload at each side of the breakpoint to check the initial layout as well as resizing.

For a direct check of which file Safari selected, run this optional diagnostic snippet in Web Inspector’s console while viewing the example:

const studyImage = document.querySelector('.study-image');
if (!studyImage) {
  throw new Error('Open the Shape study example before running this snippet.');
}
const studyBox = studyImage.getBoundingClientRect();
console.table({
  selectedURL: studyImage.currentSrc,
  displayedWidth: studyBox.width,
  displayedHeight: studyBox.height
});

Run the snippet again after crossing the breakpoint. The selected URL should end in the corresponding square or wide filename. The currentSrc property reports the URL chosen by the browser; its value alone does not prove that the resource loaded successfully. MDN: HTMLImageElement currentSrc property

What should you check when switching looks wrong?

Work through selection, resource dimensions and presentation in that order. This keeps a CSS sizing problem from being mistaken for a resource-selection problem.

  1. The square file remains selected at wide widths. Confirm that the viewport reaches 700px, that source precedes img, and that the source uses srcset. With multiple sources, inspect their order: an earlier matching source can take precedence. HTML Standard: Art direction selection
  2. A resource does not appear. Compare the filenames in the markup with the files in the folder, including extensions. For this example, both SVG files must sit beside index.html.
  3. The right resource appears in the wrong shape. Inspect CSS applied to the actual img, especially rules that assign a fixed height. Restore height: auto for proportional sizing.
  4. The image jumps after loading. Compare each declared dimension pair with its resource’s real ratio. Also check whether an explicit CSS aspect-ratio is overriding the intended proportions.

If your actual design requires a fixed frame, choose fitting behavior deliberately. object-fit: contain preserves the entire resource and can leave empty space; cover fills the frame and can clip content; fill can stretch it. Apply fitting properties to img. The supplied example needs no fixed frame because its layout follows the selected resource’s proportions. MDN: object-fit

What are the browser-support limits?

Support for picture and support for source-specific dimensions are separate considerations. The HTML Standard’s compatibility summary lists picture in current browser engines. MDN marks the source width property, which reflects its dimension attribute, as available across browsers since December 2022. Older browsers should not be assumed to reserve source-specific dimensions correctly. HTML Standard: The picture element, MDN: HTMLSourceElement width property

When no source matches, or the browser does not support picture, the fallback img supplies the image. In this example, that is the square composition. A browser that switches resources but lacks source-dimension support may establish the wide image’s final proportions only after loading. MDN: The picture element

For a target browser that supports CSS aspect-ratio but needs an explicit sizing rule, append the following CSS fragment to the existing stylesheet. It mirrors the HTML breakpoint and supplies provisional ratios while allowing the loaded image’s natural ratio to take over:

.study-image {
  aspect-ratio: auto 1 / 1;
}

@media (min-width: 700px) {
  .study-image {
    aspect-ratio: auto 2 / 1;
  }
}

MDN documents this combination of auto and a ratio, and lists CSS aspect-ratio as available across browsers since September 2021. The fragment therefore has its own support boundary. Keep its breakpoint synchronized with the source condition, and test the browser versions you actually need to accommodate. MDN: aspect-ratio

Once the example behaves correctly, replace the synthetic files with your own compositions and update their dimensions together. Keep the source condition, resource proportions and CSS sizing consistent, then repeat the checks immediately below and above the breakpoint.

Sources