Merge Dropdown Div and ToolTip for a seamless user experience

I am encountering some issues with getting the desired functionality. Either the .ToolTip just appears abruptly instead of smoothly dropping down, or the .ToolTipText does not show up and the .ToolTip has a strange transition (like opening/closing from the middle) - https://jsfiddle.net/Apryed/40exvq6s/2/.

The way I combined them is as follows:

<h3 class="ShowHide">Text to click and display/hide</h3>
    <div class="ToolTip">
        <div class="ToolTipText">Descriptive Text</div>
        <div>
            <label for="date">SaveDate:</label>
            <input type="text" id="date" name="date" required minlength="17" maxlength="17" />
        </div>
    </div>
</div>

Note: I have made several attempts to modify CSS and DOM styles with JavaScript, but unfortunately, they were unsuccessful (mostly related to visibility and z-index).

My expectation was to combine these two elements using HTML5, CSS3, and JavaScript (ES6 Tops) - https://jsfiddle.net/Apryed/gnuebymf/:

  1. A clickable drop-down
  2. A tooltip with descriptive information

To control what should be displayed and provide guidance on input.

Observe how the drop-down gently reveals and hides compared to the other fiddle.

Edit: As requested by Bharata - I'm not entirely sure why, as I've seen posts similar to mine...but it's okay with me.

let ShHi = document.getElementsByClassName("ShowHide1")
for (let i = 0; i < ShHi.length; i++) {
  ShHi[i].addEventListener("click", function () {
    this.classList.toggle("show")
    let nextEl = this.nextElementSibling
    nextEl.classList.toggle("active")
    if (nextEl.style.maxHeight) {
      nextEl.style.maxHeight = null
    } else {
      nextEl.style.maxHeight = nextEl.scrollHeight + "px"
    }
  })
}
/* DropDown Part */
.ShowHide1 {
  padding: 0;
  font-size: 1em;
  transition: 0.3s;
  cursor: pointer;
}

.ToolTip1 {
  padding: 0 18px;
  margin: 3px 0;
  max-height: 0;
  overflow: hidden;
  transition: 0.3s ease-out;
}

/* ToolTip Part */
.ToolTip2 {
  position: relative;
  display: inline-block;
}

.ToolTip2 > :nth-child(2) {
  background-color: lightgreen;
  padding: 10px;
}

.ToolTip2 .ToolTipText2 {
  width: 120px;
  background-color: black;
  color: #fff;
  text-align: center;
  border-radius: 6px;
  padding: 5px 0;

  position: absolute;
  z-index: 1;
  -webkit-transform: translateY(calc(-5px - 100%));
  transform: translateY(calc(-5px - 100%));
  left: 50%;
  margin-left: -60px;
  opacity: 0;
  transition: opacity 1s;
}

.ToolTip2 .ToolTipText2::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: black transparent transparent transparent;
}

.ToolTip2:hover .ToolTipText2 {
  opacity: 1;
}
<!DOCTYPE html>
<html lang="es">
    <head>
        <meta charset="utf-8" />
    </head>
    <body>
    <h2>DropDown Part</h2>
        <h3 class="ShowHide1"><u>Click Me!</u></h3>
        <div class="ToolTip1">
      <div>
        <label for="x">Some randomtext</label>
              <input id="x" name="x"/>
      </div>
        </div>
    <hr>
    <h2>ToolTip Part</h2>
        <h3>No Need to Click Me!</h3>
        <div class="ToolTip2">
      <div class="ToolTipText2">
        Text to display
      </div>
      <div>
              <label for="x1">Hover over this green area</label>
              <input id="x1" name="x1"/>
      </div>
        </div>
    </body>
</html>

Answer №1

Here is the code snippet for creating an expandable tooltip:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <style>
      .tooltip {
        width: 120px;
        background-color: black;
        color: #fff;
        text-align: center;
        border-radius: 6px;
        padding: 5px 0;
        position: absolute;
        z-index: 1;
        -webkit-transform: translateY(calc(-5px - 100%));
        transform: translateY(calc(-5px - 100%));
        left: 50%;
        top: 0;
        margin-left: -60px;
        opacity: 0;
        visibility: hidden;
        transition: 1s;
      }

      .tooltip::after {
        content: "";
        position: absolute;
        top: 100%;
        left: 50%;
        margin-left: -5px;
        border-width: 5px;
        border-style: solid;
        border-color: black transparent transparent transparent;
      }

      .expand {
        padding: 10px;
        font-weight: bold;
        cursor: pointer;
        width: fit-content;
      }

      .container {
        position: relative;
        width: fit-content;
      }

      .container:hover .tooltip {
        opacity: 1;
        visibility: visible;
      }

      .expandable {
        background-color: lightgreen;
        max-height: 0;
        transition: 0.3s ease-out;
        overflow: hidden;
      }

      .expandable_content {
        padding: 10px;
      }
    </style>

    <div class="expand">Expand</div>
    <div class="container">
      <div class="tooltip">tooltip</div>
      <div class="expandable">
        <div class="expandable_content">
          <label for="x1">Hover over this green area</label>
          <input id="x1" name="x1" />
        </div>
      </div>
    </div>

    <div class="expand">Expand 2</div>
    <div class="container">
      <div class="tooltip">tooltip 2</div>
      <div class="expandable">
        <div class="expandable_content">
          <label for="x2">Hover over this green area 2</label>
          <input id="x2" name="x2" />
        </div>
      </div>
    </div>

    <script>
      [...document.querySelectorAll(".expand")].forEach((el) => {
        el.addEventListener("click", () => {
          let expandable = el.nextElementSibling.querySelector(".expandable");
          if (expandable.style.maxHeight && expandable.style.maxHeight != "0px") {
            expandable.style.maxHeight = 0;
          } else {
            expandable.style.maxHeight = expandable.scrollHeight + "px";
          }
        });
      });
    </script>
  </body>
</html>

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

Create an interactive table with dynamic content that prevents wrapping using the CSS property

I am trying to create a table with two columns and specific width. The left cell should display a single-line text with auto-ellipsis, while the right cell should have dynamic content that adjusts the width of the cell accordingly, shrinking the left cell& ...

Guide on navigating to a different page following a successful Google Sign In within React18

I'm facing an issue with redirection after signing in with Google on my React 18 project. Despite successfully logging in, the page does not redirect as expected. Below is a snippet of my Login.jsx file where the Google login functionality is implemen ...

The image hover effect seems to be malfunctioning

Within my "profile.php" file, I have included a separate "head.php" file that features two images and three labels (two of which contain an additional image). .parent { position: relative; top: 0; left: 0; } .image1 { position: relative; top: ...

Creating HTML tables with PHP for dynamic web content

I am facing a minor issue while displaying my results in tables. Here is the code snippet: <?php //return data if any while ($client = mysqli_fetch_assoc($result)) { //output data form each client //var_dump($client); ?> < ...

Is there a way to add new content to my HTML page while also updating the DOM without having to refresh the entire page?

Whenever I add new data to a table, the datatables plugins fail to recognize it <javascript>$(document).refresh</javascript> Could there be a function similar to document.refresh that I should be using? ...

Issue with Three JS where the BoundingBox does not update correctly following rotation operations

I am trying to determine the bounding box of a geometry after applying rotations to it. I obtained the rotation code from the sample editor in Three JS: object.rotation.x = xRadians; object.rotation.y = yRdians; object.rotation.z = zRadians This rotatio ...

What is the best way to store the dom in cache to ensure that the page remains unchanged when navigating back using the back button?

When adding models to my JavaScript application's model collection using AJAX calls, I encounter an issue where if I click on a model and go to the next page, all the loaded models disappear when I hit the back button. What is the most effective way t ...

Navigate to the location using AngularJS elements in the JavaScript iframe1

Dealing with an issue while working on AngularJS. I am facing a frustrating problem where I am attempting to use one link to open links in two separate iframes. All aspects of this function correctly, except for the actual links. The issue arises when usin ...

Having trouble setting a value in a Vue.js variable

Upon assigning a value retrieved from the firebase collection, I encountered the following error message. Error getting document: TypeError: Cannot set property 'email' of undefined at eval (Profile.vue?5a88:68) Here is the code snippet in que ...

There seems to be an issue in Angular as it is unable to retrieve /

I'm encountering an issue with my simple application where I am receiving the error message "Cannot GET /." Also, in the console, I see this error: TypeError: Cannot read property 'checked' of null at Object.SL_BBL_locer. I'm unsure ab ...

NodeJS error: Attempted to set headers after they have already been sent to the client

As a beginner, I have encountered an error message stating that the API is trying to set the response more than once. I am aware of the asynchronous nature of Node.js but I am struggling to debug this issue. Any assistance would be greatly appreciated. rou ...

What steps should I take to resolve the issue of 'this.reduce() not being a function'?

Here is my code : app.get("/", (req, res) => { const reducer = (acc, guildCount) => acc + guildCount; const results = client.shard.fetchClientValues('guilds.cache.size'); console.log(results) let guildCount ...

Fade in a CSS class using jQuery

I'm attempting to incorporate a basic fadeIn() CSS effect on specific objects that are tagged with the "button" class. My goal is to have the "hoverbutton" class fade in when the object is hovered over, and then fade out when the cursor moves away fro ...

The function contacts.map is not defined

Can someone help me understand why I am getting the error message "contacts.map is not a function"? I am working on fetching data from a contacts array list that I have created. My goal is to display buttons inside a panel. When a button is clicked, the sc ...

I am struggling to find the correct way to fetch images dynamically from Cloudinary and display them as backgrounds. How should I go about implementing this feature successfully

I have been trying to figure out why I am unable to retrieve the image from cloudinary. My goal is to use the image as a background when posting, but it seems like I am not fetching the image correctly. function Post({post}){ return( <div ...

Struggle with creating a responsive Strava Iframe (CSS/HTML)

UPDATE: My ongoing attempts to make the iframe container responsive have been focused on adjusting its size based on the intrinsic ratio of the iframe. Unfortunately, this approach has not fully worked as some elements of the iframe remain fixed in pla ...

The hidden attribute of UIWebView and its interplay with JavaScript

In the webViewDidStartLoad method, I hide the webview. Then a request is made. In the webViewDidFinishLoad method, I use stringByEvaluatingJavaScriptFromString. Finally, the webview is shown again. However, when I run the app, I can still see how the Java ...

Using an Ajax Post Call to send FormData leads to a Get request instead

Having trouble with sending a simple form via POST method. I load the form content using AJAX: $(function() { var arg = { "operation": "upload", "step": "0" ...

Discover the ultimate guide on developing a personalized file management system using the powerful node.js platform!

I have undertaken a rather ambitious project for myself. There exists a comprehensive tutorial on the website that outlines the process of establishing an online environment (resembling a user panel) where registered users can effortlessly upload various ...

My website is displaying a CSS 404 error even though the CSS file is present

I have a question regarding express server.js const express = require('express') const app = express() const port = 8080 app.use(express.static('public')) app.use('/css', express.static(__dirname + 'public/css')) a ...