I’m having trouble displaying tooltips to a vertical navigation list.
Here’s an example of my problem: https://codepen.io/achillebourgault/pen/ZEVVbGe?editors=1100
Basically, I have a parent div .leftnav-wrapper on which you can scroll up and down to unroll its content.
Each item is represented with a .listitem div and when you hover a tooltip is displayed. However, this tooltip is cut off, as it cannot exceed the width of the parent.
How can I solve this problem?
I first tried to have a element display: inline-flex;
by displaying .leftnav-wrapper as the first element and .content as the second, but I still have the same problem.
I then tried putting in relative position and .leftnav-wrapper in fixed position, but I still have the same problem.
<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;
}
This is the code I was working on before creating a codepen to isolate the problem:
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;
}
3
Answers
Thank you! It actually corrected my codepen problem. However, I tried to integrate the solution into my project and I don't understand what I'm doing wrong
App.js
index.css
LeftNavigation.js
Welcome to Stackoverflow!
If you replace the CSS of the
main
by this :and you replace the CSS of
.leftnav-wrapper
the by this :I think it will work as you had expected!
Could you please share a Codesandbox of your app?