diff --git a/src/cdk/listbox/listbox.ts b/src/cdk/listbox/listbox.ts
index b4405757ea89..d25fe9daa6ac 100644
--- a/src/cdk/listbox/listbox.ts
+++ b/src/cdk/listbox/listbox.ts
@@ -9,6 +9,7 @@
 import {
   _IdGenerator,
   ActiveDescendantKeyManager,
+  FocusMonitor,
   Highlightable,
   ListKeyManagerOption,
 } from '../a11y';
@@ -243,7 +244,6 @@ export class CdkOption<T = unknown> implements ListKeyManagerOption, Highlightab
     '[attr.aria-multiselectable]': 'multiple',
     '[attr.aria-activedescendant]': '_getAriaActiveDescendant()',
     '[attr.aria-orientation]': 'orientation',
-    '(focus)': '_handleFocus()',
     '(keydown)': '_handleKeydown($event)',
     '(focusout)': '_handleFocusOut($event)',
     '(focusin)': '_handleFocusIn()',
@@ -269,6 +269,7 @@ export class CdkListbox<T = unknown> implements AfterContentInit, OnDestroy, Con
   }
   private _id: string;
   private _generatedId = inject(_IdGenerator).getId('cdk-listbox-');
+  private _focusMonitor = inject(FocusMonitor);
 
   /** The tabindex to use when the listbox is enabled. */
   @Input('tabindex')
@@ -462,6 +463,7 @@ export class CdkListbox<T = unknown> implements AfterContentInit, OnDestroy, Con
     }
 
     this._initKeyManager();
+    this._handleFocus();
 
     // Update the internal value whenever the options or the model value changes.
     merge(this.selectionModel.changed, this.options.changes)
@@ -477,6 +479,7 @@ export class CdkListbox<T = unknown> implements AfterContentInit, OnDestroy, Con
   }
 
   ngOnDestroy() {
+    this._focusMonitor.stopMonitoring(this.element);
     this._cleanupWindowBlur?.();
     this.listKeyManager?.destroy();
     this.destroyed.next();
@@ -698,15 +701,26 @@ export class CdkListbox<T = unknown> implements AfterContentInit, OnDestroy, Con
 
   /** Called when the listbox receives focus. */
   protected _handleFocus() {
-    if (!this.useActiveDescendant) {
-      if (this.selectionModel.selected.length > 0) {
-        this._setNextFocusToSelectedOption();
-      } else {
-        this.listKeyManager.setNextItemActive();
-      }
+    this._focusMonitor
+      .monitor(this.element, false)
+      .pipe(takeUntil(this.destroyed))
+      .subscribe(focusOrigin => {
+        // Don't forward focus on mouse interactions, because it can
+        // mess with the user's scroll position. See #30900.
+        if (focusOrigin === 'mouse' || focusOrigin === null) {
+          return;
+        }
 
-      this._focusActiveOption();
-    }
+        if (!this.useActiveDescendant) {
+          if (this.selectionModel.selected.length > 0) {
+            this._setNextFocusToSelectedOption();
+          } else {
+            this.listKeyManager.setNextItemActive();
+          }
+
+          this._focusActiveOption();
+        }
+      });
   }
 
   /** Called when the user presses keydown on the listbox. */
diff --git a/src/material/select/select.html b/src/material/select/select.html
index 6eaecee7f5c3..9b02ddfd892e 100644
--- a/src/material/select/select.html
+++ b/src/material/select/select.html
@@ -40,6 +40,7 @@
   [cdkConnectedOverlayPositions]="_positions"
   [cdkConnectedOverlayWidth]="_overlayWidth"
   [cdkConnectedOverlayFlexibleDimensions]="true"
+  [cdkConnectedOverlayGrowAfterOpen]="true"
   (detach)="close()"
   (backdropClick)="close()"
   (overlayKeydown)="_handleOverlayKeydown($event)">