Table of Contents
- copyright
- introduce
- tool-tip
-
- centered on
- animation effect
- width
- boundary
- tool-tip::after
-
- scope
- tapered gradient
- -webkit-mask
- Where did the sharp corner come from?
- appendix
-
- full code
Copyright
This article is original, following the CC 4.0 BY-SA copyright agreement, reprints must indicate the source: https://blog.csdn.net/big_cheng/article/details/130262213.
Introduction
https://web.dev/building-a-tooltip-component/ introduces the implementation of a tooltip. This article simplifies it and analyzes the principle. The effect comparison diagram is as follows:
When the mouse hovers to the parent container, the tooltip will appear.
tool-tip
tooltip is implemented as a child element:
a<br>b<br>c<br> preceding <div id="ct" style="display: inline-block; border: 1px solid;"> div content div content div content <tool-tip>this is tip content</tool-tip> </div>
The browser actually sees this unknown “tool-tip” element as a “div”.
Centered on top
Tooltip is absolutely positioned, docked above the parent container:
tool-tip {<!-- --> --_triangle-size: 7px; \t position: absolute; bottom: calc(100% + 0.75ch + var(--_triangle-size)); ?…
To achieve horizontal centering, first center the left edge, and then offset half of its own width to the left:
left: 50%; transform: translateX(-50%) translateY(3px);
Animation effect
Display the tooltip by modifying “opacity”, and fine-tune the y value to achieve a slight ‘jump’:
tool-tip {<!-- --> ?… opacity: .2; transform: translateX(-50%) translateY(3px); transition: opacity .2s ease, transform .2s ease; ?… } #ct {<!-- --> position: relative; } #ct:hover > tool-tip {<!-- --> opacity: 1; transform: translateX(-50%) translateY(0); transition-delay: 200ms; }
“translateY” positive value is down.
Note: For the convenience of debugging, the initial “opacity” was changed to “.2”.
width
tool-tip {<!-- --> ?… width: max-content; max-width: 25ch; text-align: center;
Determine the width according to the content. Debugging can find that when the screen width is compressed to the tool-tip ‘inside’, the body appears HScroll.
Boundary
tool-tip has no border line – similar effect can be achieved by filter:
will-change: filter; filter: drop-shadow(0 3px 3px hsl(0 0% 0% / 15%)) drop-shadow(0 12px 12px hsl(0 0% 0% / 15%)); }
tool-tip::after
Use ::after to achieve a sharp corner on the bottom edge of the tooltip.
Range
The ::after element uses absolute positioning and occupies the area of the tool-tip:
tool-tip::after {<!-- --> ?… background: white; position: absolute; z-index: -1; top: 0; right: 0; left: 0; bottom: -7px; border-bottom: 7px solid transparent; ?…
Bottom extends 7px more – for sharp corners.
debugging:
a) Disable “opacity|filter” of tool-tip, add “border: 1px solid”
b) Modify ::after: “background: red;”
It can be seen that ::after is within the range of tool-tip (as the parent container) and descends.
Tapered Gradient
For example, the small black block below the horizontal line:
<style> #ct2 {<!-- -->width: 50px; height: 50px; background: white conic-gradient( from -30deg at bottom, #0000, #000 1deg 60deg, #0000 61deg); ?… } </style> <div id="ct2"></div>
a) Vertical upward from the origin is 0 degrees, and -30 degrees is to the left (counterclockwise)
b) The origin “bottom” is “bottom center” – the midpoint at the bottom of the decorated container
c) “#0000”: The line 30 degrees to the left is black and fully transparent (the fourth zero)
d) “#000 1deg 60deg”: The range from 1 to 60 degrees to the right (clockwise) of the previous line is black (the previous transparent line plays the role of anti-aliasing)
e) “#0000 61deg”: Finally, it is black and transparent by 1 degree to the right, and it is still anti-aliasing
f) The rest of the 360-degree range is undefined – display the background color (white) previously defined by the conic-gradient
-webkit-mask
Apply a tapered gradient to the lower side of the ::after element:
tool-tip::after {<!-- --> ?… -webkit-mask: conic-gradient(from -30deg at bottom, #0000, #000 1deg 60deg, #0000 61deg) bottom / 100% 50% no-repeat; mask: conic-gradient(from -30deg at bottom, #0000, #000 1deg 60deg, #0000 61deg) bottom / 100% 50% no-repeat;
a) “bottom”: The starting position of the tapered mask image is the midpoint below the mask area. The mask area is the border-box of the decorated container by default.
b) “100% 50%”: The size of the mask image. This is the entire horizontal and vertical half of the mask area.
c) “no-repeat”: No repetition, that is, the mask image will not be drawn horizontally and vertically.
Note: Chrome uses “-webkit-mask” instead of “mask”.
debugging:
a) Modify ::after: “background: red;”
Visible mask plots are drawn starting from the midpoint at the bottom of the ::after element.
Because ::after “z-index” is -1, the content of ::after is displayed below the content of tool-tip (does not ‘cut’ the text).
How did the sharp corner come from?
debugging:
a) tool-tip: disable “opacity”, add “border: 1px solid”
b) ::after modification: “background: red; border-bottom: 7px solid blue;”
::after Comparison of disabling and enabling “-webkit-mask”:
The ::after color is only preserved within the black area of the tapered gradient (tool-tip border-bottom overlap is also ‘wiped out’).
The tool-tip “filter” creates a shadow effect on the sharp corners and the bottom edges on both sides. If “filter” is disabled, the sharp corners cannot be seen, only a small gap in the middle of the bottom edge.
Appendix
Complete code
a<br>b<br>c<br> preceding <div id="ct" style="display: inline-block; border: 1px solid;"> div content div content div content <tool-tip>this is tip content</tool-tip> </div>