Skip to content

feat(cdk/menu): expose transform origin as css variable #32439

@goetzrobin

Description

@goetzrobin

Feature Description

It would be great if the CDK Menu could expose the transform origin as a CSS variable e.g. --cdk-menu-transform-origin: top left

It is currently impossible to make menus built with CDK menu aware of the correct transform origin.

Angular Material Menus sets the transform origin direction as part of their positionStrategy, which is built with withTransformOriginOn.

Angular Material Code

  private _getOverlayConfig(menu: MatMenuPanel): OverlayConfig {
    return new OverlayConfig({
      positionStrategy: createFlexibleConnectedPositionStrategy(
        this._injector,
        this._getOverlayOrigin(),
      )
        .withLockedPosition()
        .withGrowAfterOpen()
        .withTransformOriginOn('.mat-menu-panel, .mat-mdc-menu-panel'),
      backdropClass: menu.backdropClass || 'cdk-overlay-transparent-backdrop',
      panelClass: menu.overlayPanelClass,
      scrollStrategy: this._scrollStrategy(),
      direction: this._dir || 'ltr',
      disableAnimations: this._animationsDisabled,
    });
  }

private _getOverlayConfig(menu: MatMenuPanel): OverlayConfig {

The CDK instead does not allow us to pass a selector, which can be used with withTransformOriginOn.

Angular CDK Code

 /** Get the configuration object used to create the overlay. */
  private _getOverlayConfig() {
    return new OverlayConfig({
      positionStrategy: this._getOverlayPositionStrategy(),
      scrollStrategy: this.menuScrollStrategy(),
      direction: this._directionality || undefined,
    });
  }

  /** Build the position strategy for the overlay which specifies where to place the menu. */
  private _getOverlayPositionStrategy(): FlexibleConnectedPositionStrategy {
    return createFlexibleConnectedPositionStrategy(this._injector, this._elementRef)
      .withLockedPosition()
      .withFlexibleDimensions(false)
      .withPositions(this._getOverlayPositions());
  }

  /** Get the preferred positions for the opened menu relative to the menu item. */
  private _getOverlayPositions(): ConnectedPosition[] {
    return (
      this.menuPosition ??
      (!this._parentMenu || this._parentMenu.orientation === 'horizontal'
        ? STANDARD_DROPDOWN_BELOW_POSITIONS
        : STANDARD_DROPDOWN_ADJACENT_POSITIONS)
    );
  }

/** Get the configuration object used to create the overlay. */

However I still need to know the exact selector of the element I will use this on.
Building a headless component library I'd much rather be able to access this from a CSS variable.
My current workaround for dialogs is to set it on the .cdk-overlay-pane and then use a renderer call to transform it to a CSS variable.

For Menu's I am simply stuck with guessing a possible transform origin, which does not work well as the position can vary based on how much space is available, e.g. not enough space to the right of my context-menu trigger location and the menu moves to the left, but I cannot react to that.

Use Case

I am building a headless component library: https://github.com/spartan-ng/spartan (currently supporting v20 & v21)
Our menu is built on top of the Angular CDK menu.
This missing feature makes it impossible to build reliably transform origin aware menus.

Example below is our context menu:
As you see the transform origin is using the default center center, which is incorrect as we expect the animation to start on the top right on the first click or the top left on the second.

Screen.Recording.2025-11-29.at.2.05.59.PM.mov

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureThis issue represents a new feature or feature request rather than a bug or bug fixneeds triageThis issue needs to be triaged by the team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions