Scrollbar πŸ”„ `width` glitch in Embedded notebooks.

In embedded notebooks there is an edge case with Input.table (or any other viewof depending on width)

Here is the flow of events:

  1. User selects a row in Inputs.table β†’
  2. Content with the selection details is rendered β†’
  3. Vertical scrollbar appears, if content doesn’t fit into the screen β†’
  4. width changes because of the scrollbar β†’
  5. Inputs.table rerenders, because it has cells depending on width β†’
  6. User selection disappears β†’
  7. Content disappears β†’
  8. Scrollbar disappears β†’
  9. width changes β†’ …

Better to see the example: https://observablehq.com/embed/@oluckyman/scrollbar-width-demo?cell=*

When you select 8 cylinders, the scrollbar appears but then disappears after the table re-renders without the selection.

I tried to style html to have overflow: scroll, but didn’t work.
So my workaround for now is to add giant white-space footer, that makes scrollbars to appear on any screen.

Maybe there is a better approach?

Hi,
That sounds like a problem!
What browser are you using? I tested this in Safari and Chrome on MacOS and did not see this behavior. My browser window reserves the spot for the scrollbar it seems (probably a setting I have somewhere, but perhaps that is actually the default behavior).

That’s the expected behavior. You’d also clear your selection if you’d resize the browser while viewing the notebook normally.

width should only be used when you cannot achieve responsive behavior through CSS, e.g. inside a canvas or SVG.

In your case you can simply use

    cylinders: (d) => html`<div style="width: ${d / 8 * 100}%; background: lightgray">${d}</div>`

where β€œ8” is the highest number of cylinders in your dataset.

For more complex applications see e.g. CSS calc() or the notebook Efficient Responsiveness.

Thanks for the suggestion!

It was an artificial example, in my real case I use Plot to render full-width cells

So, CSS will not work here.

But I got your idea, that I can remove width from the equation. Maybe by storing initial width and use it, sacrificing window resize rerenders.
Something like this:

initialWidth = {
  return this || width
}

yeah, there is a setting to preserve scrollbars in macOS, but I believe it’s turned off by default.

There’s no need to reference width at all, you can use document.body.clientWidth directly (you can find the implementation of width here).

You may also want to look into ResizeObserver.

1 Like