Paused-by-default, start-on-click GIFs in pure HTML+CSS

The ringmaster of the Pixscape Webring asked me to create an option to disable the GIF animations on my tiny ideas page. As the Web has strayed from the virtuous radiance of simple, honest code, all readymade solutions for this are in the Script of Java, which I will not utter here; as such, I finally took the time this evening to see if HTML and CSS could be abused into solving my problem.

Behold:

<!DOCTYPE HTML>
<html>
<head>
<title>page title</title>
<style>
summary.gifstop{list-style:none}
[open] summary.gifstop {margin-bottom:-120px;opacity:0%}
</style>
</head>
<body>

<details>
<img src="data-animated.gif" alt="a still image of actor Brent Spiner in pale green makeup as Data in Star Trek TNG">
<summary class="gifstop">
<img src="data-still.gif" alt="a short clip of actor Brent Spiner in pale green makeup as Data in Star Trek TNG, making quizzical and amused facial expressions">
</summary>
</details>

</body>
</html> 

As simple as I could make it. If you create this page (and add two images of your choice), it’ll show the still image. If you click it, it will be replaced with the animated image. If you click it again, it will go back to being still. Note the -120px; it’s the height of the image. This is not a universal solution, so each image would require a separate [open] CSS class. Here’s a demo.

Note that this is technically not what HTML summaries are for, and I usually prefer not to use elements in ways for which they’re not intended, but in terms of simplicity and accessibility, I think it beats those needlessly intricate scripts that were all I could find on StackExchange.

I’ll write up a proper page for this on my site later on, but I figured I’d run it by the fine people of the 32-bit Café first, see if there’s something to improve.

Edit: tweaked the code a lil bit

6 Likes

wow! this is awesome. (i, on the other hand, love using elements the way they aren’t intended! XD)

thank you so much for sharing it with us! curious to know if anyone has any notes. seems like a very cool solution to an age-old problem!

1 Like

I think this is one of those situations where using JS is not a terrible idea, especially considering you can solve this problem without using anything remotely complicated.

<img src="static.gif" data-src="running.gif" onclick="this.tmp = this.src; this.src = this.dataset.src; this.setAttribute('data-src' , this.tmp)">

Don’t get me wrong, I hate what JS has done to the web as a whole but it’s still a useful tool when used appropriately and this is one of those cases.

People with no JS will simply see a static image which is fine imo from a progressive enhancement point of view and if one prefers to show both then you can simply add a second image tag wrapped in a <noscript>

3 Likes

i agree with you there—i think JS has been unfairly hated on in retroweb circles for a while. they used to say where i come from—“don’t throw baby out with the bathwater!”

JS is a tool to make content more dynamic, that’s it. vilifying it doesn’t really make sense to me. all that being said, i understand if folks want to push themselves to use only HTML and CSS to accomplish a certain vibe, function, or aesthetic, so happy to see folks experiment with what can be done!

3 Likes

Absolutely agree. I treat JS as a progressive enhancement tool. I try do everything with HTML and CSS. if something is beyond the scope of those two I’ll use the the bare minimum of JS necessary to do what I need to do and that’s it.

And I love that many things that used to be exclusive territory of JS are now doable with just CSS which is how it should be imo.

3 Likes

I wouldn’t like it if you could only see GIF animations if you have JS enabled in your browser, though. That’s like those pages that won’t load text or images without JS.

I’m roughly the same way as you when it comes to JS, but I lean more toward just not doing something if it can’t be done in HTML, CSS or PHP. I screw around with serverside trickery for two days and then just ask myself if I really need some particular feature and in the end, I conclude that no, I don’t.

Key captures are the one functional bit of JavaScript I use to allow the user to page through photographs, and the rest is all frivolous fun stuff.

1 Like

As I said you can easily solve that by adding the animated gif inside a <noscript>

95% of what I do is HTML, CSS and PHP but some things you just can’t do without JS and that’s fine. Using JS to add functionalities that aren’t available to native languages is precisely why it was invented. The current problem is that people like to use it for literally everything and that honestly sucks.

EDIT: I uploaded a quick test here Play Gif On Click
If you disable JS you’ll see the regular running gif and doesn’t take much just an extra image tag

<noscript>
    <img src="running.gif">
</noscript>

And an extra style also in a noscript to hide the static image

<noscript>
    <style>img[data-src] {display : none}</style>
</noscript>
1 Like

Wow I had tinkered with summary/details to make gif toggles a while ago too! I would have published it, but I ended up scrapping the idea because of accessibility concerns :sweat:

Since summary acts like a button, all of the images in there will be read as the buttons name for screen reader users and I wasn’t sure how to fix that. Thinking on it now though, maybe giving the summary images empty alt text, and alt text to the details images may work :thinking:

1 Like

I think <noscript> needs revision though; if you have a browser extension such as NoScript installed, the browser doesn’t signal to the page that JS is disabled and <noscript> doesn’t work. This is a lot more common than people actually disabling JS support at the browser level, but it bypasses that tag entirely. I’ve had issues in the past with adding JS webring widgets and after adding a nice, mostly functional plaintext replacement, I found it didn’t pop up in any of the browsers I tried.

if you have a browser extension such as NoScript installed, the browser doesn’t signal to the page that JS is disabled and doesn’t work.

I just installed NoScript on Firefox and tested my quick demo and it’s working just fine. I don’t know if there’s some other more esoteric combination of things that can interfere with the noscript tag.

1 Like

Yes, it’s the main thing that’s held me back from implementing this - misuse of tags can screw up the end experience in many unexpected ways. Screen readers are pretty damn smart nowadays* so I don’t think it would actually present a big issue, especially if there’s an accompanying explanation of the functionality, but it’s a slippery slope.

* speaking of which, I wonder where we are on using <table> for nontabular purposes nowadays. Used to be we got told to never use tables except for table stuff because it would screw up accessibility, but I cannot imagine that’s still the issue it once was. I still sometimes hear the siren song of the <table> tag when I’m trying to solve some issue that’s needlessly finicky with <div>.

1 Like

So it does! I (wisely, bravely) replied to your post before checking your example.

So I guess there’s been some progress made since the last time I checked. Which was at some point last year, I believe - may still have been outlandish configurations on my part, but either way it works now.

1 Like

ARIA role="presentation" might interest you~ It gets used in emails, where CSS is limited and they often use tables for layouts.

(Also apologies for the double post, I couldn’t figure out why this quote kept breaking my reply - the angle brackets outside a code block seemed to be the issue!)

Wouldn’t that make the button empty/without a name? I guess you could use some screen-reader only text or maybe an ARIA label…

It does feel kinda tricky for accessibility, though, I agree. It’s like a button, so it should convey its function to screen readers. But it’s also an image… Hm.

1 Like

I forget what I did but I believe I either had text in the summary too like “pause/play gifs” or maybe even used the :before CSS to change it when the user clicked :thinking: