Put the images in the same HTML container, then use CSS for the layout. Use Flexbox for a straightforward row, or CSS Grid when you need explicit columns and rows. Make each image fit its cell with max-width: 100% and height: auto, and switch to a single column or allow wrapping when the available width becomes too small.
The basic side-by-side pattern
HTML determines which images exist and their source order; CSS determines whether they appear beside one another. Start with one wrapper and one <img> element per image:
<div class='image-row'>
<img src='first.jpg' alt='Description of the first image'>
<img src='second.jpg' alt='Description of the second image'>
</div>
For a simple row, Flexbox is the shortest solution:
.image-row {
display: flex;
gap: 1rem;
}
.image-row img {
display: block;
max-width: 100%;
height: auto;
}
The gap creates space without adding margins to individual images. max-width: 100% prevents an image from exceeding the width of its flex item, while automatic height preserves its proportions.
#1 Best Overall
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
Make two images share the row evenly
If both images should occupy equal columns, give each flex item a flexible basis. Applying flex: 1 to the images makes them compete for the available space:
.image-row {
display: flex;
gap: 1rem;
}
.image-row > img {
flex: 1 1 0;
min-width: 0;
display: block;
width: 100%;
height: auto;
}
The zero flex basis tells the browser to distribute the free width rather than allowing one image’s intrinsic width to dominate. min-width: 0 is useful when a long intrinsic image width would otherwise make a flex item refuse to shrink.
For a deliberately unequal layout, use different flex values:
.image-row > img:first-child { flex: 2 1 0; }
.image-row > img:last-child { flex: 1 1 0; }
This gives the first item twice the flexible share. Use a maximum width instead when one image should remain a small companion rather than stretch across the whole row.
Control alignment and spacing in Flexbox
Flexbox lays items out along a main axis and can align them on the cross axis. These properties cover common gallery adjustments:
.image-row {
display: flex;
gap: 1rem;
justify-content: center; /* horizontal distribution */
align-items: flex-start; /* top-align different heights */
}
justify-content: flex-startkeeps the row at the start of its container;center,space-between, andspace-arounddistribute remaining space differently.align-items: flex-starttop-aligns images of different heights. Usecenterto center them vertically orstretchonly when stretching the items is intentional.- Prefer
gapfor consistent horizontal and vertical spacing. It also works when the row wraps.
Do not assign a fixed pixel width that can exceed the parent. A percentage, flexible basis, or maximum width keeps the row usable when the containing element is narrower than expected.
Use CSS Grid for explicit columns and rows
Choose Grid when the gallery has a two-dimensional structure—for example, a known number of columns with cards flowing into multiple rows. A two-column grid is explicit and easy to extend:
Rank #2
.gallery {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 1rem;
}
.gallery img {
display: block;
width: 100%;
max-width: 100%;
height: auto;
}
minmax(0, 1fr) allows each track to shrink to the available width instead of being forced wider by intrinsic content. Add more columns with repeat(3, minmax(0, 1fr)), or define different track sizes such as minmax(12rem, 2fr) minmax(10rem, 1fr).
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Grid also handles an automatically repeating gallery when the minimum card width matters more than a fixed column count:
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
gap: 1rem;
}
The browser creates as many columns as fit and reflows the rest. This can avoid a device-specific breakpoint, but check the result at the narrowest width your content must support.
Make the layout responsive
A row that looks comfortable on a desktop can become cramped on a phone or at high zoom. Pick a reflow strategy based on the minimum width at which the actual images remain legible, not on a particular phone model.
Allow Flexbox to wrap
Wrapping is useful when images may remain side by side at medium widths but should move to a new line when necessary:
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →.image-row {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.image-row > img {
flex: 1 1 18rem;
max-width: 100%;
height: auto;
}
The 18rem basis is a design choice. Increase it for larger images or reduce it for a denser gallery. Because the items can wrap, the layout does not require a single hard-coded mobile breakpoint.
Stack at a deliberate breakpoint
For exactly two columns on wide screens and one column on narrow screens, use a mobile-first rule:
Rank #3
.image-row {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}
.image-row img {
width: 100%;
max-width: 100%;
height: auto;
}
@media (min-width: 42rem) {
.image-row {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
The breakpoint should be where the images stop being crowded in your container. Test the page while zoomed and at a narrow viewport; W3C reflow techniques use a width equivalent to 320 CSS pixels as an accessibility test condition intended to avoid horizontal scrolling, not as a claim about a user population or a mandatory breakpoint.
Responsive images are separate from layout
Flexbox and Grid decide where an image is placed. They do not decide which file the browser downloads. Use srcset and sizes when several resolutions are available, or <picture> when you need art direction or a different crop:
<picture>
<source media='(max-width: 41.99rem)' srcset='portrait-small.jpg'>
<img
src='landscape-large.jpg'
srcset='landscape-medium.jpg 800w, landscape-large.jpg 1400w'
sizes='(min-width: 42rem) 50vw, 100vw'
alt='A mountain trail at sunrise'>
</picture>
Keep the image’s layout rules on the image (or a consistent wrapper) so every source fits the same grid or flex item.
Keep HTML source order meaningful
Write the images in the order a person should encounter them in the document. Keyboard users and assistive technologies follow the source and focus order; changing the visual order with Flexbox order, row-reverse, or visually positioned Grid items can make those sequences disagree.
If the second image is the logical next item, place it second in the markup even if a visual design seems to suggest otherwise. Use CSS for presentation, not to express a meaningful reading sequence.
Write useful alternative text
- Describe the information or action conveyed by an informative image.
- Use an empty
alt=''for a purely decorative image when surrounding text already provides the meaning. - Do not repeat a caption word for word in the alternative text unless the repetition is useful.
When images are links, make the link’s accessible name clear; when they are a comparison, identify which version or state each image represents.
Recommended Free Tools
Captions and equal-height cards
When an image needs a caption, use a semantic <figure> for each item. Keep the figures in the same flex or grid container:
Rank #4
- Brand: Wiley
- Set of 2 Volumes
- A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
<div class='gallery'>
<figure>
<img src='before.jpg' alt='The original landing page'>
<figcaption>Before</figcaption>
</figure>
<figure>
<img src='after.jpg' alt='The redesigned landing page'>
<figcaption>After</figcaption>
</figure>
</div>
.gallery {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 1rem;
}
.gallery figure {
margin: 0;
}
.gallery img {
display: block;
width: 100%;
height: auto;
}
If equal-height cards are part of the design, make that choice at the figure or card level and verify that captions do not become clipped. Letting the image retain its natural aspect ratio is usually safer than forcing a crop just to equalize height.
Common problems and fixes
The images appear one above another
Confirm that the wrapper actually has display: flex or display: grid, and check for a later rule that sets the container back to display: block. In Grid, verify that the media query enabling multiple columns is active at the viewport width you are testing.
One image is wider than the page
Apply max-width: 100% and height: auto. If the flex item still refuses to shrink, add min-width: 0 to the item. Also inspect the image’s intrinsic dimensions and any fixed width set by an inline style or a more specific selector.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteThere is unexpected whitespace under an image
Images are inline-level by default in many stylesheets, so they can align to a text baseline. Set display: block on the image, as in the examples, to remove that baseline gap.
The columns cause horizontal scrolling
Look for fixed widths, large minimum widths, long unbroken text, or a grid track such as 1fr 1fr without a zero minimum. Use minmax(0, 1fr), min-width: 0, and a wrapping or stacking rule. Test at a width equivalent to 320 CSS pixels and with browser zoom increased.
The visual order is confusing when tabbing
Inspect the HTML order before adding order or explicit Grid placement. Move the elements in the source so the navigation sequence is correct, then let CSS create the visual arrangement.
The images have different proportions
Allow each image to keep its natural height with height: auto. If a uniform crop is genuinely required, define that as a deliberate design requirement and provide alternative text that still identifies the image’s meaning. Do not distort an image by assigning both dimensions without a cropping strategy.
Free tools Windows power users keep installed
One-click scans. No signup required.
Best Value
A practical testing checklist
- Resize from a wide desktop viewport to a narrow viewport and confirm that no horizontal scrollbar appears.
- Check the layout at the width where the columns switch or wrap, not only at the two extremes.
- Zoom the page and verify that the images and captions remain usable.
- Disable CSS temporarily to confirm that the HTML order still makes sense.
- Navigate with the keyboard and check that focus follows the same sequence as the visual content.
- Inspect each image’s alternative text and make sure decorative images are not announced unnecessarily.
- Use the browser’s responsive-image view or network panel to confirm that the intended source files are selected when
srcset,sizes, orpictureis used.
Or skip the browser setup
If your goal is to verify how the finished side-by-side page renders, ScreenshotNeo can capture the URL through one request instead of requiring you to maintain browser automation. It accepts a URL and returns a PNG, JPEG, WebP, or PDF. Before capture, it accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers.
For a direct capture, see the ScreenshotNeo API documentation:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/gallery -o gallery.webp
The same request in Python:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com/gallery"},
timeout=90,
)
r.raise_for_status()
open("gallery.webp", "wb").write(r.content)
And in Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com/gallery' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('gallery.webp', Buffer.from(await res.arrayBuffer()));
You can set a viewport or device preset, retina scale, full-page capture, custom CSS, a wait for a selector or network idle, and a cache TTL. Other useful options include hiding selectors, clicking an element before capture, blocking ads or selected resource types, supplying headers, cookies, a user agent, timezone, geolocation, or Authorization, capturing one CSS-selected element, resizing the output, and producing a PDF. Async jobs with signed webhooks, bulk capture of up to 100 URLs per call, signed links for public image tags, a usage API, and an OpenAPI specification are available as well. An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients, so an AI agent can inspect the rendered result.
The free plan includes 1,000 screenshots each month with no card. Paid plans start at $5 for 3,000 shots; every feature is included on every plan, and yearly billing provides two months free. Create a free ScreenshotNeo account to try the capture without a card.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchFAQ
Should I use Flexbox or Grid for a two-image comparison?
Use Flexbox when the requirement is mainly one row with flexible widths or wrapping. Use Grid when the comparison is part of a defined column system or will grow into multiple rows. Both can produce the same two-column result; the surrounding layout determines which is easier to maintain.
Can I place images side by side without CSS?
HTML alone supplies the elements and their source order but does not provide a reliable modern layout system for controlling equal columns, gaps, and responsive reflow. Add a small Flexbox or Grid rule instead of relying on whitespace or deprecated alignment attributes.
Why does a responsive image still look blurry?
Layout CSS controls the displayed box, not the pixel density of the downloaded file. Check the available files and the srcset and sizes descriptors, then make sure the chosen source is large enough for the rendered size and display density.
Frequently Asked Questions
Should I use Flexbox or Grid for a two-image comparison?
Use Flexbox for a single flexible row; choose Grid when the gallery belongs to an explicit row-and-column structure.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Can I place images side by side without CSS?
HTML defines the images and their order, but CSS is needed for dependable columns, spacing, and responsive reflow.
Why does a responsive image still look blurry?
Check that your srcset and sizes choices provide a source with enough pixels for the rendered dimensions and display density.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




