[html] How to change an image on click using CSS alone?

I have an image and when the image is clicked I want to reveal another image below it. I am looking for a simple CSS only solution.

Is that possible?

This question is related to html css image

The answer is


No, you will need scripting to place a click Event handler on the Element that does what you want.


A Pure CSS Solution

Abstract

A checkbox input is a native element served to implement toggle functionality, we can use that to our benefit.

Utilize the :checked pseudo class - attach it to a pseudo element of a checkbox (since you can't really affect the background of the input itself), and change its background accordingly.

Implementation

input[type="checkbox"]:before {
    content: url('images/icon.png');
    display: block;
    width: 100px;
    height: 100px;
}
input[type="checkbox"]:checked:before {
    content: url('images/another-icon.png');
}

Demo

Here's a full working demo on jsFiddle to illustrate the approach.

Refactoring

This is a bit cumbersome, and we could make some changes to clean up unnecessary stuff; as we're not really applying a background image, but instead setting the element's content, we can omit the pseudo elements and set it directly on the checkbox.

Admittedly, they serve no real purpose here but to mask the native rendering of the checkbox. We could simply remove them, but that would result in a FOUC in best cases, or if we fail to fetch the image, it will simply show a huge checkbox.

Enters the appearance property:

The (-moz-)appearance CSS property is used ... to display an element using a platform-native styling based on the operating system's theme.

we can override the platform-native styling by assigning appearance: none and bypass that glitch altogether (we would have to account for vendor prefixes, naturally, and the prefix-free form is not supported anywhere, at the moment). The selectors are then simplified, and the code is more robust.

Implementation

input[type="checkbox"] {
    content: url('images/black.cat');
    display: block;
    width: 200px;
    height: 200px;
    -webkit-appearance: none;
}
input[type="checkbox"]:checked {
    content: url('images/white.cat');
}

Demo

Again, a live demo of the refactored version is on jsFiddle.

References

Note: this only works on webkit for now, I'm trying to have it fixed for gecko engines also. Will post the updated version once I do.


This introduces a new paradigm to HTML/CSS, but using an <input readonly="true"> would allow you to append an input:focus selector to then alter the background-image

This of course would require applying specific CSS to the input itself to override browser defaults but it does go to show that click actions can indeed be triggered without the use of Javascript.


You can use the different states of the link for different images example

You can also use the same image (css sprite) which combines all the different states and then just play with the padding and position to show only the one you want to display.

Another option would be using javascript to replace the image, that would give you more flexibility


some people have suggested the "visited", but the visited links remain in the browsers cache, so the next time your user visits the page, the link will have the second image.. i dont know it that's the desired effect you want. Anyway you coul mix JS and CSS:

<style>
.off{
    color:red;
}
.on{
    color:green;
}
</style>
<a href="" class="off" onclick="this.className='on';return false;">Foo</a>

using the onclick event, you can change (or toggle maybe?) the class name of the element. In this example i change the text color but you could also change the background image.

Good Luck


Try this (but once clicked, it is not reversible):

HTML:

<a id="test"><img src="normal-image.png"/></a>

CSS:

a#test {
    border: 0;
}
a#test:visited img, a#test:active img {
    background-image: url(clicked-image.png);
}

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to image

Reading images in python Numpy Resize/Rescale Image Convert np.array of type float64 to type uint8 scaling values Extract a page from a pdf as a jpeg How do I stretch an image to fit the whole background (100% height x 100% width) in Flutter? Angular 4 img src is not found How to make a movie out of images in python Load local images in React.js How to install "ifconfig" command in my ubuntu docker image? How do I display local image in markdown?