When I used the custom masonry package implement on the angular with help of custome directive then first time content overlapped, I did not calculate proper position Why did this happen? I check debug then targetindex not proper someTime that's why they overlap with above content so What can i do? I think the issue happened only in the directive. enter image description here import { Directive, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, Output, Renderer2 } from '@angular/core'; import $ from 'jquery'; @Directive({ selector: '[appPinGrid]', // standalone: true }) export class PinGridDirective implements OnChanges, OnDestroy { @Input() gutter: number = 0; @Input() columns: number = 0; @Input() minColWidth: number = 2; @Input() maxColWidth: number = 10; @Input() doubleColumnWidth: number = 10; @Input() itemClass: string = ''; @Input() public data: any; @Output() onLayoutComplete: EventEmitter<any> = new EventEmitter(); container: any; containerWidth: number = 0; containeHeight: number = 0; columnWidth: any; items: any; // columns of grid columnHeightArray: any; // timer for detect changes controlSkipper: any; resizeControlSkipper: any; // host listener for resize window // resizeListener: any; isSearchFirstTime: any = true; constructor(public el: ElementRef, public renderer: Renderer2) { } ngOnDestroy() { // unsubscribe event listener this.resizeListener(); } resizeListener(){ this.renderer.listen('window', 'resize', () => { if (this.resizeControlSkipper) clearTimeout(this.controlSkipper) this.resizeControlSkipper = setTimeout(() => { // console.log('relayout call'); this.reLayout(); }, 400); }); } ngOnChanges(changes: { data: any; }) { if (this.isSearchFirstTime) { this.isSearchFirstTime = false; // this is for skip first changes detect for initialieze all directive (scroll unnecessary api of second page from here so this solution is apply) } else { if (changes.data) { if (this.controlSkipper) clearTimeout(this.controlSkipper) this.controlSkipper = setTimeout(async () => { this.reLayout(); }, 500); } } } reLayout() { // console.log('relayout'); this.container = this.el.nativeElement; this.items = this.el.nativeElement.childNodes; this.items.forEach((element: any) => { $(element).css('opacity', '0'); }); this.layoutItem(); } async layoutItem() { // console.log('layout'); this.getColumnWidth(); this.initColumnHeightarray(); for (var i = 0; i < this.items.length; i++) { this.placeItem(this.items); } this.items.forEach((element: any) => { console.log('element: ', element); $(element).css('opacity', '1'); }); console.log('layout complete in function'); await $(this.container).height(Math.max.apply({}, this.columnHeightArray)); // console.log('set wrapper height', Math.max.apply({}, this.columnHeightArray)); await this.onLayoutComplete.emit('LayoutComplete'); } initColumnHeightarray() { this.resetColumnHeight(); for (var i = 0; i < this.columns; i++) { this.columnHeightArray.push(0); } } resetColumnHeight() { this.columnHeightArray = []; } getColumnWidth() { this.containerWidth = this.el.nativeElement.offsetWidth; this.columnWidth = Math.floor((this.containerWidth / this.columns) - this.gutter); if (this.columnWidth <= Number(this.minColWidth) && this.columns >= 2) { this.columns--; this.getColumnWidth(); } // in below condition I check double column width // because column minus if card width < 200 and suppose column = 1 then it's width is increase // now maximum card width is 300 and container is about 465(200 column width + 2 number of column + 2 * gutter size) something, so that, below condition is become true and add one column i.e. 2. // now two column card width is again < 200 thus it will gose to infonite. // so I check that if container have enough space to display two column then I add column othersize it will display only one column if (this.columnWidth >= Number(this.maxColWidth) && this.containerWidth > this.doubleColumnWidth) { this.columns++; this.getColumnWidth(); } } calculateImageSize() { } async placeItem(item: { nodeType: number; getElementsByClassName: (arg0: string) => { (): any; new(): any; length: number; }; }) { if (item.nodeType != Node.ELEMENT_NODE) { return; // Skip non-element nodes } // Find the column with the minimum height const minimumColHeight = Math.min.apply({}, this.columnHeightArray); const minColIndex = $.inArray(minimumColHeight, this.columnHeightArray); // Calculate the position const targetIndex = minColIndex; const fixMarginLeft = (this.containerWidth - this.columnWidth * this.columns - this.gutter * (this.columns - 1)) / 2; // If the item has the specified class, adjust its size if (item.getElementsByClassName(this.itemClass).length > 0) { const img = item.getElementsByClassName(this.itemClass)[0]; $(img).css('position', 'initial'); // Ensure width and height are correctly set for proper placement const aspectRatio = $(img).width() / ($(img).height() || 1); $(img).css('width', this.columnWidth); $(img).css('height', Math.floor(this.columnWidth / aspectRatio)); } // Calculate the position for the item console.log('this.columnHeightArray[targetIndex]: ', this.columnHeightArray[targetIndex]); const position = { left: (this.columnWidth + this.gutter) * targetIndex + fixMarginLeft, top: this.columnHeightArray[targetIndex] + this.gutter // Adding gutter to the top position }; // Position the item $(item).css('position', 'absolute'); $(item).css('top', position.top); $(item).css('left', position.left); // Update the column height to account for the new item this.columnHeightArray[targetIndex] += $(item).outerHeight() + this.gutter; // Update column height including gutter console.log('this.columnHeightArray[targetIndex]: ', this.columnHeightArray[targetIndex]); } } I want to do proper adjust position how can i do? Continue reading...