Append to element
The dropdown panel renders in an Angular CDK overlay and paints in the browser's top layer wherever the native Popover API is supported, so the clipping and stacking problems that used to require appendTo are solved out of the box. The appendTo input now controls where the overlay lives in the DOM: pass any css selector when ancestor-scoped styles, a stacking context, or focus containment require the panel to be a descendant of a specific element. Positioning stays viewport-based either way, and the panel keeps following the select while scrolling.
Clipped and scrollable containers
Section titled “Clipped and scrollable containers”import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core';import { DataService } from '../data.service';import { FormsModule } from '@angular/forms';import { AsyncPipe } from '@angular/common';import { NgSelectComponent } from '@ng-select/ng-select';
@Component({ selector: 'ng-append-to-example', templateUrl: './append-to-example.component.html', styleUrls: ['./append-to-example.component.scss'], changeDetection: ChangeDetectionStrategy.Eager, imports: [NgSelectComponent, FormsModule, AsyncPipe],})export class AppendToExampleComponent implements OnInit { private dataService = inject(DataService);
people: any = []; selected: any; selected2: any; selected3: any; selected4: any;
ngOnInit() { this.people = this.dataService.getPeople(); }}<div class="alert alert-info"> The dropdown panel renders in an <a href="https://material.angular.dev/cdk/overlay/overview" target="_blank">Angular CDK overlay</a> and paints in the browser's top layer wherever the native Popover API is supported, so clipping and stacking are handled without configuration. Use <code>appendTo</code> only when the panel must live inside a specific element in the DOM — e.g. to inherit ancestor-scoped styles or satisfy focus containment.</div>
<p> Containers with fixed height and hidden overflow used to clip the dropdown unless you appended it to another element. With overlay rendering the panel escapes the container automatically:</p>
<div class="overflow-box"> <ng-select [items]="people | async" bindLabel="company" placeholder="Select item" [(ngModel)]="selected"> </ng-select></div>
<br /><p> With <code>appendTo</code> the overlay becomes a DOM descendant of the selected element, so ancestor-scoped css (like a theme class on the container) applies to the panel. Positioning is unchanged:</p>
<div class="overflow-box"> <ng-select [items]="people | async" bindLabel="company" appendTo="body" placeholder="Select item" [(ngModel)]="selected2"> </ng-select></div>
<br /><p>Inside a scrollable container the panel stays anchored to the select while you scroll — no configuration needed:</p>
<div class="scrollable-box"> <div class="overflow-box"> <ng-select [items]="people | async" bindLabel="company" placeholder="Select item" [(ngModel)]="selected3"> </ng-select> </div></div>
<br /><p>Set <code>closeOnScroll</code> to close the panel instead when the page or an ancestor container scrolls:</p>
<div class="scrollable-box"> <div class="overflow-box"> <ng-select [items]="people | async" bindLabel="company" placeholder="Select item" [closeOnScroll]="true" [(ngModel)]="selected4"> </ng-select> </div> <div style="height: 600px"></div></div>
<div style="height: 100px"></div>// as we are using ViewEncapsulation.ShadowDom we need to make sure all styles are accessible within this component// @import "~@ng-select/ng-select/themes/default.theme.css";
.overflow-box { padding: 5px; height: 100px; border: 1px solid #999; overflow: hidden;}
.scrollable-box { position: relative; height: 400px; overflow: auto;}Bootstrap modal
Section titled “Bootstrap modal”The overlay renders in the browser's top layer (native Popover API) wherever supported, so the panel paints above the modal without any configuration:
import { AsyncPipe } from '@angular/common';import { Component, TemplateRef, inject, ChangeDetectionStrategy } from '@angular/core';import { FormsModule } from '@angular/forms';import { NgbModal } from '@ng-bootstrap/ng-bootstrap';import { NgSelectComponent } from '@ng-select/ng-select';
import { DataService, Person } from '../data.service';
@Component({ selector: 'ng-modal-ng-bootstrap-example', templateUrl: './modal-ng-bootstrap-example.component.html', styleUrls: ['./modal-ng-bootstrap-example.component.scss'], changeDetection: ChangeDetectionStrategy.Eager, imports: [NgSelectComponent, FormsModule, AsyncPipe],})export class ModalNgBootstrapExampleComponent { private readonly modalService = inject(NgbModal);
readonly people$ = inject(DataService).getPeople(); selected: Person | null = null;
openModal(content: TemplateRef<unknown>): void { this.modalService.open(content); }}<p> <code>ng-select</code> inside an <strong>ng-bootstrap</strong> modal. The dropdown panel is appended to <code>body</code> by default so it stacks above the modal and is not clipped by the modal content.</p>
<button type="button" class="btn btn-primary" (click)="openModal(modalContent)">Open modal</button>
<ng-template #modalContent let-c="close" let-d="dismiss"> <div class="modal-header"> <h4 class="modal-title">Select in modal</h4> <button type="button" class="btn-close" aria-label="Close" (click)="d()"></button> </div> <div class="modal-body"> <ng-select [items]="people$ | async" bindLabel="company" placeholder="Select item" [(ngModel)]="selected"> </ng-select> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" (click)="d()">Close</button> <button type="button" class="btn btn-primary" (click)="c()">OK</button> </div></ng-template>:host { display: block;}Inputs used by the examples on this page:
| Input | Type | Default | Description |
|---|---|---|---|
| appendTo | string |
null | Append the dropdown overlay to any element using a css selector. Painting and positioning are unaffected; the target determines DOM containment (ancestor-scoped styles, focus enclosure). |
| [items] | Array<any> |
[] |
Items array |
| bindLabel | string |
label |
Object property to use for label. Default label |
| [closeOnScroll] | boolean |
false |
Close the dropdown when the page or an ancestor container scrolls. Default false |
| placeholder | string |
- |
Placeholder text. |
See the NgSelectComponent API reference for the complete list of inputs and outputs.