Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
.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
Sale
HTML and CSS: Design and Build Websites
  • 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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: :hover alone 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.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Minimal two-image example

For the original hover-only requirement, this is sufficient:

Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • 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

SaleBestseller No. 2
HTML and CSS: Design and Build Websites
HTML and CSS: Design and Build Websites
HTML CSS Design and Build Web Sites; Comes with secure packaging; It can be a gift option
$14.18
SaleBestseller No. 4
Web Design with HTML, CSS, JavaScript and jQuery Set
Web Design with HTML, CSS, JavaScript and jQuery Set
Brand: Wiley; Set of 2 Volumes
$35.05

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.