html 在悬停可滚动项目上显示工具提示

l3zydbqr  于 2023-10-14  发布在  其他
关注(0)|答案(2)|浏览(98)

在垂直导航列表中显示工具提示时遇到问题。
这里有一个我的问题的例子:https://codepen.io/achillebourgault/pen/ZEVVbGe?editors=1100
基本上,我有一个父div .leftnav-wrapper,您可以在其上上下滚动以展开其内容。每个项目都用一个.listitem div表示,当您悬停时,将显示一个工具提示。但是,此工具提示将被切断,因为它不能超过父对象的宽度。
我该如何解决这个问题?
我首先尝试了一个元素显示:inline-flex;通过将.leftnav-wrapper显示为第一个元素,将.content显示为第二个元素,但我仍然遇到了同样的问题。然后我试着把相对位置和.leftnav-wrapper放在固定位置,但我仍然有同样的问题。

<main>
  <div class="leftnav-wrapper">
    <div class="leftnav">
      <div class="listitem">
        <button>A</button>
        <div class="listitem-name">
          Example Item Name
        </div>
      </div>
    <div class="listitem">
        <button>A</button>
        <div class="listitem-name">
          Example Item Name
        </div>
      </div>
      <div class="listitem">
        <button>A</button>
        <div class="listitem-name">
          Example Item Name
        </div>
      </div>
      <div class="listitem">
        <button>A</button>
        <div class="listitem-name">
          Example Item Name
        </div>
      </div>
      <div class="listitem">
        <button>A</button>
        <div class="listitem-name">
          Example Item Name
        </div>
      </div>
      <div class="listitem">
        <button>A</button>
        <div class="listitem-name">
          Example Item Name
        </div>
      </div>
      <div class="listitem">
        <button>A</button>
        <div class="listitem-name">
          Example Item Name
        </div>
      </div>
      <div class="listitem">
        <button>A</button>
        <div class="listitem-name">
          Example Item Name
        </div>
      </div>
      <div class="listitem">
        <button>A</button>
        <div class="listitem-name">
          Example Item Name
        </div>
      </div>
      
      <div class="listitem">
        <button>A</button>
        <div class="listitem-name">
          Example Item Name
        </div>
      </div>
      
      <div class="listitem">
        <button>A</button>
        <div class="listitem-name">
          Example Item Name
        </div>
      </div>
      
      <div class="listitem">
        <button>A</button>
        <div class="listitem-name">
          Example Item Name
        </div>
      </div>
  </div>
 </div>
  <div class="content">
    Content
  </div>
</main>
* {
  margin: 0;
  padding: 0;
}

main {
  height: 100vh;
  width: 100%;
  overflow: hidden;
}

.leftnav-wrapper {
    width: 68px;
    max-height: 100vh;
    overflow-y: auto;
    overflow-x: hidden;
    position: fixed;
    z-index: 999;
}

.leftnav-wrapper::-webkit-scrollbar {
    width: 0;
    background: transparent;
}

.leftnav-wrapper::-webkit-scrollbar-thumb {
    background: transparent;
}

.leftnav-wrapper::-webkit-scrollbar-track {
    background: transparent;
}

.leftnav {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.listitem {
  background: #cecece;
  height: 52px;
  width: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.listitem-name {
  visibility: hidden;
  opacity: 0;
  position: absolute;
  left: 52px;
  transition; all 0.3s;
  background: green;
  width: 100px;
  overflow: visible;
  z-index: 999;
}

.listitem:hover .listitem-name {
  visibility: visible;
  opacity: 1;
  transition; all 0.3s;
}

.content {
  padding-left: 68px;
  background: black;
  width: 100%;
  height: 100vh;
  color: white;
}

这是我在创建一个codepen来隔离问题之前所处理的代码:

import React from "react";

import styles from './LeftNavigation.module.css';

import {ServerListExample} from "../../assets/examples/ServerListExample";

export default function LeftNavigation() {
    return (
        <div className={styles.leftNavigation}>
            <div className={styles.listItem + " " + styles.privateMessages}>
                <div className={styles.listItemIcon + " " + styles.privateMessagesActive}>
                    <img src={"/images/discord-logo.png"} alt="Private Messages"/>
                    <div className={styles.listItemIconName}>Private Messages</div>
                </div>
            </div>
            <div className={styles.listItemSep}></div>
            <div className={styles.serversList}>
                {
                    ServerListExample.map((server, index) => {
                        return server.type === 'server' ? (
                            <div className={styles.listItem} key={index}>
                                <div className={styles.listItemIcon}>
                                    <img src={server?.avatar} alt={server?.name}/>
                                    <div className={styles.listItemIconName}>{server?.name}</div>
                                </div>
                            </div>
                        ) : (
                            <div className={styles.listItemGroup} key={index}>
                                <div className={styles.listItemGroupTitle}>
                                    <svg aria-hidden="true" role="img" width="24" height="24" viewBox="0 0 24 24" style={{color: 'rgb(88, 101, 242)'}}><path fill="currentColor" d="M20 7H12L10.553 5.106C10.214 4.428 9.521 4 8.764 4H3C2.447 4 2 4.447 2 5V19C2 20.104 2.895 21 4 21H20C21.104 21 22 20.104 22 19V9C22 7.896 21.104 7 20 7Z"></path></svg>
                                    <div className={styles.listItemGroupTitleName}>{server?.name}</div>
                                </div>
                                {server.childList.map((child, index) => {
                                    return (
                                        <div className={styles.listItem} key={index}>
                                            <div className={styles.listItemIcon}>
                                                <img src={child?.avatar} alt={child?.name}/>
                                                <div className={styles.listItemIconName}>{child?.name}</div>
                                            </div>
                                        </div>
                                    )
                                })}
                            </div>
                        )
                    })
                }
            </div>
        </div>
    )
}
/* LeftNavigation.module.css */

.leftNavigation {
    background: transparent;
    height: 100%;
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 8px;
    width: var(--left-navigation-width);
    user-select: none;
    align-items: center;
    z-index: 999;
    max-height: calc(100% - 16px);
    overflow-y: auto;
    position: relative;
}

.leftNavigation::-webkit-scrollbar {
    width: 0;
    background: transparent;
}

.leftNavigation::-webkit-scrollbar-thumb {
    background: transparent;
}

.leftNavigation::-webkit-scrollbar-track {
    background: transparent;
}

.listItem {
    display: flex;
    align-items: center;
    justify-content: center;
}

.listItemIcon {
    width: 50px;
    height: 50px;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    border-radius: 25px;
    transition: all 0.3s;
    align-items: stretch;
    cursor: pointer;
}

.privateMessages .listItemIcon {
    align-items: center;
}

.listItemIcon .listItemIconName {
    position: absolute;
    top: 50%;
    left: 40px;
    transform: translateY(-50%);
    background: var(--black-100);
    color: #cecece;
    padding: 8px;
    border-radius: 8px;
    font-weight: bold;
    opacity: 0;
    transition: opacity 0.3s;
    display: none;
    z-index: 9999;
}

.listItemIcon:hover .listItemIconName {
    display: block;
    opacity: 1;
    transition: opacity 0.3s;
    position: absolute;
}

.listItemIcon:hover,
.listItemIcon:hover > img {
    border-radius: 16px;
    transition: all 0.3s;
}

.listItemIcon > img {
    border-radius: 50%;
    transition: all 0.3s;
    height: 48px;
    width: 48px;
}

.privateMessages img {
    height: 26px !important;
    width: 26px !important;
    object-fit: contain;
}

.listItemSep {
    margin: 0 auto 6px;
    width: 66%;
    border-bottom: solid var(--grey-200) 2px;
}

.privateMessagesActive {
    background: #5764f0;
}

.listItemGroup {
    display: flex;
    flex-direction: column;
    gap: 12px;
    width: fit-content;
    place-self: center;
    background: var(--grey-300);
    border-radius: 50px;
}

.listItemGroup .listItem:last-child img {
    margin-top: 2px;
}

.listItemGroupTitle {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 44px;
}

.listItemGroupTitle svg {
    height: 24px;
    width: 24px;
    fill: var(--grey-000);
    transition: all 0.3s;
}

.listItemGroupTitle .listItemGroupTitleName {
    display: none;
    opacity: 0;
    transition: opacity 0.3s;
    position: fixed;
    z-index: 1000;
}

.listItemGroupTitle:hover .listItemGroupTitleName {
    display: block;
    opacity: 1;
    transition: opacity 0.3s;
}

.serversList {
    display: flex;
    flex-direction: column;
    gap: 8px;
    width: 100%;
    margin-top: -6px;
}
e37o9pze

e37o9pze1#

欢迎来到Stackoverflow!
如果将main的CSS替换为:

main {
  display: flex;
  background: black
}

然后将.leftnav-wrapper的CSS替换为:

.leftnav-wrapper {
    width: 68px;
}

我想它会像你预期的那样工作!

kx7yvsdv

kx7yvsdv2#

谢谢!它实际上纠正了我的codepen问题。然而,我试图将解决方案集成到我的项目中,我不明白我做错了什么
App.js

// src/App.js
import React from 'react';
import TitleBar from "./components/TitleBar/TitleBar";

import LeftNavigation from "./components/LeftNavigation/LeftNavigation";
import LeftNavigationExtended from "./components/LeftNavigationExtended/LeftNavigationExtended";

import {useState} from "react";
import './assets/css/index.css';

function App() {
    const [user, setUser] = useState({
        name: 'JohnDoe74',
        avatar: 'https://media-cldnry.s-nbcnews.com/image/upload/t_nbcnews-fp-1200-630,f_auto,q_auto:best/rockcms/2022-01/210602-doge-meme-nft-mb-1715-8afb7e.jpg',
        activity: 'online',
        microMuted: false,
        soundMuted: false,
    });

  return (
      <div className="parent">
        <TitleBar />

        <main>
            <div className="leftNavWrapper">
                <LeftNavigation />
            </div>
          <div className="content">
              <LeftNavigationExtended user={user} />
          </div>
        </main>
      </div>
  );
}

export default App;

index.css

.parent {
    height: 100%;
    width: 100%;
}

.parent main {
    display: flex;
    /*height: calc(100vh - var(--title-bar-height));*/
}


.private-messages {
    /*width: 100%;*/
    /*height: 100%;*/
    /*display: flex;*/
    /*flex-direction: column;*/
    /*gap: 6px;*/
    /*padding: 8px;*/
    /*overflow-y: auto;*/
}

.content {
    /*border-top-left-radius: 8px;*/
    /*width: calc(100vw -var(--left-navigation-width));*/
    /*height: calc(100vh - var(--title-bar-height));*/
    /*background: var(--black-300);*/
    width: 100%;
    height: 100vh;
    color: white;
}

.leftNavWrapper {
    width: var(--left-navigation-width);
}

.leftNavWrapper::-webkit-scrollbar {
    width: 0;
    background: transparent;
}

.leftNavWrapper::-webkit-scrollbar-thumb {
    background: transparent;
}

.leftNavWrapper::-webkit-scrollbar-track {
    background: transparent;
}

LeftNavigation.js

import React from "react";

import styles from './LeftNavigation.module.css';

import {ServerListExample} from "../../assets/examples/ServerListExample";

export default function LeftNavigation() {
    return (
        <div className={styles.leftNavigation}>
            <div className={styles.listItem + " " + styles.privateMessages}>
                <div className={styles.listItemIcon + " " + styles.privateMessagesActive}>
                    <img src={"/images/discord-logo.png"} alt="Private Messages"/>
                    <div className={styles.listItemIconName}>Private Messages</div>
                </div>
            </div>
            <div className={styles.listItemSep}></div>
            <div className={styles.serversList}>
                {
                    ServerListExample.map((server, index) => {
                        return server.type === 'server' ? (
                            <div className={styles.listItem} key={index}>
                                <div className={styles.listItemIcon}>
                                    <img src={server?.avatar} alt={server?.name}/>
                                    <div className={styles.listItemIconName}>{server?.name}</div>
                                </div>
                            </div>
                        ) : (
                            <div className={styles.listItemGroup} key={index}>
                                <div className={styles.listItemGroupTitle}>
                                    <svg aria-hidden="true" role="img" width="24" height="24" viewBox="0 0 24 24" style={{color: 'rgb(88, 101, 242)'}}><path fill="currentColor" d="M20 7H12L10.553 5.106C10.214 4.428 9.521 4 8.764 4H3C2.447 4 2 4.447 2 5V19C2 20.104 2.895 21 4 21H20C21.104 21 22 20.104 22 19V9C22 7.896 21.104 7 20 7Z"></path></svg>
                                    <div className={styles.listItemGroupTitleName}>{server?.name}</div>
                                </div>
                                {server.childList.map((child, index) => {
                                    return (
                                        <div className={styles.listItem} key={index}>
                                            <div className={styles.listItemIcon}>
                                                <img src={child?.avatar} alt={child?.name}/>
                                                <div className={styles.listItemIconName}>{child?.name}</div>
                                            </div>
                                        </div>
                                    )
                                })}
                            </div>
                        )
                    })
                }
            </div>
        </div>
    )
}
/* LeftNavigation.module.css */

.leftNavigation {
    background: transparent;
    height: 100%;
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 8px;
    width: var(--left-navigation-width);
    user-select: none;
    align-items: center;
    z-index: 999;
    max-height: calc(100% - 16px);
    overflow-y: auto;
    position: relative;
}

.leftNavigation::-webkit-scrollbar {
    width: 0;
    background: transparent;
}

.leftNavigation::-webkit-scrollbar-thumb {
    background: transparent;
}

.leftNavigation::-webkit-scrollbar-track {
    background: transparent;
}

.listItem {
    display: flex;
    align-items: center;
    justify-content: center;
}

.listItemIcon {
    width: 50px;
    height: 50px;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    border-radius: 25px;
    transition: all 0.3s;
    align-items: stretch;
    cursor: pointer;
}

.privateMessages .listItemIcon {
    align-items: center;
}

.listItemIcon .listItemIconName {
    position: absolute;
    top: 50%;
    left: 40px; /* Ajustez la position horizontale selon vos besoins */
    transform: translateY(-50%);
    background: var(--black-100);
    color: #cecece;
    padding: 8px;
    border-radius: 8px;
    font-weight: bold;
    opacity: 0;
    transition: opacity 0.3s;
    display: none;
    z-index: 9999;
}

.listItemIcon:hover .listItemIconName {
    display: block;
    opacity: 1;
    transition: opacity 0.3s;
    position: absolute;
}

.listItemIcon:hover,
.listItemIcon:hover > img {
    border-radius: 16px;
    transition: all 0.3s;
}

.listItemIcon > img {
    border-radius: 50%;
    transition: all 0.3s;
    height: 48px;
    width: 48px;
}

.privateMessages img {
    height: 26px !important;
    width: 26px !important;
    object-fit: contain;
}

.listItemSep {
    margin: 0 auto 6px;
    width: 66%;
    border-bottom: solid var(--grey-200) 2px;
}

.privateMessagesActive {
    background: #5764f0;
}

.listItemGroup {
    display: flex;
    flex-direction: column;
    gap: 12px;
    width: fit-content;
    place-self: center;
    background: var(--grey-300);
    border-radius: 50px;
}

.listItemGroup .listItem:last-child img {
    margin-top: 2px;
}

.listItemGroupTitle {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 44px;
}

.listItemGroupTitle svg {
    height: 24px;
    width: 24px;
    fill: var(--grey-000);
    transition: all 0.3s;
}

.listItemGroupTitle .listItemGroupTitleName {
    display: none;
    opacity: 0;
    transition: opacity 0.3s;
    position: fixed;
    z-index: 1000;
}

.listItemGroupTitle:hover .listItemGroupTitleName {
    display: block;
    opacity: 1;
    transition: opacity 0.3s;
}

.serversList {
    display: flex;
    flex-direction: column;
    gap: 8px;
    width: 100%;
    margin-top: -6px;
}

相关问题