fix(theme): prevent code blocks painting over next paragraph

Pair overflow-x: auto with overflow-y: hidden so the wrapper does not
become a vertical scrollport. That stops WebKit painting the block and
its scrollbar over the following paragraph.
pull/5478/head
Michał Furgała 1 day ago
parent 56fa6c9df1
commit fefa10e7ec

@ -362,3 +362,37 @@ describe('Image Lazy Loading', () => {
expect(await img.getAttribute('loading')).toBe('lazy') expect(await img.getAttribute('loading')).toBe('lazy')
}) })
}) })
describe('Wide code blocks', () => {
beforeEach(async () => {
await goto('/markdown-extensions/wide-code')
})
test('do not paint over the following paragraph', async () => {
const block = page.locator('.vp-doc div[class*="language-"]').first()
const paragraph = page.locator('#after-wide-code')
expect(await block.count()).toBe(1)
expect(await paragraph.count()).toBe(1)
const overflowY = await block.evaluate(
(el) => getComputedStyle(el).overflowY
)
expect(overflowY).toBe('hidden')
const pre = block.locator('pre')
expect(await pre.evaluate((el) => el.scrollWidth > el.clientWidth)).toBe(
true
)
const [blockBox, paragraphBox] = await Promise.all([
block.boundingBox(),
paragraph.boundingBox()
])
expect(blockBox).toBeTruthy()
expect(paragraphBox).toBeTruthy()
expect(paragraphBox!.y).toBeGreaterThanOrEqual(
blockBox!.y + blockBox!.height - 1
)
})
})

@ -0,0 +1,9 @@
# Wide Code Block
A paragraph before the code.
```js
const wide = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
```
<p id="after-wide-code">A paragraph after the wide code block.</p>

@ -0,0 +1,31 @@
import { readFileSync } from 'node:fs'
import { fileURLToPath } from 'node:url'
const vpDocCss = readFileSync(
fileURLToPath(
new URL(
'../../../../src/client/theme-default/styles/components/vp-doc.css',
import.meta.url
)
),
'utf8'
)
function ruleFor(css: string, selector: string): string {
const start = css.indexOf(selector)
if (start === -1) {
throw new Error(`missing selector ${selector}`)
}
const open = css.indexOf('{', start)
const close = css.indexOf('}', open)
return css.slice(open + 1, close)
}
describe('client/theme-default/code-overflow', () => {
test('code block wrappers clip vertical overflow', () => {
const rule = ruleFor(vpDocCss, ".vp-doc div[class*='language-']")
expect(rule).toMatch(/overflow-x:\s*auto/)
expect(rule).toMatch(/overflow-y:\s*hidden/)
})
})

@ -354,7 +354,11 @@
position: relative; position: relative;
margin: 1rem -1.5rem; margin: 1rem -1.5rem;
background-color: var(--vp-code-block-bg); background-color: var(--vp-code-block-bg);
/* pair overflow-x so overflow-y does not compute to auto; otherwise the
wrapper becomes a vertical scrollport and WebKit can paint the block
(and its scrollbar) over the following paragraph */
overflow-x: auto; overflow-x: auto;
overflow-y: hidden;
transition: background-color 0.5s; transition: background-color 0.5s;
} }

Loading…
Cancel
Save