Is this a regression?
The previous version in which this bug was not present was
17.3.5 (previews became native popovers in 17.3.6/17.3.7)
Description
Since v17.3.7 the drag preview is rendered as a native popover — preview.setAttribute('popover', 'manual') + showPopover() — which is great for stacking, but it also opts the preview into the spec-mandated UA popover styles.
Per the WHATWG HTML rendering section, every [popover] element gets:
[popover] {
position: fixed;
inset: 0;
width: fit-content;
height: fit-content;
margin: auto;
border: solid;
padding: 0.25em;
overflow: auto; /* 👈 */
color: CanvasText;
background-color: Canvas;
}
CDK already neutralizes most of that block in src/cdk/drag-drop/resets.scss:
@layer cdk-resets {
.cdk-drag-preview {
background: none;
border: none;
padding: 0;
color: inherit;
// Chrome sets a user agent style of `inset: 0` which combined
// with `align-self` can break the positioning (see #29809).
inset: auto;
}
}
…but overflow was never included, so every drag preview is silently a scroll container (getComputedStyle(preview).overflow === 'auto').
That stays invisible only while the preview's content happens to fit its box exactly. CDK sizes the default preview with inline width/height measured from the original element (matchElementSize), so any app styling on .cdk-drag-preview that changes the box — a 1px border, some padding — combined with the near-universal * { box-sizing: border-box } reset shrinks the content box below the measured content.
The result is 1–2px of scrollable overflow, and a scrollbar renders on the floating "photo" of the dragged element and rides along with the pointer. The scroll container exists in every engine that I tested (Firefox ships the identical UA rule, citing the same spec anchor); Chromium's scrollbar presentation just makes it the most visible.
Related issues:
Following the #29809 pattern, it looks like the reset could be completed with an explicit overflow declaration in the same resets.scss block (e.g. overflow: clip).
Workaround:
For anyone hitting this today — simply complete the reset app-side:
.cdk-drag-preview {
overflow: clip;
}
Reproduction
StackBlitz link: https://stackblitz.com/edit/components-issue-starter-wr9aehf8?file=src%2Fglobal_styles.css
Steps to reproduce:
- Open the StackBlitz preview in a Chromium browser (Chrome/Edge) and drag any row, holding it mid-drag.
- Look at the right edge of the floating preview: a vertical scrollbar is rendered. The console also logs the preview's computed overflow (
auto auto) and its overflow geometry (scrollHeight > clientHeight) mid-drag.
The repro is the docs sorting example plus two commonplace styles: a global * { box-sizing: border-box } reset and a 1px border on .cdk-drag-preview — the same effective styling the docs example produced on its preview when #29419 was filed.
Even with no author styling at all, the preview is still a scroll container (getComputedStyle reports overflow: auto); the border merely gives the overflow a visible 1–2px to show.
Expected Behavior
The drag preview should paint exactly like the dragged element (plus any intentional .cdk-drag-preview styling) and should never be a scroll container. The UA popover styles should be fully neutralized by @layer cdk-resets the way background, border, padding, color, and inset already are — so an author border or padding on the preview can never produce scrollbars mid-drag.
Actual Behavior
getComputedStyle(document.querySelector('.cdk-drag-preview')).overflow reports auto mid-drag — the UA popover style survives the reset. With a 1px preview border under box-sizing: border-box, measured while dragging the second row of the repro: scrollHeight 48 vs clientHeight 47, with the rendered scrollbar consuming a 15px gutter (offsetWidth 418 vs clientWidth 401 + 2px of borders).
Environment
- Angular: 22.0.7
- CDK/Material: 22.0.5 (still reproducible against
main — resets.scss has no overflow reset)
- Browser(s): Chrome 150 (any Chromium; Firefox has the same UA rule but paints no classic scrollbar)
- Operating System (e.g. Windows, macOS, Ubuntu): macOS
Is this a regression?
The previous version in which this bug was not present was
17.3.5 (previews became native popovers in 17.3.6/17.3.7)
Description
Since v17.3.7 the drag preview is rendered as a native popover —
preview.setAttribute('popover', 'manual')+showPopover()— which is great for stacking, but it also opts the preview into the spec-mandated UA popover styles.Per the WHATWG HTML rendering section, every
[popover]element gets:CDK already neutralizes most of that block in
src/cdk/drag-drop/resets.scss:…but
overflowwas never included, so every drag preview is silently a scroll container (getComputedStyle(preview).overflow === 'auto').That stays invisible only while the preview's content happens to fit its box exactly. CDK sizes the default preview with inline
width/heightmeasured from the original element (matchElementSize), so any app styling on.cdk-drag-previewthat changes the box — a 1px border, some padding — combined with the near-universal* { box-sizing: border-box }reset shrinks the content box below the measured content.The result is 1–2px of scrollable overflow, and a scrollbar renders on the floating "photo" of the dragged element and rides along with the pointer. The scroll container exists in every engine that I tested (Firefox ships the identical UA rule, citing the same spec anchor); Chromium's scrollbar presentation just makes it the most visible.
Related issues:
border: noneto the example's CSS — the underlying UA style is still un-reset, so any app that styles its own preview the same way still hits it.inset: 0) leaking through, fixed by extending this same reset withinset: auto.cdk-resetslayer to neutralize UA popovercolor/background/border/padding..cdk-overlay-popover { … overflow: visible; … }insrc/cdk/overlay/_index.scss.Following the #29809 pattern, it looks like the reset could be completed with an explicit
overflowdeclaration in the sameresets.scssblock (e.g.overflow: clip).Workaround:
For anyone hitting this today — simply complete the reset app-side:
Reproduction
StackBlitz link: https://stackblitz.com/edit/components-issue-starter-wr9aehf8?file=src%2Fglobal_styles.css
Steps to reproduce:
auto auto) and its overflow geometry (scrollHeight > clientHeight) mid-drag.The repro is the docs sorting example plus two commonplace styles: a global
* { box-sizing: border-box }reset and a 1px border on.cdk-drag-preview— the same effective styling the docs example produced on its preview when #29419 was filed.Even with no author styling at all, the preview is still a scroll container (
getComputedStylereportsoverflow: auto); the border merely gives the overflow a visible 1–2px to show.Expected Behavior
The drag preview should paint exactly like the dragged element (plus any intentional
.cdk-drag-previewstyling) and should never be a scroll container. The UA popover styles should be fully neutralized by@layer cdk-resetsthe waybackground,border,padding,color, andinsetalready are — so an author border or padding on the preview can never produce scrollbars mid-drag.Actual Behavior
getComputedStyle(document.querySelector('.cdk-drag-preview')).overflowreportsautomid-drag — the UA popover style survives the reset. With a 1px preview border underbox-sizing: border-box, measured while dragging the second row of the repro:scrollHeight 48vsclientHeight 47, with the rendered scrollbar consuming a 15px gutter (offsetWidth 418vsclientWidth 401+ 2px of borders).Environment
main—resets.scsshas nooverflowreset)