The positioning of CSS arrows using the "top" attribute is not relative to the top of the page when using absolute values

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;
}

Answer №1

When using the CSS property <code>absolute
, the element is positioned relative to its parent container that has a relative position. To change this behavior and make the absolute element relative to the body of the page itself, simply remove the position: relative from the parent container.

If you are unable to modify the parent container, another option is to use the fixed positioning for your arrow. Keep in mind that with this approach, the arrow will remain fixed on the screen even when scrolling.

Alternatively, you can experimentally find the correct coordinates for placing the absolutely positioned arrow. In addition to using pixels (px) as units, you can also utilize percentages (%). Another technique is to use transform: translate(X, Y);, where X and Y can be defined in either pixels or percentages.

Answer №2

After some examination, I realized that the necessary calculation should account for relative positioning like so:

const top = tRect.top - mRect.top + tRect.height / 2 + 'px';
  1. Determine the top of the button
  2. Determine the top of the menu
  3. Subtract the two to find the difference (placing the arrow at the top of the button)
  4. Add half the height of the button (arrow will now be positioned at half the height of the button)

This method is effective whether the button is located at the top, bottom, left, right, or center of the page.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ensure that the link's color remains constant and remove any styling of text-decoration

Attempting to create a customized header. My goal is to change the color and remove text decoration in the navbar. Below is my code snippet: ReactJS: import React from 'react'; import './Header.css'; function Header() { return ( ...

The jQuery .load function does not function properly when an ajax query is already underway

My web application utilizes dynamic loading of content within the same div (.content) through either an ajax request or a .load() request. An example of the ajax request code snippet is: $(document).on('click', '.button1', functio ...

Can the AngularJS icon adapt to different lists?

I'm currently developing in AngularJS / Jade and I need to implement functionality where an icon changes when a user clicks on something. The code I have right now looks like this: a(onclick='return false', href='#general', data-t ...

Clicking a button in React requires two clicks to update a boolean state by triggering the onClick event

I have a React functional component with input fields, a button, and a tooltip. The tooltip is initially disabled and should only be enabled and visible when the button is clicked and the input fields contain invalid values. The issue I'm facing is t ...

Using Bootstrap 4: How to maximize the width of a span element placed near a label

I need to adjust the width of a span next to its label in my project. My goal is to show multiple groups {label / data} on the same line. To achieve this, I divided the row into 4 columns and tried to set a specific width for a span. However, no matter wh ...

Tips for customizing the transparency of a Bootstrap dropdown menu

I'm currently working with .navbar-default { z-index:99; opacity:0.8; } However, I am looking to adjust the opacity of dropdown menu items to 0.9. I have attempted several solutions without success. Here are a few examples: .dropdown-menu>li> ...

Upcoming topics - The Challenge of Staying Hydrated at Basecamp One

I have implemented a themes package for dark mode and light mode in my project. Despite doing the installation correctly as per the repository instructions, I am encountering an issue. My expected behavior for the project is: The webpage should initially ...

Determine the variance between two strings using Jquery

Hello and thank you in advance for your help. I'm facing a basic query here - I have two variables: var x = 'abc'; var y = 'ac'; I am looking to compare the two variables and find the dissimilarity between them, which should be: ...

Shifting the use of @Inject(MAT_DIALOG_DATA) away from class constructors

Our team is making a transition in the Dependency Injection pattern we utilize to minimize the dependency on TypeScript constructors. This shift will help us address recurring issues caused by team members adding logic that shouldn't be included in co ...

What could be causing the issue of being unable to connect to the NodeJS express server from any network?

Imagine having a web server running on port 3001 with the IP address 23.512.531.56 (obviously not a real one) and then switching to another network, like your neighbor's. Now, when you try entering 23.512.531.56:3001 in Chrome, why doesn't the se ...

When attempting to render a base64 string in an <img> tag using ReactJS, an error message ERR_INVALID_URL is displayed

I am currently working on displaying server-generated images (specifically matplotlib graphs) in a ReactJS module without needing to save the files on the server. To achieve this, I decided to use base64 to create an image string. When it comes time to sh ...

Validation of input using JQuery

I am currently working on validating a form, with a specific field that needs to be required. Here is the code for the field in question: <p> <label for="lf">Name: </label> <input class="lf" name="name" type="text"/> < ...

Challenges with the dropdown menu navigation bar

I am struggling with my dropdown menu and sign up/sign in buttons as they are not aligning properly. I have tried various coding methods but haven't been able to fix the issue. Can someone provide me with suggestions on how to rectify this problem? c ...

Issue with Heroku deployment: unable to locate JavaScript file

I encountered an issue while deploying my node.js app. Everything seemed to be working fine but it couldn't locate the JavaScript files. The error message displayed was: proove.herokuapp.com/:16 GET 404 (Not Found) Here is the server.js code snip ...

The single controller can now showcase various notification styles for operations such as insertion, updating, or error handling

I need to display notifications to the user based on three different scenarios using a controller. When data is successfully inserted When data is successfully updated In case of an error For each scenario, I want to show a different style of notificati ...

When you set the href attribute, you are essentially changing the destination of the link

UPDATE: I'm not referring to the status bar; instead, I'm talking about the clickable text that leads to a link. /UPDATE I've gone through a few similar posts but couldn't find a solution. I have a link that needs to be displayed. www ...

construct a table utilizing JSON information

If I have data returned from an ajax call that needs to be processed, a table like the following needs to be created: ID NAME Object Type ============================================== 1 SWT-F1-S32-RTR-1 Network Switch 2 ...

Javascript is handling the JSON Request flawlessly, however, when using Nodejs, an error is encountered with a status

I'm trying to fetch a simple JSON File in NodeJS. Using Javascript and jQuery, it functions perfectly: $(document).ready(function() { $.getJSON('https://www.younow.com/php/api/broadcast/info/curId=0/user=Peter', function(json) { if ...

Regex: Enabling commas in the name of an Excel file

My JavaScript code is set up to extract data from an excel file. As a first step, I define a regular expression and assign it to a variable named regex var regex = /^([a-zA-Z0-9\s_!()\\.\-:])+(.xls|.xlsx)$/; Following this, there is s ...

What is preventing me from retrieving these JSON values?

One of the functionalities on my website involves making an AJAX call to retrieve a member's profile information for editing purposes. The code snippet responsible for this operation is shown below: function loadProfileData() { var ...