Gracefullly degrading SVG diagrams

Hi everyone,

I’m working on SVG diagrams/charts from upcoming SitePoint books (see Codepen below for a prototype).

Often these SVGs are rendered outside my control – PDF, ePubs, etc – so always as <img src='chart.svg'>, which means any interactivity is dead. No :hover, :active, or :focus gets recognized.

That’s fine. The static graphic works.

But in our own SitePoint reader format I can make it an <object> which gives me another level of interactivity to show/hide items, open and close elements. I think I might be able to even get a simple magnify/zoom tool working – just with CSS. I think there’s quite a bit of potential here.

BTW: I’m ignoring JavaScript entirely as it regularly gets santized by SVG uploaders – potentially breaking the graphic.

My issue: I want to display the ‘Interactive’ icon only when interactivity is an option (i.e NOT when the graphic in an IMG tag).

I basically want something that reliably fails in SVG in IMG tags. I’ve tried media queries and @keyframes, hoping that IMG ignores them. But alas, it works perfectly.

Any ideas?

1 Like

Tagging @PaulOB, as he usually has good thoughts on this kind of thing :wink:

Had a brainstorm and thought I’d figured it out. What if you wrote basically a CSS feature detector?
Set up a default class, say:

.red {
    fill: red;

Then followed it with a :hover rule for the whole SVG.

svg:hover .red {
    fill: cyan

Inline SVGs render it. The IMG should (and does) ignore it. Nice.
What about the rest of the time when the user is NOT hovering on the SVG?
What about combining :not() and :hover to create that state as a new CSS rule?

svg:not(:hover) .red {
    fill: blue;

If user is NOT hovering on the SVG, turn the .red class fill blue, please.

Kinda of insane, I know, but 100% valid.

And the inline SVG understands it perfectly, rendering the text blue.

The crazy thing is, the IMG version understands and honors that rule too, also rendering the text blue instead of the default red I set up earlier. How does IMG disable :hover, yet happily enable :not(:hover)?

I can’t believe that’s not the answer, but hey…

Hi there alexwalker,

I am rather confused - ( not unusual for me :wonky: )

If the chart.svg file works perfectly in the object element
why are you not happy to use it instead of the img element ?


Heya @coothead,

I’ll definitely use it as an <object> element in the places I can. But we generate PDFs, ePubs and other formats all from the same source. PDF can’t render <object> or inline SVG, so the SVG will always be static there. I think ePub3 can now, but Kindles don’t have any ability to render interactive content.

For us, it’s not really practical to maintain different versions of a book with different images for different output formats. So each book is essentially a single ‘code base’ converted to different output formats.

Ideally I’d love to build a graphic smart enough to advertise its abilities relative to whichever format it finds itself rendered in.

This ‘CSS logic switch’ is an attempt to have that ‘interactive’ label not appear when that SVG gets rendered in a PDF or a Kindle.

Hi there alexwalker,

I can hide it for an img element .

Here is an example…

…and the code…

Would that suffice?



I’m afraid svg is out of my comfort zone.

I did get something to work in Chrome only though.


    svg:hover .red{
      fill: cyan
	@media (hover: hover) {

The media hover: hover is only showing the orange in the inline svg and not when in an image tag. As I said it only works in Chrome so don’t know whether its a bug or feature :slight_smile:

   	@media (hover: hover) {

Not quite, although there may not be a better solution, @coothead. I’m trying to keep the logic inside the SVG file itself, rather than the HTML structure that wraps around it.

In a perfect world, you’d be able to right-click and save my SVG, stick it in an IMG tag on your Wordpress blog and it will automatically not show the ‘Interactive’ label.

1 Like

It’s definitely something I haven’t tried! It’s just gone 11pm here, but I’ll have a play with that idea tomorrow. Cheers for the approach :slight_smile:

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.