Week 274 was posted by Charanjit Chana on 2023-01-23.
Almost 3 years ago, I put together some CSS demos on CodePen. The one I was most proud of was a pure-CSS and HTML slideshow. The demo is fairly crude and it had three key issues:
- I couldn't figure out how to highlight the current slide in the pagination
- It relied on the <a> tag which the page to jump when going through the slideshow
- I couldn't automatically cycle through images
Happy to say though, after an interaction on Twitter where I shared my post but the page jumps were pointed out. Given it had been 3 years and CSS has moved on I decided to attempt a slight re-write to achieve what I set out to achieve.
And here is my second version of a CSS only slideshow:
The only thing to note is that it still doesn't automatically go through the slides and I think that would most likely be achieved with JavaScript. In this case it would be progressive enhancement so I'd be willing to concede that point. Otherwise, this genuinely is a pure-CSS slideshow!
How to build a CSS only slideshow
I wanted to evolve what I'd built before, which was based on the <a> tag and the :target attribute, now it uses radio buttons and the :has() selector.
It took me a while to realise I could place labels elsewhere, so all aspects of the pagination are now driven by labels.
Putting the pagination aside, each slide has a next and previous input and label. If you select an input (hidden) by clicking on the label (visible), then the :has() selector is used to find the checked input from deep inside the slideshow and then allow the slide that's been requested to come to the forefront.
Using these same selectors, I can now also highlight the pagination which wasn't possible before and these have also become labels which just point to specific radio inputs.
Why not to build a CSS only slideshow
The one thing that is a bit of a pain is the fact that I've had to specify the CSS combinations for each slide. This means I couldn't have a dynamic number of slides... rather than setting specific IDs, maybe it would be possible with the :nth-child() and :has() selectors but it feels like it would just be another layer of complication rather than a robust solution.
In the real world, I'd probably programatically figure it out with a @for loop, but that's beyond the scope of a proof of concept.
Would I use a CSS only slideshow in production?
I definitely would, I'd have to refactor it but it's certainly possible and would mean I avoid JavaScript yet again!
Update
After some more feedback, I've taken another fork and now added a check that :has() is supported by the browser. If not, then the pagination is hidden and only the first slide is show. I updated the embedded pen above to show v3, but if you want, you can still check out v2 on CodePen.
Tags: css, development, has-css