Enable the children elements' before and after content to surpass the limitations set by the parent's overflow property

I have a division with the overflow property set to scroll to view all fields without using too much page space. Each field includes a title span and an associated input. Users can hover over the spans to see helpful tooltips. I use the spans' after and before pseudo-elements to create customized tooltips on hover. However, the display of tooltips is limited by the parent div's overflow property.

Below is the rendered HTML example:

<div id="ContentPlaceHolder1_leftDiv" class="l-custom-left">     
    <div class="personalizedFields">
        <table>
            <tr>
                <td>
                    <span title="Field Associated: First Name" class="tooltip">First Name</span>
                </td>
            </tr>
            <tr>
                <td>
                    <input name="ctl00$ContentPlaceHolder1$ucPF$ucCustomField36$field36" type="text" id="field36" />

                </td>
            </tr>

            <tr>
                <td>
                    <span title="Field Associated: Last Name" class="tooltip">Last Name</span>
                </td>
            </tr>
            <tr>
                <td>
                    <input name="ctl00$ContentPlaceHolder1$ucPF$ucCustomField37$field37" type="text" id="field37" />

                </td>
            </tr>
        </table>
    </div>
</div>

Css for the parent div and spans:

.l-custom-left
{
    overflow-x: hidden;
    width: 250px;
    height: 50vh;
}

.tooltip:hover:after{
    background: #333;
    background: rgba(0,0,0,.8);
    border-radius: 5px;
    bottom: 26px;
    color: #fff;
    content: attr(title);
    left: 20%;
    padding: 5px 10px;
    position: absolute;
    z-index: 98;
}

.tooltip:hover:before{
    border: solid;
    border-color: #333 transparent;
    border-width: 6px 6px 0 6px;
    bottom: 20px;
    content: "";
    left: 50%;
    position: absolute;
    z-index: 99;
}

How can I make the spans' after and before content "override" the parent div's overflow restriction?

JSfiddle

Answer №1

If you are looking to make this function, there are two methods you can try. The first option is to utilize JavaScript (which I won't delve into) to position an element outside the container at the exact location of the element. This solution may seem cumbersome, but I have had to resort to it numerous times before CSS3 came into play.

The second method is more refined, although it does violate HTML semantics. The issue with your :before and :after pseudo-elements not extending beyond a scrollable container is due to them being perceived as children of the .tooltip element, thereby becoming part of the document flow within the scrolling container even if they are absolutely positioned.

So how do we tackle this problem? We take a shortcut, plain and simple.

Add another element following your span like so:

<span class="tooltip">First Name</span>
<span title="Associated Field: First Name" class="tooltip-hovershim">First Name</span>

We duplicate the content to maintain consistency in size.

Then, adjust your CSS as follows:

.tooltip, .tooltip-hovershim
{
    display: inline;
}

.tooltip:hover:after, .tooltip-hovershim:hover:after{
    background: #333;
    background: rgba(0,0,0,.8);
    border-radius: 5px;
    bottom: 26px;
    color: #fff;
    content: attr(title);
    left: 20%;
    padding: 5px 10px;
    position: absolute;
    z-index: 98;
}
.tooltip-hovershim { 
    position: absolute;
    transform: translateX(-100%);
    color: transparent;
}

.tooltip:hover:before, .tooltip-hovershim:hover:before {
    border: solid;
    border-color: #333 transparent;
    border-width: 6px 6px 0 6px;
    bottom: 20px;
    content: "";
    left: 50%;
    position: absolute;
    z-index: 99;
}

And there you have it! You now have your floating element. It's that simple.

JSFiddle Example

Applied only to the initial two elements for brevity.


For added fun, here is the JavaScript alternative

JSFiddle with the JS variant

And here is the essential segment of the JavaScript code:

var span_labels = document.querySelectorAll('.personalizedFields td span'),
    label_house = document.createElement('div');

document.body.appendChild(label_house);
label_house.setAttribute('class', 'tooltip-hoverer');

for (var i=0,l=span_labels.length;i<l;i++){
  var curr_label = span_labels[i];
    curr_label.addEventListener('mouseover', function(e) {
       e.preventDefault();
       label_house.innerHTML = e.target.getAttribute('title');
       var xy = getOffset(e.target);
       label_house.style.top = (xy.top - 26) + 'px';
       label_house.style.left = (xy.left) + 'px';
       label_house.style.display = 'block';
    });
    curr_label.addEventListener('mouseout', function() {
       label_house.style.display = 'none'; 
    });
}
                                
function getOffset(el) {
    var elementRectangle = el.getBoundingClientRect();
    var _x = elementRectangle.left;
    var _y = elementRectangle.top + el.offsetParent.scrollTop;
    return { top: _y, left: _x };
}

Answer №2

Due to the limitations of CSS alone, I made the decision to combine JavaScript and JQuery to achieve the desired functionality. Taking inspiration from Josh Burgess's JS implementation, I present a JQuery-focused solution:

var tooltip;

$(document).ready(function() {
    $('span.tooltip').on({
        mouseenter: function (e) {
            tooltip = document.createElement('div');
            document.body.appendChild(tooltip);
            $(tooltip).addClass('tooltip-hoverer');
            $(tooltip).text($(this).attr('data-tooltip'));
            var x = e.clientX - (($(tooltip).outerWidth()) / 2); // Adjusting for tooltip arrow position
            var y = this.getBoundingClientRect().top + this.offsetParent.scrollTop;
            $(tooltip).css({
                top: y - 32,
                left: x,
                display: 'block'
            });
        },
        mouseleave: function () {
            document.body.removeChild(tooltip);
        }
    });                       
});

Note that my approach differs from Josh's in that tooltips are generated per span hover, eliminating the need to preload all tooltips. They are removed upon cursor exit.

View the JSFiddle demo here

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

Navigate between tabs with a single click

Hey there! I'm having trouble putting together a webpage that features a sidebar. I want to make it so that clicking on one of the links at the top will switch the tab and its content accordingly. However, the current code I have isn't working an ...

Issues encountered while modifying Vue data

In my Vue JS 2 code, I have structured my data as follows: data : { newBus: { name: '', hours: { sunday: '', } } } When setting the data usi ...

Exploring elements in Javascript

I am attempting to retrieve values from various elements when a 'a' element is clicked. Consider the following code: <tr data-id="20"> <div class="row"> <td> <div class="btn-group"> <a data-checked= ...

I am unable to utilize the backspace function within a text box generated by JavaScript

I have created a dynamic form using JavaScript that includes buttons and one text input field. However, the issue is that to delete the text entered in the input field, one must highlight the text and then type over it instead of being able to simply use t ...

Managing the output from a function: Tips and strategies

Below is the function I am currently working with: function kontrola(){ var jmeno = self.document.forms.newPassForm.user.value; $.get("checkMail.php?mail="+jmeno, function(data){ if(data=='1'){ alert('Tento ...

Different floating divisions that are tightly packed adjacent to each other

I'm dealing with dynamically created divs that have variable content, all following the same CSS rules. My goal is to organize them into 2 columns without any space in between. I attempted to use float: left/right, but there still remains space at the ...

Error: Validation issues detected in field functionality

My goal is to loop through a set of text fields and check if the user has input any values. However, I'm facing an issue where even though I have provided values in the text fields, it seems like they are empty. To better illustrate my problem, I have ...

What is the most streamlined method for identifying if a browser is operating on an Android device?

Looking to add a banner on our mobile website specifically for Android users to prompt them to download the Android mobile app. Wanting to find a lightweight way to detect in Javascript if the user is using an Android browser. Have reviewed various soluti ...

Some devices experiencing website update issues while others are successful

My website is functioning properly on my laptop and phone, but not on my school iPad (managed by the district). I have already cleared the cache, but the site does not update. It was working fine earlier, and I need to present it next Monday. Please help a ...

Include an additional title to the header of the Bootstrap 4 modal

Currently, I am utilizing a basic modal window which was constructed from Bootstrap's (4.4) sample. This modal consists of a header division: <div class="modal-header"> <h5 class="modal-title">Modal title</h5> <button ty ...

Leveraging the useEffect hook to make multiple API calls in ReactJS

I have a useEffect function in my react component where I am calling the API videoGridState. The issue I am facing is that the API is being called twice; once when the page initially reloads and again when the count changes. I want it to be called only onc ...

Move the location of the mouse click to a different spot

I recently received an unusual request for the app I'm developing. The requirement is to trigger a mouse click event 50 pixels to the right of the current cursor position when the user clicks. Is there a way to achieve this? ...

How to display currency input in Angular 2

Is there a way to dynamically format input as USD currency while typing? The input should have 2 decimal places and populate from right to left. For example, if I type 54.60 it should display as $0.05 -> $0.54 -> $5.46 -> $54.60. I found this PLUN ...

How can I select a checkbox using jQuery?

I need help toggling a checkbox on and off using jQuery. Here is the HTML code: <input type="checkbox" id="isWorking" name="isWorking" /> I attempted to control it with jQuery like this: $('#isWorking').prop('checked', true); $ ...

Is it possible to personalize Carousel-indicators within react-bootstrap?

I'm currently utilizing the Carousel component from . My goal is to customize the carousel-indicators, adding text and making them appear as buttons with text. However, when I attempt to do so, React renders 'ol' tag into a new CarouselItem ...

Utilizing the map() method for iterating through a nested property within a React component

Currently, my React setup involves rendering a prop named area which has the following structure: [{ "id": 1, "name": "Europe", "Countries": [{ "id": 1, "name": "Iceland", "Cities": [{ "id": 1, " ...

"Error in Visual Studio: Identical global identifier found in Typescript code

I'm in the process of setting up a visual studio solution using angular 2. Initially, I'm creating the basic program outlined in this tutorial: https://angular.io/docs/ts/latest/guide/setup.html These are the three TS files that have been genera ...

How can I conceal login and register router-links in the Vue + Laravel SPA project navbar immediately after a user logs in?

Currently, I am working on my Bachelor's degree project and have encountered a specific issue. While the login, register, and logout functions all seem to be working well, there is an inconsistency with the navigation bar not automatically switching b ...

NodeJs Importing a File

Currently working with NodeJS, I have encountered a challenge. Is it possible to require a JavaScript file in Node similar to how we do in browsers? When using the require() method, I noticed that the JavaScript file called does not have access to global v ...

There seems to be an issue with the Alexa skill's ability to provide a response after another

I am currently developing an Alexa skill that involves a multi-step dialog where the user needs to respond to several questions one after the other. To begin, I am trying to kick things off by implementing a single slot prompt. I am checking if the slot is ...