I am currently working on positioning the arrow in the screenshot using TypeScript calculations. However, I am facing an issue where the position is being determined based on the top of the black popup instead of the top of the screen.
- From the top of the screen to the middle of the button = 250px
- From the top of the popup to the arrow = 250px
The offset seems correct, but it is measuring from the top of the popup as 0px instead of the top of the screen. How can I adjust my formula to ensure that the arrow is positioned relative to the top of the screen?
When I utilize relative positioning: https://i.sstatic.net/JsF6A.png
When I use absolute positioning: https://i.sstatic.net/oc4V3.png
This is how my CSS code looks (I experimented with setting relative
to absolute
without success:
.menu-popup {
--arrow-left-offset: 50%;
--arrow-top-offset: 50%;
padding: var(--spacing-s) 0;
margin: 10px;
position: relative;
&::after {
content: ' ';
position: absolute;
}
// Arrow placement
&.menu-popup-right.standard-variant::after {
top: var(--arrow-top-offset);
right: 100%; /* Positioned to the left of menu-popup */
margin-top: -5px;
}
}
To update the CSS variable, I follow this process:
// Altering arrow placement:
private changeArrowPlacement() {
if (typeof this.menu === 'undefined') return;
// Button
const tRect = this.triggerRef.nativeElement.getBoundingClientRect();
// Menu
const mRect = this.menu.nativeElement.getBoundingClientRect();
if (typeof this.position === 'string' && ['left', 'right'].includes(this.position)) {
const top = tRect.height / 2 + tRect.top + 'px';
this.setArrowOffset('top', top);
}
}
// Modifying CSS property:
private setArrowOffset(position: 'left' | 'top', value: string) {
if (typeof this.menu === 'undefined') return;
this.menu.nativeElement.style.setProperty('--arrow-left-offset', '0%');
this.menu.nativeElement.style.setProperty('--arrow-top-offset', '0%');
this.menu.nativeElement.style.setProperty(`--arrow-${position}-offset`, value);
}
The popup is created using Angular CDK, which generates a div element.
Here is a simple representation of the HTML structure:
<!-- Created by me -->
<div id="application">
<button (click)="openPopup()">Open Popup</button>
</div>
<!-- Created by Angular CDK -->
<div class="overlay">
<div class="pane">
<div class="menu-popup">
</div>
</div>
</div>
This is the output generated by Angular for the popup:
/* Overlay element */
.overlay {
top: 0px;
left: 0px;
height: 100%;
width: 100%;
position: absolute;
}
/* Overlay Pane */
.pane {
top: 144.5px;
left: 573.844px;
}