Tags: svg

74

sparkline

Wednesday, April 26th, 2023

Assumption

While I’m talking about the SVGs on The Session, I thought I’d share something else related to the rendering of the sheet music.

Like I said, I use the brilliant abcjs JavaScript library. It converts ABC notation into sheet music on the fly, which still blows my mind.

If you view source on the rendered SVG, you’ll see that the path and rect elements have been hard-coded with a colour value of #000000. That makes sense. You’d want to display sheet music on a light background, probably white. So it seems like a safe assumption.

Ah, but when it comes to front-end development, assumptions are like little hidden bombs just waiting to go off!

I got an email the other day:

Hi Jeremy,

I have vision problems, so I need to use high-contrast mode (using Windows 11). In high-contrast mode, the sheet-music view is just black!

Doh! All my CSS adapts just fine to high-contrast mode, but those hardcoded hex values in the SVG aren’t going to be affected by high-contrtast mode.

Stepping back, the underlying problem was that I didn’t have a full separation of concerns. Most of my styling information was in my CSS, but not all. Those hex values in the SVG should really be encoded in my style sheet.

I couldn’t remove the hardcoded hex values—not without messing around with JavaScript beyond my comprehension—so I made the fix in CSS:

[fill="#000000"] {
  fill: currentColor;
}
[stroke="#000000"] {
  stroke: currentColor;
}

That seemed to do the trick. I wrote back to the person who had emailed me, and they were pleased as punch:

Well done, Thanks!  The staff, dots, etc. all appear as white on a black background.  When I click “Print”, it looks like it still comes out black on a white background, as expected.

I’m very grateful that they brought the issue to my attention. If they hadn’t, that assumption would still be lying in wait, preparing to ambush someone else.

Workaround

Two weeks ago, I wrote:

I woke up today to a very annoying new bug in Firefox. The browser shits the bed in an unpredictable fashion when rounding up single pixel line widths in SVG. That’s quite a problem on The Session where all the sheet music is rendered in SVG. Those thin lines in sheet music are kind of important.

Paul Rosen, who makes abcjs, the JavaScript library that renders sheet music on The Session, managed to get a fix out pretty quickly. But I use an older version of the library and updating it would introduce some side-effects that would take me a while to work around. So that option wasn’t available to me.

In this situation, when the problem is caused by a browser bug, the correct course of action is to file a bug with the browser. That had already been done. Now all I could do was twiddle my thumbs and wait for the next release of the browser, which would hopefully ship with the fix.

But I figured I may as well try to find a temporary workaround in the meantime.

At first, I looked at diving into the internals of the JavaScript—that’s where the instructions are given for drawing the SVGs.

But then I stopped and thought, “If the problem is with the rendering of the SVG, maybe CSS can help.”

I started messing around with SVG-specific CSS properties like stroke, fill, and so on. With dev tools open, I started targeting the paths that acted as bar lines in the sheet music, playing around with widths, opacities, and fills.

It was the debugging equivalent of throwing spaghetti at the wall. Remarkably, it actually worked.

I found a solution with this nonsensical bit of CSS:

stroke: currentColor;
stroke-opacity: 0;

For some reason, rather than making all the barlines disappear, this ensured they were visible.

It’s the worst kind of hacky fix—the kind where you have no idea why it works, but it does.

So I shipped it.

And at pretty much exactly the same time, a new version of Firefox dropped …with the bug fixed.

I can’t deny that there was a certain satisfaction in being able to work around a browser bug. But there’s much more satisfaction in deleting the hacky workaround when it’s no longer needed.

Wednesday, September 21st, 2022

Remix Icon - Open source icon library

I love how easy it is to use these icons: you can copy and paste the SVG or even get it encoded as a data URL.

Thursday, September 16th, 2021

Basic Pattern Repository

A nice little collection of very simple—and very lightweight—SVGs to use as background patterns.

Wednesday, April 21st, 2021

PlymouthPress – A Letterpress Image Font

An experimental image font made using the University of Plymouth’s unique letterpress workshop.

Grungy!

The font is intended for display purposes only, and not is suitable for body text.

Tuesday, April 6th, 2021

Swipey image grids.

This is how you write up a technique! Cassie takes an SVG pattern she used on the Clearleft “services” page and explains it in step-by-step detail, complete with explanatory animated diagrams.

Wednesday, March 17th, 2021

Good, Better, Best: Untangling The Complex World Of Accessible Patterns — Smashing Magazine

I really like the approach that Carie takes here. Instead of pointing to specific patterns to use, she provides a framework for evaluating technology. Solutions come and go but this kind of critical thinking is a long-lasting skill.

Tuesday, December 22nd, 2020

SVGs in dark mode

I added a dark mode to my site last year. Since then I’ve been idly toying with the addition of a dark mode to The Session too.

As with this site, the key to adding a dark mode was switching to custom properties for color and background-color declarations. But my plans kept getting derailed by the sheet music on the site. The sheet music is delivered as SVG generated by ABCJS which hard-codes the colour in stroke and fill attributes:

fill="#000000" stroke="#000000"

When I was describing CSS recently I mentioned the high specifity of inline styles:

Whereas external CSS and embedded CSS don’t have any effect on specificity, inline styles are positively radioactive with specificity.

Given that harsh fact of life, I figured it would be nigh-on impossible to over-ride the colour of the sheetmusic. But then I realised I was an idiot.

The stroke and fill attributes in SVG are presentational but they aren’t inline styles. They’re attributes. They have no affect on specifity. I can easily over-ride them in an external style sheet.

In fact, if I had actually remembered what I wrote when I was adding a dark mode to adactio.com, I could’ve saved myself some time:

I have SVGs of sparklines on my homepage. The SVG has a hard-coded colour value in the stroke attribute of the path element that draws the sparkline. Fortunately, this can be over-ridden in the style sheet:

svg.activity-sparkline path {
  stroke: var(--text-color);
}

I was able to do something similar on The Session. I used the handy currentColor keyword in CSS so that the sheet music matched the colour of the text:

svg path {
  fill: currentColor;
}
svg path:not(stroke="none") {
  stroke: currentColor;
}

Et voila! I now had light-on-dark sheet music for The Session’s dark mode all wrapped up in a prefers-color-scheme: dark media query.

I pushed out out the new feature and started getting feedback. It could be best summarised as “Thanks. I hate it.”

It turns out that while people were perfectly fine with a dark mode that inverts the colours of text, it felt really weird and icky to do the same with sheet music.

On the one hand, this seems odd. After all, sheet music is a writing system like any other. If you’re fine with light text on a dark background, why doesn’t that hold for light sheet music on a dark background?

But on the other hand, sheet music is also like an image. And we don’t invert the colours of our images when we add a dark mode to our CSS.

With that in mind, I went back to the drawing board and this time treated the sheet music SVGs as being intrinsicly dark-on-light, rather than a stylistic choice. It meant a few more CSS rules, but I’m happy with the final result. You can see it in action by visiting a tune page and toggling your device’s “appearance” settings between light and dark.

If you’re a member of The Session, I also added a toggle switch to your member profile so you can choose dark or light mode regardless of your device settings.

Sunday, November 22nd, 2020

Static sites, slack and scrollytelling. | Clearleft

Cassie’s enthusiasm for fun and interesting SVG animation shines through in her writing!

Thursday, October 15th, 2020

Google font to SVG path

Cassie pointed me to this very nifty tool (that she plans to use in your SVG animation workshop): choose font from Google Fonts, type some text, and get the glyphs immediately translated into an SVG!

Sunday, March 22nd, 2020

Lea Verou on Twitter

Now that all modern browsers support SVG favicons, here’s how to turn any emoji into a favicon.svg:

<svg xmlns="http://w3.org/2000/svg" viewBox="0 0 100 100"> <text y=".9em" font-size="90"> 💩 </text> </svg>

Useful for quick apps when you can’t be bothered to design a favicon!

Tuesday, December 3rd, 2019

Motion Paths - Past, Present and Future | Codrops

This is superbly in-depth and easy-to-follow article from Cassie—everything you need to know about motion paths in SVG and CSS! It’s worth reading just for the wonderful examples.

Wednesday, October 30th, 2019

Interactive web animation with SVG by Cassie Evans | CSSCAMP 2019 - YouTube

Cassie’s excellent talk on SVG animation is well worth your time.

Interactive web animation with SVG by Cassie Evans | CSSCAMP 2019

Tuesday, September 10th, 2019

SVG Artista

A handy tool for tweaking the animations in your SVGs.

Tuesday, July 30th, 2019

Creating my logo animation - cassie.codes

What a wonderfully in-depth and clear tutorial from Cassie on how she created the animation for her nifty SVG logo!

Also: Cassie is on the indie web now, writing on her own website—yay!

Friday, July 5th, 2019

Smashing TV — Webinars and Live Sessions — Smashing Magazine

Don’t miss this—a masterclass in SVG animation with Cassie (I refuse to use the W word). Mark your calendar: August 20th.

Wednesday, May 29th, 2019

Wednesday, May 22nd, 2019

Accessible Icon Buttons — Sara Soueidan – Freelance-Front-End UI/UX Developer

Sara runs through the many ways of providing an accessible name to an icon button, backed up with Scott’s testing.

Wednesday, April 24th, 2019

Earth day at Clearleft

Isn’t this just lovely?

Cassie made a visualisation of the power we’re getting from the solar panels we installed on the roof of the Clearleft building.

I highly recommend reading her blog post about the process too. She does such a great job of explaining how she made API calls, created SVGs, and calculated animations.

Thursday, April 18th, 2019

Inlining SVG background images in CSS with custom properties

Here’s a tiny lesson that I picked up from Trys that I’d like to share with you…

I was working on some upcoming changes to the Clearleft site recently. One particular component needed some SVG background images. I decided I’d inline the SVGs in the CSS to avoid extra network requests. It’s pretty straightforward:

.myComponent {
    background-image: url('data:image/svg+xml;utf8,<svg> ... </svg>');
}

You can basically paste your SVG in there, although you need to a little bit of URL encoding: I found that converting # to %23 to was enough for my needs.

But here’s the thing. My component had some variations. One of the variations had multiple background images. There was a second background image in addition to the first. There’s no way in CSS to add an additional background image without writing a whole background-image declaration:

.myComponent--variant {
    background-image: url('data:image/svg+xml;utf8,<svg> ... </svg>'), url('data:image/svg+xml;utf8,<svg> ... </svg>');
}

So now I’ve got the same SVG source inlined in two places. That negates any performance benefits I was getting from inlining in the first place.

That’s where Trys comes in. He shared a nifty technique he uses in this exact situation: put the SVG source into a custom property!

:root {
    --firstSVG: url('data:image/svg+xml;utf8,<svg> ... </svg>');
    --secondSVG: url('data:image/svg+xml;utf8,<svg> ... </svg>');
}

Then you can reference those in your background-image declarations:

.myComponent {
    background-image: var(--firstSVG);
}
.myComponent--variant {
    background-image: var(--firstSVG), var(--secondSVG);
}

Brilliant! Not only does this remove any duplication of the SVG source, it also makes your CSS nice and readable: no more big blobs of SVG source code in the middle of your style sheet.

You might be wondering what will happen in older browsers that don’t support CSS custom properties (that would be Internet Explorer 11). Those browsers won’t get any background image. Which is fine. It’s a background image. Therefore it’s decoration. If it were an important image, it wouldn’t be in the background.

Progressive enhancement, innit?