z-index of Bootstrap3 Tooltip in columns is Browser specific - javascript

Using bootstrap 3 I've got two columns (sm-3 and sm-9). The left column is position: fixed and contains a link with a tooltip. The z-index of the tooltip (without being specified) seems to be browser specific.
What is (in general) the best way to define the z-index of the tooltip? I'm looking for a clean solution that works in all common browsers.
FIDDLE
Internet Explorer 11 (left) Chrome 48 / Edge 25 (right)
HTML:
<div class="container">
<div class="col-sm-3" id="left">
<a id="tooltipButton" href="#" data-toggle="tooltip" title='Long Text'>Show Tooltip</a>
</div>
<div class="col-sm-9 col-sm-offset-3" id="right">
Content
</div>
</div>
CSS:
#left { position: fixed; }
#right { background-color: #ddd; }
JS:
$('#tooltipButton').tooltip({
trigger: 'click',
html: true,
placement: 'right',
});
A few things I've tried (CSS):
.tooltip { z-index: 10; } // Doesn't work
.tooltip .tooltip.in { z-index: 10; } // Doesn't work
.tooltip .tooltip-inner { z-index: 10; } // Doesn't work
Is there a clean solution without adding more divs and without changing the attributes of the left or right div? E.g. #left { z-index: 10; } seems to work but changes the attributes and the overlapping behavior of the left div.
FIDDLE

If you give an element a position other than static it forces it to appear above any element that is still static. It's a rather unknown behavior of z-index. Therefore if a parent element has a position other than static all it's children will have their own stacking scope. It works almost like layers.
This article has an amazing write up about it: What no-one told you about z-index
So in your example all the tooptip code is appearing in the container that has it's own stacking scope and is therefore forced under the next container. If you add z-index:999; to the #left container you will see it is fixed. This is because that container (and it's contents) are now forced higher than the next.
JSFIDDLE
The other thing you could do is remove position:relative from the #right container so it doesn't have it's own stacking scope and then it works again.
JSFIDDLE v2
I don't think this helps much with your problem as I don't think you can hack you way out of it. It is much more common practice that tooltip code is injected into the bottom of the page so that it naturally stacks above everything else.

Related

CLS (Cummulative Layout Shift ) in sticky navigations with position: fixed

With the new Web Vitals incoming I have a problem with my sticky navigations/menus. In fact most pages will have :-(
The problem is that I use an approach like bootstrap affix to make the menu sticky when it would leave the viewport. But every time the menu leaves the viewport (and enters it as well) and the position is set from relative/static/absolute to fixed it increases CLS (Cumulative Layout Shift). I realize that changing the position to fixed will result in a layout shift because the element is removed from the layer and all following elements will be shifted to the top.
BUT: That's why I came up with some solutions and the best I think is that I use a wrapper with a specific height around the menu. So when the position of the menu changes to fixed the wrapper still exists and does not change in position or height, which means that no following elements has to shift. But the CLS is still counting up. And I do not know what to do to make my menus sticky without affecting the CLS which is important. Btw I cannot use position: sticky because there is not enough browser support. Because if my researches are correct position: sticky works without negatively affecting the CLS, my solution does not although the user **does not see any difference at all **....
Here comes some pseudo code to be more visual:
...
<body>
<h1>
Headline
</h1>
<p>
Here is some elements an stuff
</p>
<div class="menu-wrapper">
<div class="menu">
<ul>...........</ul>
</div>
</div>
<p>
More elements and stuff. Nothing shifting because the wrapper always has the same height.
</p>
...
</body>
...
.menu-wrapper {
height: 60px;
width: 100%;
}
.menu {
height: 60px;
width: 100%;
position: static;
}
.menu.affix {
position: fixed;
top: 0;
}
Any ideas? Thank you very much!
This may be fixed in Chrome Canary 90.
Context: CLS change log reports couple of improvements in this regards: https://chromium.googlesource.com/chromium/src/+/master/docs/speed/metrics_changelog/cls.md:
Cumulative Layout Shift Changelog
This is a list of changes to Cumulative Layout Shift.
Metric definition improvement: Bug fixes involving changes to transform, effect, clip or position
Metric definition improvement: Consider transform change countering layout shift.
Other fixes from Chrome 89 listed on the same page may apply also.

How to keep underlay element hover when upper element pass through

i have a situation when some div i hover on calls tooltip. And I have re-positioning logic in case tooltip does not fit the screen. But i faced a problem (epecially in FireFox) that when tooltip travels over "caller" div, "caller" div looses its hover state. This is 100% reproducible in FF, in Chrome works on some machines and on some does not.
Is there any solution for this?
I have creatted jsfiddle to show this. You will see that animation gets canceled - and yes i can do some workaround in such a simple case but reall situation is much more complex.
jsfiddle.net/5c1fdw6o/9/
You may apply CSS: pointer-events: none; to the top layer, for that.
In your case:
.sliding-tooltip {
pointer-events: none;
}
I would recommend switching html divs so the span would be above the other div.
<div class="container">
<div class="sliding-tooltip">
I slide to the right
</div>
<span class="hover-item">Hover me!</span>
</div>
If this isn't enough you could use z-index on both elements to make sure div is always on top of the other. But make sure to position the span as relative.
.hover-item {
color: blue;
position: relative;
z-index: 10;
}

Layer is not being display even though it was assigned high z-index

I am facing an issue with a div not being displayed when it is toggled from display: none; to display: block;
HTML:
<div class="menus-container" style="display: block; top: 50px; height: 277px;">
.. some pretent content, which shows up in another place on the website ...
</div>
Which is toggled by js by a plugin JS which is minified so I cannot list the js, but I see in the developer toolbar that the style changes work.
I see that it has a height, I see that it has a width and a z-index of about 99999.To be sure I assigned in the developer tool bars all parent elements as well an z-index: 999 !important;
Still that div wont show up... any ideas? If you want to look at the example follow this link (redacted) - it only happens at a width of less than 850px.
The problem here isn't a z-index issue, it's that the menu is appearing outside of its parent, the header element, which has overflow set to hidden. Setting the overflow to visible reveals the menu. You'll want to do some other things too, like give the menu a solid background color so it's easier to read.
<header class="main-header collapsed-gallery-page-menu" style="overflow: visible;">

Minimum / Maximum absolute position in CSS

What is the best approach to restricting an absolutely positioned element's position, ideally in pure CSS?
I know that the following isn't possible but I guess what I'm looking for would look something like:
.stickyElement{
bottom-max:auto;
bottom-min:0px;
top-max: auto;
top-min: 100px;
}
That would allow an element to move to a position no less than 100px from the top of it's containing, positioned element.
An example (and my initial) use case for this is a menu that scrolls as part of a page but stops scrolling when it hits the top of a viewport. (Sticky menus?) an example of which can be seen on this page:
http://spektrummedia.com/startups
I fully expect that this is not possible without using some Javascript but I thought I'd put it out there.
position: sticky
There have been discussions in the W3C about this in recent years. One proposal is the addition of a sticky value for the position property.
.content {
position: -webkit-sticky;
position: -moz-sticky;
position: -ms-sticky;
position: -o-sticky;
position: sticky;
top: 10px;
}
This is currently supported in Chrome 23.0.1247.0 and later as an experimental feature. To enable it, enter about:flags for the URL address and press enter. Then search for "experimental WebKit features" and toggle it between enabled and disabled.
On the html5rocks website, there's a working demo.
Strictly speaking, this is an implementation of sticky content, and not a general-purpose way to limit the minimum or maximum position of an element relative to another element. However, sticky content might be the only practical application for the type of the behavior you're describing.
As there is no way to build this for all major browsers without the use of JavasScript I made my own solution with jQuery:
Assign position:relative to your sticky-top-menu. When it reaches the top of the browser window through scrolling the position is changed to positon:fixed.
Also give your sticky-top-menu top:0 to make sure that it sticks to the top of your browser window.
Here you find a working JSFiddle Example.
HTML
<header>I'm the Header</header>
<div class="sticky-top-menu">
<nav>
Page 1
Page 2
</nav>
</div>
<div class="content">
<p>Some content...</p>
</div>
jQuery
$(window).scroll(function () {
var headerTop = $("header").offset().top + $("header").outerHeight();
if ($(window).scrollTop() > headerTop) {
//when the header reaches the top of the window change position to fixed
$(".sticky-top-menu").css("position", "fixed");
} else {
//put position back to relative
$(".sticky-top-menu").css("position", "relative");
}
});
CSS
.sticky-top-menu {
position:relative;
top: 0px;
width: 100%;
}
I know this post is old, and I might be a little late to it, but to anyone still wondering how to do this i would suggest checking out the clamp() method in CSS, you could do something like this:
top: clamp(30px, 10vw, 50px);
Which would set the min top value to 30px, the ideal value to 10vw, and the max value to 50px.
A media query expression that defines the distance between body 0X 0Y and browser-window 0X 0Y would allow elements to be made sticky after page is scrolled
No such expression has otherwise been proposed and is not supported by any browser, to my knowledge, but it would be a useful expression to allow dynamic configuration of sticky elements, such as menu bars that are sticky after page is scrolled past head, without use of JavaScript.
.this element {
position: absolute;
top: 200px;
}
#media (max-scroll: 200px 0) {
.this.element {
position:fixed;
top: 0;
}
}
To my knowledge, there is no way to restrict an element that was positioned using absolute positioning using solely CSS.

Javascript Drop Down Menu over Image Rotator

Designer here, trying to code.
I am almost there! Trying to get a drop down menu from dynamic drive to work over an jQuery image rotator. Played with z-index. I can get the menu to work over the image rotation on all browsers except in IE compatibility mode, cannot click on the buttons in the rotator.
http://local495.bigrigmedia.com/
Any help would be greatly appreciated!
Always so much easier to get everything looking right in Photoshop eh? You can fix your overlap issue with 2 minor tweaks to the CSS:
styles.css
#top {
position: relative;
z-index: 2;
height: 155px;
}
ddsmoothmenu.css
.ddsmoothmenu{
position: relative;
z-index: 2;
/* remaining css */
}
homerotation.css
div#feature_list {
position: relative;
z-index: 1;
/* remaining css */
}
I also noticed you had a lot of z-index: -100 sprinkled around your CSS. Those are also going to cause you trouble. I would suggest taking them all out and just using the above 2 changes.
What the above 2 rules do is establish the stacking order for the menu and image rotator in a way that all browsers (including our friend IE) understands.
The trick with IE when using z-index is to make sure all the elements you're trying to overlap are in the same stacking context. IE creates a new stacking context whenever you use relative, absolute or fixed position on an element. In our case above, we're setting the stacking order on the top most elements in the stacking context (i.e. the document), therefore it will be respected.
Edit
Added a z-index to the #top container as this is actually the <div> that's at the same level in the document as <div id="feature_list">.

Categories

Resources