66import * as DOM from '../../../../base/browser/dom.js' ;
77import { CancellationToken } from '../../../../base/common/cancellation.js' ;
88import { Emitter , Event } from '../../../../base/common/event.js' ;
9- import { DisposableStore , IDisposable , MutableDisposable } from '../../../../base/common/lifecycle.js' ;
9+ import { DisposableStore , IDisposable , MutableDisposable , toDisposable } from '../../../../base/common/lifecycle.js' ;
1010import { isWeb } from '../../../../base/common/platform.js' ;
1111import { generateUuid } from '../../../../base/common/uuid.js' ;
1212import * as nls from '../../../../nls.js' ;
@@ -71,6 +71,8 @@ export class WebviewEditor extends EditorPane {
7171 this . synchronizeWebviewContainerDimensions ( this . webview ) ;
7272 }
7373 } ) ) ;
74+
75+
7476 }
7577
7678 private get webview ( ) : IOverlayWebview | undefined {
@@ -188,6 +190,26 @@ export class WebviewEditor extends EditorPane {
188190
189191 this . synchronizeWebviewContainerDimensions ( input . webview ) ;
190192 this . _webviewVisibleDisposables . add ( this . trackFocus ( input . webview ) ) ;
193+
194+ // Use CSS Anchor Positioning to automatically track position changes.
195+ // The editor element's parent acts as the CSS anchor, and the webview
196+ // container is tethered to it.
197+ // Falls back to explicit pixel positioning via layoutWebviewOverElement
198+ // when anchor positioning is not supported.
199+ if ( this . _element ?. parentElement && CSS . supports ( '(top: anchor(top))' ) ) {
200+ const anchorName = `--${ this . _element . id } ` ;
201+ this . _element . parentElement . style . setProperty ( 'anchor-name' , anchorName ) ;
202+ const container = input . webview . container ;
203+ container . style . setProperty ( 'position-anchor' , anchorName ) ;
204+ container . style . setProperty ( 'top' , 'anchor(top)' ) ;
205+ container . style . setProperty ( 'left' , 'anchor(left)' ) ;
206+ this . _webviewVisibleDisposables . add ( toDisposable ( ( ) => {
207+ this . _element ?. parentElement ?. style . removeProperty ( 'anchor-name' ) ;
208+ container . style . removeProperty ( 'position-anchor' ) ;
209+ container . style . removeProperty ( 'top' ) ;
210+ container . style . removeProperty ( 'left' ) ;
211+ } ) ) ;
212+ }
191213 }
192214
193215 private synchronizeWebviewContainerDimensions ( webview : IOverlayWebview , dimension ?: DOM . Dimension ) {
@@ -203,6 +225,14 @@ export class WebviewEditor extends EditorPane {
203225 clippingContainer = this . _workbenchLayoutService . getContainer ( this . window , Parts . EDITOR_PART ) ;
204226 }
205227 webview . layoutWebviewOverElement ( this . _element . parentElement ! , dimension , clippingContainer ) ;
228+
229+ // Re-apply CSS anchor positioning after layoutWebviewOverElement sets
230+ // explicit pixel values for top/left. This lets the browser handle
231+ // position tracking between explicit layout calls.
232+ if ( CSS . supports ( '(top: anchor(top))' ) && this . _element . parentElement ?. style . getPropertyValue ( 'anchor-name' ) ) {
233+ webview . container . style . setProperty ( 'top' , 'anchor(top)' ) ;
234+ webview . container . style . setProperty ( 'left' , 'anchor(left)' ) ;
235+ }
206236 }
207237
208238 private trackFocus ( webview : IOverlayWebview ) : IDisposable {
0 commit comments