The last tech tip showed up over the summer, so I hope that we haven’t gotten into a routine where all the people interested in programming left, leaving me with an audience of people feeling alienated by occasional posts like this. On the other hand, I created the blog partly to keep notes that might help somebody else down the line, so you all need to expect some occasional chaos. The entropy in the blog title has more value here, for now.

Gears

In any case, I had some work to do on a project, recently, and got derailed by something strange in the browser: My logo showed with its stylized background image, but the name of the application appeared in browser-default block letters.

You probably want to know the following.

  • I stored the logo as an SVG, consisting of an icon-style image in the background and the application’s name in the foreground.
  • The foregrounded name uses a web font. I have that font stored on the same server.
  • The page shows the logo in an <img ...> element.
  • I previously saw the logo appear correctly, but that must have stopped recently.
  • Opening the URL of the logo itself displays the text correctly.
  • The problem doesn’t limit itself to fonts. Referencing a CSS file or embedded image has similar problems in experiments.

It looks something like this, boring as that seems.

<img src="images/logo.svg">

After some searching, I discovered that browsers have finished phasing out the ability of the img element’s target to reference further resources. As usual, I don’t much appreciate the pseudo-security reasons for the change—when the application controls all the assets, it seems irrational to claim that it represents a vulnerability, and if the browser shouldn’t trust indirection, then it probably shouldn’t trust the page itself—but the situation changed, and we need to live with it.

We have multiple solutions for this, none ideal.

For example, the solution recommended in official channels involves embedding all required assets in the SVG file in the editor. While that does solve the problem, it bloats what should stay small into something small carrying around a font that probably also sees use elsewhere in the application. That severely impacts page load times, so we can probably throw that out.

Alternatively, we can embed the SVG code into the webpage. That can work in some cases, but in the general case, that damages maintainability. Specifically, if that logo or other image changes, then someone needs to chase down every use, to update the code. Some frameworks have the idea of a rendering a “partial (document),” which can make this work, but that usually requires modifying the SVG code, which creates a different maintenance problem, where the file in use can’t go straight to the vector graphics software.

Instead of those, I converted the img element to an object element.

<object
  data="images/logo.svg"
  type="image/svg+xml"
>
</object>

Note that this takes more work than a search-and-replace pass. The object element works as a block, for example, and so needs a closing tag. It also requires a type attribute, and the URL goes in the data attribute instead of img’s src.

This doesn’t thrill me, either. The conversion, as mentioned, requires some care. The text in the image becomes part of the document, selectable with a click. And the browser seems to make strange assumptions about the image’s size.

However, it comes the closest to a “drop-in replacement” for the more straightforward img element, and doesn’t appear to create any speed or maintenance problems.

Most importantly, though, this all raises an interesting question: If either the HTML standard or the browser vendors have rescued us from some imminent threat by not allowing the contents of the img element to reference anything else, then what makes the object element safe enough to let it do whatever it likes?


Credits: The header image is work, technology, vintage, wheel, retro, clock by an anonymous PxHere photographer, made available under the terms of the CC0 1.0 Universal Public Domain Dedication.