diff --git a/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts b/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts index a84a12c0d17..801efe8c04f 100644 --- a/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts +++ b/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts @@ -7234,20 +7234,24 @@ export abstract class IgxGridBaseDirective implements GridType, if (!this._height) { return null; } + const styles = this.document.defaultView.getComputedStyle(this.nativeElement); const actualTheadRow = this.getTheadRowHeight(); const footerHeight = this.getFooterHeight(); const toolbarHeight = this.getToolbarHeight(); const pagingHeight = this.getPagingFooterHeight(); const groupAreaHeight = this.getGroupAreaHeight(); const scrHeight = this.getComputedHeight(this.scr.nativeElement); + const borderTop = parseFloat(styles.getPropertyValue('border-top-width')) || 0; + const borderBottom = parseFloat(styles.getPropertyValue('border-bottom-width')) || 0; + const renderedHeight = toolbarHeight + actualTheadRow + footerHeight + pagingHeight + groupAreaHeight + - scrHeight; + scrHeight + borderTop + borderBottom; let gridHeight = 0; if (this.isPercentHeight) { - const computed = this.document.defaultView.getComputedStyle(this.nativeElement).getPropertyValue('height'); + const computed = styles.getPropertyValue('height'); const autoSize = this._shouldAutoSize(renderedHeight); if (autoSize || computed.indexOf('%') !== -1) { const bodyHeight = this.getDataBasedBodyHeight(); diff --git a/projects/igniteui-angular/grids/grid/src/grid.component.spec.ts b/projects/igniteui-angular/grids/grid/src/grid.component.spec.ts index 3dbf7acad9b..2ccd8f07ee0 100644 --- a/projects/igniteui-angular/grids/grid/src/grid.component.spec.ts +++ b/projects/igniteui-angular/grids/grid/src/grid.component.spec.ts @@ -1307,6 +1307,30 @@ describe('IgxGrid Component Tests #grid', () => { expect(parseInt(window.getComputedStyle(domGrid).height, 10)).toBe(300); })); + it('should account for CSS border widths in body height calculation when height is percent #16640', fakeAsync(() => { + const fix = TestBed.createComponent(IgxGridWrappedInContComponent); + fix.componentInstance.outerHeight = 600; + fix.componentInstance.data = fix.componentInstance.fullData; + tick(); + fix.detectChanges(); + + const grid = fix.componentInstance.grid; + const calcHeightNoBorder = grid.calcHeight; + expect(calcHeightNoBorder).not.toBeNull(); + + // Apply a 2px border (top and bottom) to the grid's native element + grid.nativeElement.style.borderTop = '2px solid black'; + grid.nativeElement.style.borderBottom = '2px solid black'; + + // Trigger height recalculation + grid.reflow(); + fix.detectChanges(); + + // The fix ensures border widths are included in the rendered height calculation, + // reducing the available body height accordingly and preventing continuous reflow growth + expect(grid.calcHeight).toBe(calcHeightNoBorder - 4); + })); + it('should keep auto-sizing if initial data is empty then set to a new array', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridWrappedInContComponent); tick(); diff --git a/src/app/grid-auto-size/grid-auto-size.sample.scss b/src/app/grid-auto-size/grid-auto-size.sample.scss index 5e9b37fd2f3..381adfb8f86 100644 --- a/src/app/grid-auto-size/grid-auto-size.sample.scss +++ b/src/app/grid-auto-size/grid-auto-size.sample.scss @@ -11,3 +11,7 @@ margin-bottom: 16px; max-width: 900px; } + +igx-grid { + border: 1px solid lightgray; +}