Is there an existing issue for this?
Which package(s) or projects are affected?
React (@videojs/react)
Browser/OS/Node environment
Browser: Chromium 148.0.0.0 (headless, via Playwright), DPR 1 - also seen in desktop Chrome on a Retina display (DPR 2), where the fractional-device-pixel variant shows along straight edges too
OS: Linux x86_64 (kernel 6.8)
Node version: 24.18.0 (not relevant — rendering bug, no CLI involvement)
npm version: 11.16.0
Description
Current behavior
The video skins round every layer independently: the skin root uses border-radius plus
overflow: clip, and the light-DOM <video> and poster <img> take border-radius: inherit.
The root also paints a hardcoded opaque stage, background: oklch(0 0 0) on
.media-default-skin--video, with no CSS variable to change it.
Each rounded edge is antialiased separately. A corner boundary pixel therefore composites as
content plus black plus page, instead of content plus page: at a half-covered pixel roughly
30 to 40 percent black is mixed in. Over bright content this renders as a thin dark arc tracing
every corner. Over dark content it is invisible, which makes it look intermittent.
In real layouts (percentage sizing, DPR above 1, the composited video layer rasterizing at
fractional device offsets) the same contamination also shows along straight edges as a faint
line around the whole player. Sampling a production page: page pixel 248, boundary pixel 122,
adjacent content pixel 144. The boundary pixel is darker than both of its neighbours, which
rules out ordinary antialiasing between the two.
Expected behavior
Edge pixels of a rounded player blend content directly into the page with no dark rim.
Minimal reproduction (no player needed)
<body style="background:#f8f8f8; margin:40px">
<!-- BUG: mirrors the skin structure: rounded clip + black stage, inner content border-radius: inherit -->
<div style="width:640px; aspect-ratio:16/9; border-radius:14px;
overflow:clip; background:oklch(0 0 0)">
<div style="width:100%; height:100%; border-radius:inherit; background:#fff"></div>
</div>
<!-- FIXED: single clip-path mask, no internal rounding -->
<div style="width:640px; aspect-ratio:16/9;
clip-path:inset(0 round 14px); overflow:clip; background:oklch(0 0 0)">
<div style="width:100%; height:100%; background:#fff"></div>
</div>
</body>
Zoom into the first box's corners: dark arc. The second box is the identical stack rounded once
by a clip-path mask, and its corners are clean.
Workaround we ship in production
Zero the skin's internal rounding natively (--media-border-radius: 0 on the skin root, the same
state the skin itself uses in fullscreen) and round once on our wrapper with
clip-path: inset(0 round 14px), a single mask over the finished composite. Verified pixel-level.
Note this is not the clip-path variant dismissed in #1449. That test used inset(...) without
round, which is why it broke the corners there, and #1449 itself is a different bug
(WebKit aspect-ratio sub-pixel gap).
Suggested fix (either one removes the need for the workaround)
- Round the skins with a single mask,
clip-path: inset(0 round var(--media-border-radius))
on the root, instead of per-layer border-radius and overflow rounding. Fullscreen already
zeroes the radius, and top-layer elements escape ancestor clips, so it composes cleanly.
- And/or expose the stage color as
background: var(--media-background, oklch(0 0 0)) on the
skin roots, so integrators can match the stage to the page for seamless or decorative
placements such as hero films.
Affects the default video, minimal, and live skins. Present in 10.0.0-beta.26 and unchanged
through 10.0.0-beta.32. The affected skin CSS (dist/*/presets/*/skin.css) is shared with the
HTML package, so this applies there too.
Reduced test case
No response
Steps to reproduce
- Render bright video content (a white intro card is worst case) in any v10 skin with
--media-border-radius set, on a light page. Alternatively use the 15-line HTML in the description, which mirrors the skin's layer structure without a player.
- Zoom into any corner of the player, with browser zoom or a magnified screenshot.
- Observe a thin dark arc tracing the rounded corner between the content and the page. Sample the pixels: the boundary pixel is darker than both the content and the page next to it.
- Repeat with dark content: the arc becomes invisible, confirming it is the black stage bleeding through the antialiased rounded edges, not the content itself.
Current Behavior
A thin dark hairline traces the player's rounded corners over bright content, because every layer (skin root via border-radius plus overflow: clip, light-DOM video and poster img via border-radius: inherit) is antialiased separately over the hardcoded opaque stage (background: oklch(0 0 0), no variable). On fractional device-pixel layouts (DPR 2, percentage sizing) the line also shows along the straight edges, around the whole player.
Expected Behavior
Edge pixels of a rounded player blend the content directly into the page with no dark rim, as produced by rounding the composed player once (for example clip-path: inset(0 round var(--media-border-radius)) on the root), or by letting integrators set the stage color via a variable so it can match the page.
Errors
No response
What version of the package are you using?
v10.0.0-beta.26
Is there an existing issue for this?
Which package(s) or projects are affected?
React (@videojs/react)
Browser/OS/Node environment
Browser: Chromium 148.0.0.0 (headless, via Playwright), DPR 1 - also seen in desktop Chrome on a Retina display (DPR 2), where the fractional-device-pixel variant shows along straight edges too
OS: Linux x86_64 (kernel 6.8)
Node version: 24.18.0 (not relevant — rendering bug, no CLI involvement)
npm version: 11.16.0
Description
Current behavior
The video skins round every layer independently: the skin root uses
border-radiusplusoverflow: clip, and the light-DOM<video>and poster<img>takeborder-radius: inherit.The root also paints a hardcoded opaque stage,
background: oklch(0 0 0)on.media-default-skin--video, with no CSS variable to change it.Each rounded edge is antialiased separately. A corner boundary pixel therefore composites as
content plus black plus page, instead of content plus page: at a half-covered pixel roughly
30 to 40 percent black is mixed in. Over bright content this renders as a thin dark arc tracing
every corner. Over dark content it is invisible, which makes it look intermittent.
In real layouts (percentage sizing, DPR above 1, the composited video layer rasterizing at
fractional device offsets) the same contamination also shows along straight edges as a faint
line around the whole player. Sampling a production page: page pixel 248, boundary pixel 122,
adjacent content pixel 144. The boundary pixel is darker than both of its neighbours, which
rules out ordinary antialiasing between the two.
Expected behavior
Edge pixels of a rounded player blend content directly into the page with no dark rim.
Minimal reproduction (no player needed)
Zoom into the first box's corners: dark arc. The second box is the identical stack rounded once
by a
clip-pathmask, and its corners are clean.Workaround we ship in production
Zero the skin's internal rounding natively (
--media-border-radius: 0on the skin root, the samestate the skin itself uses in fullscreen) and round once on our wrapper with
clip-path: inset(0 round 14px), a single mask over the finished composite. Verified pixel-level.Note this is not the
clip-pathvariant dismissed in #1449. That test usedinset(...)withoutround, which is why it broke the corners there, and #1449 itself is a different bug(WebKit aspect-ratio sub-pixel gap).
Suggested fix (either one removes the need for the workaround)
clip-path: inset(0 round var(--media-border-radius))on the root, instead of per-layer
border-radiusandoverflowrounding. Fullscreen alreadyzeroes the radius, and top-layer elements escape ancestor clips, so it composes cleanly.
background: var(--media-background, oklch(0 0 0))on theskin roots, so integrators can match the stage to the page for seamless or decorative
placements such as hero films.
Affects the default video, minimal, and live skins. Present in 10.0.0-beta.26 and unchanged
through 10.0.0-beta.32. The affected skin CSS (
dist/*/presets/*/skin.css) is shared with theHTML package, so this applies there too.
Reduced test case
No response
Steps to reproduce
--media-border-radiusset, on a light page. Alternatively use the 15-line HTML in the description, which mirrors the skin's layer structure without a player.Current Behavior
A thin dark hairline traces the player's rounded corners over bright content, because every layer (skin root via border-radius plus overflow: clip, light-DOM video and poster img via border-radius: inherit) is antialiased separately over the hardcoded opaque stage (background: oklch(0 0 0), no variable). On fractional device-pixel layouts (DPR 2, percentage sizing) the line also shows along the straight edges, around the whole player.
Expected Behavior
Edge pixels of a rounded player blend the content directly into the page with no dark rim, as produced by rounding the composed player once (for example clip-path: inset(0 round var(--media-border-radius)) on the root), or by letting integrators set the stage color via a variable so it can match the page.
Errors
No response
What version of the package are you using?
v10.0.0-beta.26