Vitrinev1.0.4

Styles, scripts and imports

How an example’s CSS stays inside it, how its script runs, and how it imports a library by its npm name.

Styles stay inside the example

Vitrine wraps an example’s style.css in @scope (opens in a new tab) when it runs:

css
@scope ([data-example="demo"]) {
  /* your style.css */
}

So a plain button { … } styles that example’s buttons and nothing else on the page, and two examples can use the same class names. The tab shows your file without the wrapper.

An example’s rules come after the theme’s, so they win over it. The theme gives buttons inside a frame a look of their own (filled, in the accent colour), which your style can replace. The theme’s colours are custom properties you can use, like var(--accent) and var(--bg-soft) (all are listed in Customizing): an example that uses them follows light and dark mode.

@scope works in all current major browsers. An older browser ignores the whole style, and the example runs unstyled.

Scripts run as modules

script.js goes into the page as <script type="module">. That means:

Importing a library by its npm name

Readers of your docs will write import { thing } from "my-lib" after npm install my-lib. Your examples should say the same. An import map (opens in a new tab) tells the browser where the name points:

hugo.toml
[params.importmap]
  my-lib = "https://cdn.jsdelivr.net/npm/my-lib@1.2.0/dist/my-lib.js"

Then this runs as written:

script.js
import { thing } from "my-lib";

The map can point at:

The import map is on every page, so your own scripts can use it too. If the library has a stylesheet, add it to every page with params.stylesheets:

hugo.toml
[params]
  stylesheets = ["https://cdn.jsdelivr.net/npm/my-lib@1.2.0/dist/my-lib.css"]

The photo viewer example imports dialog-lightbox (opens in a new tab) this way.