Place an element in relation to the vertical size of a div that includes written content

Currently, I am working on implementing a button with a popup that appears underneath it when the user hovers over it.

The specific requirements for this setup are:

  • The size of the button should not affect the size of the popup
  • The popup should always be a fixed distance from the bottom edge of the button
  • The popup should not disrupt the layout of any other element (hence the absolute positioning)
  • The popup should be centered relative to the button

To better visualize this concept, please refer to the image provided below before analyzing my current attempt at coding this functionality.

.button-container {
  display : inline-flex;
  height  : 100%;
  }
.popup-positioner {
  display  : inline-block;
  position : relative;
  right    : 50%;
  }
.button-container button {
  background-color : rgba(40, 40, 40, 1);
  border           : none;
  border-radius    : 5px;
  outline          : 0px solid rgb(90, 90, 90);
  font-weight      : 900;
  color            : rgb(220, 220, 220);
  padding          : 8px 10px 8px 10px;
  }
.button-container .popup {
  display           : none;
  background-color  : rgba(80, 80, 80, 1);
  color             : rgba(220, 220, 220, 1);
  border-radius     : 5px;
  -webkit-transform : translate(-50%, 110%);
  padding           : 6px 10px 6px 10px;
  }
.button-container:hover .popup {
  position  : absolute;
  display   : block;
  animation : show_popup 0.5s;
  }
@keyframes show_popup {
  0% {
    opacity: 0;
    -webkit-transform: translate(-50%, 110%);
    }
  100% { 
    opacity: 1;
    -webkit-transform: translate(-50%, 110%);
    }
  }
<div class="button-container">

  <button> 
      this is a button with lots of text
  </button>
  
  <div class"popup-positioner">
    <div class="popup"> 
      this is a popup
    </div>
  </div>

</div>

At present, the code functions as described above. However, there is an issue where the popup's positioning is based on its own height.

.button-container .popup {
    ...
    -webkit-transform: translate(-50%, 110%);
    ...
}

This results in undesirable behavior on smaller screens where the popup does not align correctly.

I am seeking assistance on adjusting the code so that the popup's position is relative to the height of the <button> it is associated with.
Any guidance or suggestions to achieve this would be greatly appreciated.
Thank you - Oli

Answer №1

When it comes to absolute positioning, utilizing properties like top, left, right, and bottom is crucial for positioning an element in relation to its parent container. This key detail appears to be missing from your current code snippet.

In addition, when implementing hover effects, consider using transition instead of animation. Transitions generally offer more ease when transitioning between different states, making the overall user experience smoother.

In the example provided below, I have placed the popup-positioner at the bottom of the button-container and applied a padding-top to create space between the popup and the button. Adjust this padding as needed to achieve the desired spacing consistency between the button and the popup.

The rationale behind this approach is to ensure that the popup remains visible even when hovering over the button, preventing it from disappearing if the mouse moves between the button and the popup.

To prevent sentence wrapping, you can use white-space: nowrap;. If line breaks are necessary within a sentence, utilize the <br> tag to indicate where the line break should occur.

.button-container {
  display: inline-block;
  position: relative;
}

.button-container button {
  background-color: rgba(40, 40, 40, 1);
  border: none;
  border-radius: 5px;
  outline: 0px solid rgb(90, 90, 90);
  font-weight: 900;
  color: rgb(220, 220, 220);
  padding: 8px 10px 8px 10px;
}

.button-container .popup-positioner {
  display: flex;
  justify-content: center;
  position: absolute;
  top: 100%;
  left: 0%;
  width: 100%;
  padding-top: 10px;
  opacity: 0;
  visibility: hidden;
  transition: 150ms ease-in-out;
  transition-property: opacity, visibility;
}

.button-container:hover .popup-positioner {
  opacity: 1;
  visibility: visible;
}

.button-container .popup {
  background-color: rgba(80, 80, 80, 1);
  color: rgba(220, 220, 220, 1);
  border-radius: 5px;
  padding: 6px 10px 6px 10px;
  white-space: nowrap;
}
<div class="button-container">
  <button>this is a button with lots of text</button>
  <div class="popup-positioner">
    <span class="popup">this is a popup</span>
  </div>
</div>

Answer №2

Here is a clever and efficient workaround that will always position the popup under the button and center it, even if you don't know the width of the popup.

I've assigned new IDs in this code snippet, but feel free to customize them as needed.

An alternative to adjusting opacity is to use display: none; initially and then switch to display: block; upon hovering.

/* Set parent(button) container relative */

#button {
  position: relative;
  display: inline-block;
  padding: 5px;
  background: black;
  color: white;
  border-radius: 5px;
  text-decoration: none;
}


/* Pop up position: absolute, left: 50% and translate back 50% based on its width */

#popup {
  position: absolute;
  display: block;
  opacity: 0;
  top: 50px;
  left: 50%;
  transform: translate(-50%, -50%);
  background: black;
  border-radius: 5px;
  padding: 5px;
  transition: opacity 0.3s;
}


/* Increase opacity of popup on hover over the parent(button) */

#button:hover #popup {
  opacity: 1;
}
<a href="#" id="button">
  <span>This is a button with lots of text. Text text, more text.</span>
  <span id="popup">Button Pop Up</span>
</a>

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

How to add a jQuery function to a Rails 3 if statement?

I followed a Rails 3 tutorial on creating a multi-step form which you can check out here. Additionally, I incorporated Stripe payment functionality in my app using another railscast found here. Within my application, the payment form is hidden using jQuer ...

What is the best approach for encoding text inputs automatically?

In order to prevent my application from crashing due to the error "A potentially dangerous Request.Form value was detected...", I initially disabled page validation. However, I am now reassessing this approach and aiming to resolve it properly. Is there a ...

Switch up the styling of a component by updating its properties with a switch statement

Although there is a similar question, my query has a unique requirement. I have defined the common styles for my button and implemented a function using a switch statement with different properties for various buttons across different pages. However, for ...

Troubulating with overflow-y: scroll functionality? Follow these steps to troubleshoot

I've been working on a project involving the .menu-scroll class, which is a div within a <ul> list. I want this div to display a scroll bar when it exceeds its height limit. However, instead of achieving this, it keeps pushing down the .menu-foo ...

Get an Array Using AJAX in PHP and JavaScript

Section 1 I want to retrieve an Array from PHP and use it in JavaScript. I have created a file using the fwrite function in PHP, then included that file in my next .load method inside a Div. The new PHP file contains an "include 'somefile.php';" ...

Organizing outcome searches through ajax

I have a result table displayed on the left side https://i.stack.imgur.com/otaV4.png https://i.stack.imgur.com/pp9m0.png My goal is to transform it into the format shown on the right side of the table In a previous inquiry found here, @Clayton provided ...

Attempting to display numerous react components on various divs instead of just one ID

Currently, I am facing a challenge in creating multiple react comment boxes. The package I am using is based on #id instead of class, which resulted in only rendering one box instead of all. To resolve this issue, I attempted to switch from GetelemntbyID t ...

What is the best way to achieve a Clamp-To-Border effect on a Texture loaded onto an Image in the THREE.js?

My scene includes a plane with an image loaded onto the texture. I've found that there is no Clamp-To-Border option for textures, only Clamp-To-Edge, Repeat Wrapping, and Mirrored Wrapping. Below is an image displaying the default ClampToEdge effect. ...

Discover how to achieve the detail page view in Vue Js by clicking on an input field

I'm a beginner with Vuejs and I'm trying to display the detail page view when I click on an input field. <div class="form-group row"> <label for="name" class="col-sm-2 col-form-label">Name</label> ...

Display each div one at a time

I am working on a script that should reveal my divs step by step. However, the current code only shows all the divs at once when clicked. How can I modify it to detect each individual div and unveil them one by one? For example, on the 1st click => expa ...

Unveiling Fresh URLs within an iFrame

Here is the current situation: www.mywebsite.com/Pagex.html - On this page, there is an iFrame with a default URL (src) from a different domain than the host page (Pagex.html). The code inside the iFrame is a user input form with a submit button. Upon su ...

Migration processes encountering delays due to running nodes

When running migrations in Node, I am encountering a timeout error. The specific error message is: Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. Here is the ...

Finding your site's First Contentful Paint (FCP) can be done by analyzing the

After doing some research on Google insights, I came across information about FCP. However, I'm still unsure about how to determine my site's FCP and other relevant metrics. If anyone could provide me with more information or share detailed link ...

Web application error: Karma and Webpack cannot locate Angular controller

After following a blog post on setting up an Angular project with webpack, I used an associated boilerplate on Github. Although the app is functioning properly, Karma seems to have trouble finding the controller it needs to test. // karma.config.js modul ...

Is there a way to decrease the size of the content within this iFrame?

Is there a way to display 6 cameras on a single webpage without them taking up the entire screen within iframe windows? Can the content be shrunken to fit the iframe window? <!doctype html> <html> <head> <meta charset="utf-8"> &l ...

Running Jasmine asynchronously in a SystemJS and TypeScript setup

I am currently executing Jasmine tests within a SystemJS and Typescript environment (essentially a plunk setup that is designed to be an Angular 2 testing platform). Jasmine is being deliberately utilized as a global library, rather than being imported vi ...

Navigating dropdown list items using the keyboard in TypeScript is a breeze

I've encountered a bug while working on my open-source project. The issue is with navigating the dropdown list items using the keyboard (arrow key/tab). I have implemented the keyboard-navigation logic, but I'm unsure of how to make it work corre ...

Despite the presence of a producer and topic, sending Kafka messages is proving to be a challenge

Currently, I am using TypeScript and the KafkaJS library on my local machine with a single Kafka broker. After successfully connecting a producer, confirming the creation of my topic, and creating messages like so: const changeMessage = { key: id, ...

Determining season goals for teams using nested JSON data

Is it possible to retrieve a team's total goals scored for the season from the provided data by using the team's name as the input for a function? Would it be accurate to attempt mapping over the rounds and filtering matches where either team1 o ...

Angular JS does not display the bold tag for specific words

I'm currently working on an Angular JS application and receiving text from the server that needs to be displayed on my website. The text received from the server is: "My name is <b> John </b>" with b tags. Unfortunately, when I display ...