import React, {useState, useEffect} from "react";
// The tooltip ponent is used for the Tooltip feature that is utilized
const Tooltip = (couponProps) => {
const { couponTheme, verticalMousePosition, data, showTooltip, isSwiper } = couponProps;
const { TooltipText } = data;
const [tooltipStyles, setTooltipStyles] = useState({display: 'none'});
const [tooltipArrowStyles, setTooltipArrowStyles] = useState({display: 'none'});
const { TooltipTextColor, TooltipBackgroundColor, TooltipFontSize } = couponTheme;
// The useEffect hook will first define all the tooltip styling as objects. If the showTooltip variable defined in the parent element is active, render the tooltip.
useEffect(() => {
const topTooltipStyles = {
bottom: '130%',
left: '20%',
right: '20%',
width: '60%'
}
const topTooltipArrowStyles = {
top: '100%',
left: '50%',
marginLeft: '-5px',
borderColor: (TooltipBackgroundColor || 'black') + ' transparent transparent transparent',
marginTop: 'unset'
}
const bottomTooltipStyles = {
top: '125%',
left: '20%',
right: '20%',
width: '60%'
}
const bottomTooltipArrowStyles = {
bottom: '100%',
left: '50%',
marginLeft: '-5px',
borderColor: 'transparent transparent ' + (TooltipBackgroundColor || 'black') + ' transparent'
}
if (showTooltip) {
// The tooltip is configured to either render at the top of the interval bar or at the bottom of the interval bar. That is pased on where the mouse is located on the screen.
let tooltipPositionStyles = {};
let tooltipArrowPositionStyles = {};
// If the vertical mouse position is less than 250px to the top, render the tooltip at the bottom under the parent ponet. This means the user is at the top of the screen, so use the bottom styling.
if (verticalMousePosition < 250 || isSwiper) {
// This way, the tooltip will not be cut of from the top of the screen.
tooltipPositionStyles = bottomTooltipStyles;
tooltipArrowPositionStyles = bottomTooltipArrowStyles;
// Else, that means the user is not at the top of the screen
} else {
tooltipPositionStyles = topTooltipStyles;
tooltipArrowPositionStyles = topTooltipArrowStyles;
}
const tooltipArrowStylesObj = {
content: ' ',
position: 'absolute',
borderWidth: '5px',
borderStyle: 'solid',
...tooltipArrowPositionStyles
}
const tooltipStylesObj = {
position: 'absolute',
color: TooltipTextColor || 'white',
background: TooltipBackgroundColor || 'black',
padding: '10px',
borderRadius: '10px',
zIndex: '5000',
textAlign: 'center',
...tooltipPositionStyles
}
// Set all of the arrow styles after determining if the tooltip is on top or on bottom.
setTooltipArrowStyles(tooltipArrowStylesObj);
setTooltipStyles(tooltipStylesObj);
} else {
// If the showTooltip variable is false, hide the tooltip.
setTooltipArrowStyles({});
setTooltipStyles({display: 'none'});
}
}, [showTooltip, verticalMousePosition, TooltipBackgroundColor, TooltipTextColor, isSwiper])
return (
<>{TooltipText !== undefined && TooltipText.trim() !== '' && TooltipText !== 'None' && TooltipText !== 'Inset Tooltip Text Here' && showTooltip ?
<div className='TooltipDiv' style={tooltipStyles}>
<span className="ToolTipText" style={{fontSize: TooltipFontSize || '12px'}}>{TooltipText}</span>
<span className="ToolTipArrow" style={tooltipArrowStyles}></span>
</div>
: null}</>
);
}
export default Tooltip;
import React, {useState, useEffect} from "react";
// The tooltip ponent is used for the Tooltip feature that is utilized
const Tooltip = (couponProps) => {
const { couponTheme, verticalMousePosition, data, showTooltip, isSwiper } = couponProps;
const { TooltipText } = data;
const [tooltipStyles, setTooltipStyles] = useState({display: 'none'});
const [tooltipArrowStyles, setTooltipArrowStyles] = useState({display: 'none'});
const { TooltipTextColor, TooltipBackgroundColor, TooltipFontSize } = couponTheme;
// The useEffect hook will first define all the tooltip styling as objects. If the showTooltip variable defined in the parent element is active, render the tooltip.
useEffect(() => {
const topTooltipStyles = {
bottom: '130%',
left: '20%',
right: '20%',
width: '60%'
}
const topTooltipArrowStyles = {
top: '100%',
left: '50%',
marginLeft: '-5px',
borderColor: (TooltipBackgroundColor || 'black') + ' transparent transparent transparent',
marginTop: 'unset'
}
const bottomTooltipStyles = {
top: '125%',
left: '20%',
right: '20%',
width: '60%'
}
const bottomTooltipArrowStyles = {
bottom: '100%',
left: '50%',
marginLeft: '-5px',
borderColor: 'transparent transparent ' + (TooltipBackgroundColor || 'black') + ' transparent'
}
if (showTooltip) {
// The tooltip is configured to either render at the top of the interval bar or at the bottom of the interval bar. That is pased on where the mouse is located on the screen.
let tooltipPositionStyles = {};
let tooltipArrowPositionStyles = {};
// If the vertical mouse position is less than 250px to the top, render the tooltip at the bottom under the parent ponet. This means the user is at the top of the screen, so use the bottom styling.
if (verticalMousePosition < 250 || isSwiper) {
// This way, the tooltip will not be cut of from the top of the screen.
tooltipPositionStyles = bottomTooltipStyles;
tooltipArrowPositionStyles = bottomTooltipArrowStyles;
// Else, that means the user is not at the top of the screen
} else {
tooltipPositionStyles = topTooltipStyles;
tooltipArrowPositionStyles = topTooltipArrowStyles;
}
const tooltipArrowStylesObj = {
content: ' ',
position: 'absolute',
borderWidth: '5px',
borderStyle: 'solid',
...tooltipArrowPositionStyles
}
const tooltipStylesObj = {
position: 'absolute',
color: TooltipTextColor || 'white',
background: TooltipBackgroundColor || 'black',
padding: '10px',
borderRadius: '10px',
zIndex: '5000',
textAlign: 'center',
...tooltipPositionStyles
}
// Set all of the arrow styles after determining if the tooltip is on top or on bottom.
setTooltipArrowStyles(tooltipArrowStylesObj);
setTooltipStyles(tooltipStylesObj);
} else {
// If the showTooltip variable is false, hide the tooltip.
setTooltipArrowStyles({});
setTooltipStyles({display: 'none'});
}
}, [showTooltip, verticalMousePosition, TooltipBackgroundColor, TooltipTextColor, isSwiper])
return (
<>{TooltipText !== undefined && TooltipText.trim() !== '' && TooltipText !== 'None' && TooltipText !== 'Inset Tooltip Text Here' && showTooltip ?
<div className='TooltipDiv' style={tooltipStyles}>
<span className="ToolTipText" style={{fontSize: TooltipFontSize || '12px'}}>{TooltipText}</span>
<span className="ToolTipArrow" style={tooltipArrowStyles}></span>
</div>
: null}</>
);
}
export default Tooltip;
So the code is passed the vertical mouse position as a prop and if the mouse is within 250 from the top of the page the tooltip is rendered below the ponent hovered. It all works fine if the ponent renders above and the mouse is lower down the page because there is nothing above to obstruct the tooltip, but when the ponent renders below, with bottomTooltipStyles, it is absolutely positioned but the issue is it is rendering behind another ponent. My gut said it was obviously the z-index, but this tooltip has a zIndex of 5000 which is significantly larger than the next largest z-index on the page at 60. Checking google chrome dev tools, the styles are all appropriate, the ponent renders, but it is still somehow behind/hidden behind another ponent no matter what I do. Any ideas would be greatly appreciated!! Thanks in advance!
So my question can also be asked like, "Is there a css property that would cause an element to render 'above' (over) another element that has an arbitrarily high z-index?"
Share Improve this question edited Jun 1, 2022 at 21:50 FODpatrick asked May 27, 2022 at 17:24 FODpatrickFODpatrick 1012 silver badges8 bronze badges 3-
1
Can you try changing
zIndex
value to a number?5000
not'5000'
– A G Commented May 28, 2022 at 8:08 - snippet don't seem to be working, please update – Jacouille Commented Jun 1, 2022 at 22:04
- Provided code snippet is not working, but what I understood from your code is that your issue has to do something with the "Stacking Context". So, please try resolving your issue by following what @lfalin has suggested & if not then please update the snippet so, that we can have a look and tell you the exact cause for your issue. – Ddmteetu Commented Jun 7, 2022 at 13:37
2 Answers
Reset to default 5 +25Most of the gotchas with z-index
have to do with "stacking context".
Elements are stacked on the z-axis
within their stacking context.
Elements without position
or explicit z-index
values all share the same stacking context and are rendered in order of appearance in the rendered HTML.
Here are some specific z-index
gotchas related to stacking context that may be affecting you:
1. z-index only applies to positioned elements
That is, position: absolute
, position: relative
, position: fixed
, or position: sticky
) and flex items. [1]
So first, make sure the elements you want to position on the z-axis are all explicitly positioned.
2. Some css properties can move an element into a new stacking context.
Some mon ones are opacity
and transform
. Here is a list of CSS properties that can affect the stacking context.
And here is a detailed explanation on how opacity values affect stacking context:
Since an element with opacity less than 1 is posited from a single offscreen image, content outside of it cannot be layered in z-order between pieces of content inside of it. For the same reason, implementations must create a new stacking context for any element with opacity less than 1. If an element with opacity less than 1 is not positioned, then it is painted on the same layer, within its parent stacking context, as positioned elements with stack level 0. If an element with opacity less than 1 is positioned, the ‘z-index’ property applies as described in [CSS21], except that if the used value is ‘auto’ then the element behaves exactly as if it were ‘0’. [2]
To fix these, explicitly set the position
and z-index
so that they will be evaluated relative to the other positioned elements.
3. If an element's parent z-index (and position) is set, then that element's z-index will only apply within the parent.
In other words, the parent element is the stacking context.
To fix this, you can either modify the HTML hierarchy, or remove the position of the parent, or modify its z-index.
There are some good visuals and code examples for these situations here: https://www.freecodecamp/news/4-reasons-your-z-index-isnt-working-and-how-to-fix-it-coder-coder-6bc05f103e6c/
I had the same issue when rendering multiple ponents in one parent ponent. My popup div didn't appear on top of other ponents even though it had a higher z-index.
After a little bit of research, I found this answer helpful. I had to move the popup ponent above everything else.
Also, please fix your code snippet so we can find out exactly what's wrong.