html - 动态居中工具提示
问题描述
我正在尝试使工具提示居中,但我希望当它溢出时它会根据位置向右或向左移动。
这是示例。我希望在这种情况下工具提示向右移动,但如果铃铛位于不会溢出的位置,则工具提示必须居中。
:root {
--blue: hsl(190, 10%, 60%);
--dark: hsl(0, 0%, 10%);
--dark-light: hsl(0, 0%, 50%);
--light: hsl(0, 0%, 100%);
}
body {
margin: 0;
font-family: sans-serif;
height: 100vh;
display: grid;
}
.main {
max-height: 100%;
margin: 10px;
display: flex;
border: 1px solid var(--dark-light);
}
.notifications {
margin:10px;
}
.notifications::before{
content: 'hover over bell';
width: 100px;
height: 100px;
}
.notifications-content {
height: 25px;
width: 25px;
position: relative;
display: flex;
justify-content: center;
}
.notifications-content svg {
height: 100%;
width: 100%;
}
.notifications-content::after {
content: attr(notifications-tooltip);
visibility: hidden;
opacity: 0;
background-color: var(--dark);
color: white;
overflow: auto;
padding: 5px;
border-radius: 10px;
position: absolute;
top: 110%;
transition: opacity 0.5s;
}
.notifications-content:hover::after {
opacity: 1;
visibility: visible;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mastering Front End</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class='main'>
<div class="notifications">
<div class='notifications-content' notifications-tooltip='Here are your notifications'>
<svg id="Layer_4" enable-background="new 0 0 24 24" height="512" viewBox="0 0 24 24" width="512" xmlns="http://www.w3.org/2000/svg"><g><path d="m21.379 16.913c-1.512-1.278-2.379-3.146-2.379-5.125v-2.788c0-3.519-2.614-6.432-6-6.92v-1.08c0-.553-.448-1-1-1s-1 .447-1 1v1.08c-3.387.488-6 3.401-6 6.92v2.788c0 1.979-.867 3.847-2.388 5.133-.389.333-.612.817-.612 1.329 0 .965.785 1.75 1.75 1.75h16.5c.965 0 1.75-.785 1.75-1.75 0-.512-.223-.996-.621-1.337z"/><path d="m12 24c1.811 0 3.326-1.291 3.674-3h-7.348c.348 1.709 1.863 3 3.674 3z"/></g></svg>
</div>
</div>
</div>
</body>
</html>
解决方案
使用 Java 脚本,您可以使用根变量来设置在伪元素中使用的单位。使用 javascript,您可以获得元素的位置并在数学上计算出位置,然后使用条件检查元素相对于窗口边缘的位置,以在 dom 中正确定位工具提示。document.documentElement
下面是一个基本示例,说明如何使用您的代码完成此操作。我在 Java Script 中添加了注释,希望能帮助您进一步了解正在发生的事情。
// set the root to the document.documentElement HTML element
const root = document.documentElement;
// get the .main element
const main = document.querySelector('.main');
// get the .notification-content element
const ntfctnsCntnt = document.querySelectorAll('.notifications-content');
// getBoundingClientRect() and computed styles
const mainRect = main.getBoundingClientRect()
const mainRight = mainRect.x + mainRect.width
const compStyleRoot = getComputedStyle(root);
const ttContWidth = compStyleRoot.getPropertyValue('--tt-cont-width');
const rootRect = root.getBoundingClientRect();
// run each nodeList through a loop
ntfctnsCntnt.forEach(el => {
// event listener on hover (mouseover)
el.addEventListener('mouseover', e => {
// set the event targets boundingClientRect
const elRect = e.target.getBoundingClientRect()
// e.targets width
const elWidth = elRect.width;
// get width of tooltip before DOM changes it using root variable
let ttcWidth = ttContWidth;
// if the tooltips width is greater than the windows left "0" + parent left => "main"
// which will be padding and/or margin, + the bell elements left then we set the
// tooltip to the right of the "bell" element
// "parseInt(ttContWidth.split('px')[0]) we are removing the px portion from the string
// and parsing this string as an integer so it can be compared with another number
if (parseInt(ttContWidth.split('px')[0]) > rootRect.left + mainRect.left + elRect.left) {
// set the varibale for --ttp-left-pos (left: ) to window.left + main.left + e.target.left
// which will be right of the element
root.style.setProperty(`--ttp-left-pos`, rootRect.left + mainRect.left + elRect.left + 'px')
} else {
// else we set the tooltip to the left of the "bell" element
root.style.setProperty(`--ttp-left-pos`, `-${parseInt(ttContWidth.split('px')[0]) + elWidth}px` )
}
})
})
:root {
--blue: hsl(190, 10%, 60%);
--dark: hsl(0, 0%, 10%, 0.8);
--dark-light: hsl(0, 0%, 50%);
--light: hsl(0, 0%, 100%);
--ttp-left-pos:0;
--ttp-top-pos:100%;
--tt-cont-width:100px;
}
body {
margin: 0;
font-family: sans-serif;
height: 100vh;
overflow-x: hidden;
display: grid;
}
.main {
max-height: 100%;
margin: 10px;
display: flex;
border: 1px solid var(--dark-light);
display: flex;
justify-content: space-between;
}
.notifications:nth-of-type(1) {
margin: 10px;
}
.notifications::before {
content: 'hover over bell';
width: 100px;
height: 100px;
}
.notifications-content {
height: 25px;
width: 25px;
position: relative;
}
.notifications:nth-of-type(2) {
margin-top: 10px;
}
.notifications-content svg {
height: 100%;
width: 100%;
}
.notifications-content::after {
content: attr(notifications-tooltip);
visibility: hidden;
opacity: 0;
background-color: var(--dark);
color: white;
overflow: auto;
padding: 5px;
border-radius: 10px;
position: absolute;
top: var(--ttp-top-pos);
left: var(--ttp-left-pos);
transition: opacity 0.5s;
width: var(--tt-cont-width);
}
.notifications-content:hover::after {
opacity: 1;
visibility: visible;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mastering Front End</title>
</head>
<body>
<div class='main'>
<div class="notifications">
<div class='notifications-content' notifications-tooltip='Here are your notifications'>
<svg id="Layer_4" enable-background="new 0 0 24 24" height="512" viewBox="0 0 24 24" width="512" xmlns="http://www.w3.org/2000/svg"><g><path d="m21.379 16.913c-1.512-1.278-2.379-3.146-2.379-5.125v-2.788c0-3.519-2.614-6.432-6-6.92v-1.08c0-.553-.448-1-1-1s-1 .447-1 1v1.08c-3.387.488-6 3.401-6 6.92v2.788c0 1.979-.867 3.847-2.388 5.133-.389.333-.612.817-.612 1.329 0 .965.785 1.75 1.75 1.75h16.5c.965 0 1.75-.785 1.75-1.75 0-.512-.223-.996-.621-1.337z"/><path d="m12 24c1.811 0 3.326-1.291 3.674-3h-7.348c.348 1.709 1.863 3 3.674 3z"/></g></svg>
</div>
</div>
<div class="notifications">
<div class='notifications-content' notifications-tooltip='Here are your notifications'>
<svg id="Layer_5" enable-background="new 0 0 24 24" height="512" viewBox="0 0 24 24" width="512" xmlns="http://www.w3.org/2000/svg"><g><path d="m21.379 16.913c-1.512-1.278-2.379-3.146-2.379-5.125v-2.788c0-3.519-2.614-6.432-6-6.92v-1.08c0-.553-.448-1-1-1s-1 .447-1 1v1.08c-3.387.488-6 3.401-6 6.92v2.788c0 1.979-.867 3.847-2.388 5.133-.389.333-.612.817-.612 1.329 0 .965.785 1.75 1.75 1.75h16.5c.965 0 1.75-.785 1.75-1.75 0-.512-.223-.996-.621-1.337z"/><path d="m12 24c1.811 0 3.326-1.291 3.674-3h-7.348c.348 1.709 1.863 3 3.674 3z"/></g></svg>
</div>
</div>
</div>
</body>
</html>
推荐阅读
- angular - Angular 自定义表单控件 - 使用 selectionChange 事件对 mat-select 进行更改检测
- c++ - OpenCV C++ 查找轮廓并获取像素值
- google-chrome-extension - 如何避免 chrome web 扩展中的跨域读取阻塞(CORB)
- react-native - 在 react native 中将完整的 android 项目导出到 iOS 的可能性
- firefox-developer-tools - 将选项卡堆栈跟踪的所有数据、Firefox DevTools 上网络面板的各种 HTTP 连接的所有数据保存在文件中?
- python-2.7 - 如何使用 pyqt4 将我的子小部件添加到树小部件
- amazon-web-services - 我是否应该获得 AWS 的(笔测试)批准才能对托管在 AWS 上的应用程序 API 进行模糊测试?
- c# - 为什么 async/await 在 UI 线程上恢复?
- javascript - Javascript - 干净的用户输入的货币价值
- bash - .bash_profile 文件发生一些更改后终端无法正常工作