For a simple mouseover preview, use CSS: place both images in one wrapper, hide the second image, and reveal it with the wrapper’s :hover state. Use JavaScript when the image must stay visible after a click, be toggled from a keyboard-accessible control, or follow more complex state rules.
CSS-only mouseover reveal
The wrapper is important because it gives the selector a stable hover target and lets the cascade control the second image. When the pointer leaves the wrapper, the second image automatically returns to its hidden state.
<div class="image-swap">
<img src="thumb.jpg" alt="Front view of the product">
<img class="image-swap__detail" src="detail.jpg" alt="Close-up view of the product">
</div>
.image-swap {
position: relative;
display: inline-block;
}
.image-swap__detail {
display: none;
}
.image-swap:hover .image-swap__detail {
display: block;
}
display: none removes the second image from layout until the wrapper is hovered. This is appropriate when the preview should not reserve space while hidden. The :hover pseudo-class matches while a pointing device designates the element, so the image reverts as soon as the pointer leaves.
Overlay the alternate image instead of changing layout
If the two images must occupy exactly the same space, position the alternate image over the first one. Give both images a predictable size or aspect ratio so the wrapper does not jump.
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 →#1 Best Overall
.image-swap {
position: relative;
display: inline-block;
}
.image-swap img {
display: block;
}
.image-swap__detail {
display: none;
position: absolute;
inset: 0;
}
.image-swap:hover .image-swap__detail {
display: block;
}
Use visibility: hidden rather than display: none only when the hidden image should continue occupying layout space. Visibility alone does not create a click-persistent state and may still require additional positioning or pointer-event decisions.
JavaScript for a click-persistent toggle
CSS hover has no memory of a click. If the alternate image must remain visible after the pointer moves away, store that state in JavaScript. The HTML hidden property is a clear way to represent whether the target is shown.
Rank #2
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
<button type="button" id="image-toggle" aria-controls="detail-image" aria-expanded="false">
Show alternate image
</button>
<img id="detail-image" src="detail.jpg" alt="Close-up view of the product" hidden>
const button = document.querySelector('#image-toggle');
const target = document.querySelector('#detail-image');
button.addEventListener('click', () => {
const willShow = target.hidden;
target.hidden = !willShow;
button.setAttribute('aria-expanded', String(willShow));
button.textContent = willShow
? 'Hide alternate image'
: 'Show alternate image';
});
A real button is preferable when the interaction is a control: it works with the keyboard, has the expected semantics for assistive technology, and can expose its state with aria-expanded. Give both images meaningful alternative text if both convey information; use an empty alt="" for a purely decorative duplicate.
JavaScript hover behavior
JavaScript can also reveal an image only while the pointer is over a trigger. Modern event listeners are clearer than inline onmouseover attributes.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC 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 & 11Rank #3
const trigger = document.querySelector('#img1');
const target = document.querySelector('#img2');
target.hidden = true;
trigger.addEventListener('mouseenter', () => {
target.hidden = false;
});
trigger.addEventListener('mouseleave', () => {
target.hidden = true;
});
mouseenter and mouseleave are generally better for this simple boundary because they do not repeatedly fire when the pointer moves between a parent and its child elements. By contrast, mouseover fires when the pointer enters an element or one of its children, which can produce extra events in nested markup.
Which implementation should you choose?
| Requirement | Best fit | Reason |
|---|---|---|
| Show an alternate image only while hovering | CSS :hover |
No JavaScript dependency; the state resets automatically when hover ends. |
| Keep the image visible after a click | JavaScript with hidden |
JavaScript stores and changes the toggle state. |
| Allow keyboard users to operate the control | Button plus JavaScript | A button provides keyboard semantics and an explicit expanded/collapsed state. |
| React to pointer entry without child-boundary noise | mouseenter/mouseleave |
These events avoid the bubbling behavior associated with mouseover. |
| Keep the hidden image’s space reserved | visibility or an equivalent layout-preserving method |
The element remains in layout instead of being removed as with display: none or hidden. |
Practical limitations and fixes
- Touch screens: a mouseover interaction may not exist or may behave inconsistently on touch devices. Provide a visible button or another tap-friendly control for the same information.
- Keyboard access:
:hoveralone is not a complete keyboard interaction. Add a focus style and a focus state where a preview is essential, or use the button-based toggle. - Layout shifts: reserve dimensions or use an absolutely positioned overlay if swapping images changes surrounding content.
- Image loading: the browser may need to fetch the alternate image only when it is requested. If an immediate preview matters, preload it or include explicit dimensions; do not rely on the hidden state as a loading strategy.
- Click target: do not attach a click-only behavior to a decorative image when a labeled button can communicate the action more clearly.
Minimal two-image example
For the original hover-only requirement, this is sufficient:
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 id="images">
<img id="img1" src="thumb.jpg" alt="Thumbnail">
<img id="img2" src="detail.jpg" alt="Additional view">
</div>
#img2 { display: none; }
#images:hover #img2 { display: block; }
Start with this CSS solution. Add JavaScript only when you need persistence, keyboard-operable controls, or behavior that cannot be expressed as a simple hover state.
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.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitches

