🏠 back to Observable

Render differences summary page and real page


#1

No big deal, but summary page shows correct green Free Cultural Works logo:

while actual notebook forgets all colours and shows black Free Cultural Works logo:

Does this have to do with refs that need to be unique across notebooks?

Any ideas how to fix this (does it require to change the embedded SVG?).


#2

This is a difference in interpretation of the SVG spec across browsers, and can be fixed by changing the embedded SVG.

Code in Observable is evaluated in a sandboxed iframe for security that lives on a separate domain, such as:

https://mbostock.static.observableusercontent.com/worker/worker.6f71c375c3425c23eced43b3e198e6826c7b5624067563d62896626647ff7b20.html

In order to make relative links work, the document’s base URL is set to the notebook URL, such as:

https://beta.observablehq.com/@mbostock/19-circle

Unfortunately, in some browsers this affects the interpretation of SVG IRIs, the identifiers that are used within SVGs to refer to things like gradients, patterns, and reusable content. In these browsers, relative IRIs (such as #foo) don’t work on a page with a different document base URL because the SVG itself is interpreted as being on the original URL, while the IRI is interpreted as relative to the base URL.

Even if this browser inconsistency did not exist, the other problem (fundamental to the design of SVG) is that ids are global to the page, and thus when you import SVG content from another notebook, you can easily get namespace collisions.

This is why DOM.uid is in Observable’s standard library.

See this notebook for an example:

You can also use window.location to convert a relative IRI to an absolute IRI, but DOM.uid is still preferred because it will avoid namespace collisions when importing.


#3

.@mike that explains it :slight_smile:


#4

Hi @mike, thanks for your elaborative reply. I’ve run into this problem earlier (svg defs of gradients, to be used later on) using DOM.uid to create a universal and unique ID.

Now the next challenge is to elegantly and automatically tweak the embedded (and imported, foreign) SVG to inject and use these IDs. Any tip for that, too?

NEVER MIND! I fixed it: A bit of a hack, but I replaced all relevant id="_string_" in id="${_string_.id}", created corresponding const _string_ = DOM.uid("_string_"), and referred to it as ${_string_.toString()}.

See Creative Commons Logos.