我创建了一个垂直菜单,我想将其扩展到视口的整个高度,但如果这不足以容纳它,我想要一些滚动机制(在页面或垂直菜单上,这两种情况都可以) )这使我能够这样做。我尝试了多种方法,但都达不到想要的效果。
有了这个解决方案,
header.sidebar
是position:sticky
,当我在主体上滚动时,我可以看到所有垂直菜单,但只有当我滚动很多时,这对用户不友好。这是不可接受的。
/*#region BASE */
@import url("https://fonts.googleapis.com/css2?family=Anta&family=Madimi+One&display=swap");
*,
*::after,
*::before {
margin: 0;
padding: 0;
list-style: none;
box-sizing: border-box;
font-family: inherit;
}
html {
font-size: 16px;
}
body {
background-image: url("https://i.ibb.co/gDgZ3c9/background-Template.png");
background-size: cover;
background-attachment: fixed;
font-family: "Anta", sans-serif;
/* Non uso gridbox perchè gridbox imposta la dimensione delle colonne nell'elemento genitore(quindi qui nel body) con la
proprietà grid-template-columns e non riuscirei con il meccanismo dell'input:checkbox a cambiarne la dimensione
(perchè non posso selezionare il body quando l'input è checked perchè il body è l'elemento genitore).
Con flexbox invece quando clicco sull'hamburger menu basta cambiare la dimensione della sidebar */
display: flex;
/* Questa serve affinchè */
align-items: start;
}
a {
text-decoration: none;
}
/*#endregion BASE */
/*#region SIDEBAR*/
/* Uso position:sticky e top:0 left:0 perchè non voglio */
header.sidebar {
position: sticky;
/* overflow-y: auto;
overflow-x: visible; */
top: 0;
bottom: 0;
left: 0;
background-image: linear-gradient(
30deg,
rgba(5, 5, 75, 0.85),
rgba(5, 5, 75, 0.85) 20%,
rgb(5, 5, 75)
);
min-height: 100vh;
min-height: 100svh;
width: 65px;
padding: 0.4rem 0.8rem;
transition: all 0.5s ease;
}
/*#region SIDEBAR HEADER*/
.sidebar__header {
display: flex;
align-items: center;
justify-content: center;
}
.sidebar__header__logo {
display: flex;
align-items: center;
display: none;
}
.sidebar__header__logo img {
width: 50px;
}
.sidebar__header__logo span {
color: white;
}
.sidebar__header__hamburger {
cursor: col-resize;
margin-top: 0.4rem;
}
/*#endregion SIDEBAR HEADER*/
/*#region SIDEBAR USER*/
.sidebar__user {
display: flex;
justify-content: center;
}
.sidebar__user__img {
width: 50px;
height: 50px;
object-fit: cover;
border: 3px solid rgb(182, 5, 152);
border-top-color: rgb(23, 23, 201);
border-bottom-color: rgb(23, 23, 201);
border-radius: 50%;
margin-top: 20px;
}
.sidebar__user__name {
display: none;
}
/*#endregion SIDEBAR USER*/
/*#region SIDEBAR MENU*/
.sidebar__menu__item {
min-height: 40px;
margin: 10px 0;
display: flex;
align-items: center;
justify-content: center;
}
.sidebar__menu__item:hover {
border-radius: 10px;
background-color: white;
}
.sidebar__menu__item:hover .sidebar__menu__item__icon::before {
/* background-image: red; */
background-image: linear-gradient(rgb(5, 5, 75), rgb(5, 5, 75));
font-size: larger;
}
.sidebar__menu__item a {
position: relative; /* Serve per posizionare il tooltip */
display: block;
/* Le seguenti due regole servono per far si che il
tag a si sovrapponga perfettamente all'li
genitore in modo che la superficie cliccabile
del link cresca e sia uguale a quella dell'li */
width: 100%;
min-height: inherit;
display: flex;
justify-content: center;
align-items: center;
}
.sidebar__menu__item__text {
height: 3.2em;
min-width: 100px;
display: none;
font-size: 1rem;
background-color: rgb(182, 5, 152);
background-image: linear-gradient(
to right,
rgb(23, 23, 201),
rgb(182, 5, 152)
);
background-clip: text;
-webkit-text-fill-color: transparent;
}
/* Questa regola funge da fallback in caso -webkit-text-fill-color o background-clip: text;
non siano supportati */
.sidebar__menu__item__icon {
color: rgb(23, 23, 201);
}
:is(.sidebar__menu__item__icon, .sidebar__header__hamburger)::before {
background-image: linear-gradient(
to right,
rgb(23, 23, 201),
rgb(182, 5, 152)
);
background-clip: text;
-webkit-text-fill-color: transparent;
}
.sidebar__menu__tooltip {
position: absolute;
right: 0;
top: 50%;
/* 0.8rem è la dimensione del padding destro della sidebar */
/* 10px è la distanza con cui voglio distanziare il
tooltip dal bordo della sidebar */
transform: translate(calc(100% + 0.8rem + 10px), -50%);
background-color: white;
border-radius: 8px;
min-width: 75px;
text-align: center;
font-size: 0.7rem;
font-weight: 500;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
padding: 5px;
letter-spacing: -0.2px;
display: none;
color: rgb(5, 5, 75);
}
.sidebar__menu__item a:hover .sidebar__menu__tooltip {
display: block;
}
/*#endregion SIDEBAR MENU*/
/*#region SIDEBAR INPUT*/
input#sidebar-toggle {
display: none;
}
input#sidebar-toggle:checked + header.sidebar {
width: 250px;
}
/*#endregion SIDEBAR INPUT*/
/*#endregion SIDEBAR*/
/*#region MAIN */
/* input#sidebar-toggle:checked ~ main.main-content {
} */
main.main-content {
flex-grow: 1;
}
/*#endregion MAIN */
/* per i devices che non supportano l'hover aggiungo il focus e l'active per intercettare il touch.
In questo modo avrò la comparsa del tooltip al touch (long touch).
Così più che realizzare l'hover ho realizzato il click ma mi sta bene
Questa soluzione potrebbe non funzionare per i browser mobile Edge per i quali devi aggiungere nell'html
aria-haspopup="true" */
/* In questo caso la media query @media all and (hover: none) serve perchè altrimenti se tieni premuto
una voce di menu si attiva il popup e rimane aperto (perchè è active) e rimarrà aperto finchè non cliccki altrove.
Per capirlo prova il codice su un computer con mouse rimuovendo la media query @media all and (hover: none)
Nota che stiamo trascurando altri dispositivi di puntamento (come i pennini)
*/
@media all and (hover: none) {
.sidebar__menu__item a:focus .sidebar__menu__tooltip,
.sidebar__menu__item a:active .sidebar__menu__tooltip {
background-color: red;
display: block;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Dashboard</title>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"
integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA=="
crossorigin="anonymous" />
<link rel="stylesheet" href="../css/dashboard.css" />
<script src="../js/dashboard.js" defer></script>
</head>
<body>
<input type="checkbox" name="sidebar-toggle" id="sidebar-toggle" />
<header class="sidebar">
<div class="sidebar__header">
<div class="sidebar__header__logo">
<!-- <i class="fa-brands fa-codepen"></i> -->
<img src="../../assets/img/logo.png" alt="" />
<span>Wardiere</span>
</div>
<label for="sidebar-toggle">
<i class="fa-solid fa-bars sidebar__header__hamburger"></i>
</label>
</div>
<div class="sidebar__user">
<img src="https://i.ibb.co/tP3Vryt/foto.jpg"
class="sidebar__user__img" alt="foto profilo" >
<p class="sidebar__user__name">Marco Rossi</p>
</div>
<nav class="sidebar__menu">
<ul>
<li class="sidebar__menu__item">
<a href="#">
<i
class="fa-solid fa-window-maximize fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Dashboard</span>
<span class="sidebar__menu__tooltip">Dashboard</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="#">
<i
class="fa-solid fa-message fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Messages</span>
<span class="sidebar__menu__tooltip">Messages</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="#">
<i
class="fa-solid fa-dollar-sign fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Revenue</span>
<span class="sidebar__menu__tooltip">Revenue</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="#">
<i class="fa-solid fa-bell fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Notifications</span>
<span class="sidebar__menu__tooltip">Notifications</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="#">
<i class="fa-solid fa-heart fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Likes</span>
<span class="sidebar__menu__tooltip">Likes</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="#">
<i
class="fa-solid fa-wallet fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Wallet</span>
<span class="sidebar__menu__tooltip">Wallet</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="#">
<i class="fa-solid fa-gear fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Settings</span>
<span class="sidebar__menu__tooltip">Settings</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="../../index.html">
<i class="fa-solid fa-house fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Home</span>
<span class="sidebar__menu__tooltip">Home</span>
</a>
</li>
</ul>
</nav>
</header>
<main class="main-content" style="margin-top: 2000px">
<h1 style="color: red">DASHBOARD</h1>
</main>
<script defer src="../js/dashboard.js"></script>
</body>
</html>
有了这个更规范的解决方案:
/*#region BASE */
@import url("https://fonts.googleapis.com/css2?family=Anta&family=Madimi+One&display=swap");
*,
*::after,
*::before {
margin: 0;
padding: 0;
list-style: none;
box-sizing: border-box;
font-family: inherit;
}
html {
font-size: 16px;
}
body {
background-image: url("https://i.ibb.co/gDgZ3c9/background-Template.png");
background-size: cover;
background-attachment: fixed;
font-family: "Anta", sans-serif;
/* Non uso gridbox perchè gridbox imposta la dimensione delle colonne nell'elemento genitore(quindi qui nel body) con la
proprietà grid-template-columns e non riuscirei con il meccanismo dell'input:checkbox a cambiarne la dimensione
(perchè non posso selezionare il body quando l'input è checked perchè il body è l'elemento genitore).
Con flexbox invece quando clicco sull'hamburger menu basta cambiare la dimensione della sidebar */
display: flex;
/* Questa serve affinchè */
align-items: start;
}
a {
text-decoration: none;
}
/*#endregion BASE */
/*#region SIDEBAR*/
/* Uso position:sticky e top:0 left:0 perchè non voglio */
header.sidebar {
position: fixed;
overflow-y: auto;
overflow-x: visible;
top: 0;
bottom: 0;
left: 0;
background-image: linear-gradient(
30deg,
rgba(5, 5, 75, 0.85),
rgba(5, 5, 75, 0.85) 20%,
rgb(5, 5, 75)
);
height: 100vh;
height: 100svh;
width: 65px;
padding: 0.4rem 0.8rem;
transition: all 0.5s ease;
}
/*#region SIDEBAR HEADER*/
.sidebar__header {
display: flex;
align-items: center;
justify-content: center;
}
.sidebar__header__logo {
display: flex;
align-items: center;
display: none;
}
.sidebar__header__logo img {
width: 50px;
}
.sidebar__header__logo span {
color: white;
}
.sidebar__header__hamburger {
cursor: col-resize;
margin-top: 0.4rem;
}
/*#endregion SIDEBAR HEADER*/
/*#region SIDEBAR USER*/
.sidebar__user {
display: flex;
justify-content: center;
}
.sidebar__user__img {
width: 50px;
height: 50px;
object-fit: cover;
border: 3px solid rgb(182, 5, 152);
border-top-color: rgb(23, 23, 201);
border-bottom-color: rgb(23, 23, 201);
border-radius: 50%;
margin-top: 20px;
}
.sidebar__user__name {
display: none;
}
/*#endregion SIDEBAR USER*/
/*#region SIDEBAR MENU*/
.sidebar__menu__item {
min-height: 40px;
margin: 10px 0;
display: flex;
align-items: center;
justify-content: center;
}
.sidebar__menu__item:hover {
border-radius: 10px;
background-color: white;
}
.sidebar__menu__item:hover .sidebar__menu__item__icon::before {
/* background-image: red; */
background-image: linear-gradient(rgb(5, 5, 75), rgb(5, 5, 75));
font-size: larger;
}
.sidebar__menu__item a {
position: relative; /* Serve per posizionare il tooltip */
display: block;
/* Le seguenti due regole servono per far si che il
tag a si sovrapponga perfettamente all'li
genitore in modo che la superficie cliccabile
del link cresca e sia uguale a quella dell'li */
width: 100%;
min-height: inherit;
display: flex;
justify-content: center;
align-items: center;
}
.sidebar__menu__item__text {
height: 3.2em;
min-width: 100px;
display: none;
font-size: 1rem;
background-color: rgb(182, 5, 152);
background-image: linear-gradient(
to right,
rgb(23, 23, 201),
rgb(182, 5, 152)
);
background-clip: text;
-webkit-text-fill-color: transparent;
}
/* Questa regola funge da fallback in caso -webkit-text-fill-color o background-clip: text;
non siano supportati */
.sidebar__menu__item__icon {
color: rgb(23, 23, 201);
}
:is(.sidebar__menu__item__icon, .sidebar__header__hamburger)::before {
background-image: linear-gradient(
to right,
rgb(23, 23, 201),
rgb(182, 5, 152)
);
background-clip: text;
-webkit-text-fill-color: transparent;
}
.sidebar__menu__tooltip {
position: absolute;
right: 0;
top: 50%;
/* 0.8rem è la dimensione del padding destro della sidebar */
/* 10px è la distanza con cui voglio distanziare il
tooltip dal bordo della sidebar */
transform: translate(calc(100% + 0.8rem + 10px), -50%);
background-color: white;
border-radius: 8px;
min-width: 75px;
text-align: center;
font-size: 0.7rem;
font-weight: 500;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
padding: 5px;
letter-spacing: -0.2px;
display: none;
color: rgb(5, 5, 75);
}
.sidebar__menu__item a:hover .sidebar__menu__tooltip {
display: block;
}
/*#endregion SIDEBAR MENU*/
/*#region SIDEBAR INPUT*/
input#sidebar-toggle {
display: none;
}
input#sidebar-toggle:checked + header.sidebar {
width: 250px;
}
/*#endregion SIDEBAR INPUT*/
/*#endregion SIDEBAR*/
/*#region MAIN */
/* input#sidebar-toggle:checked ~ main.main-content {
} */
main.main-content {
flex-grow: 1;
}
/*#endregion MAIN */
/* per i devices che non supportano l'hover aggiungo il focus e l'active per intercettare il touch.
In questo modo avrò la comparsa del tooltip al touch (long touch).
Così più che realizzare l'hover ho realizzato il click ma mi sta bene
Questa soluzione potrebbe non funzionare per i browser mobile Edge per i quali devi aggiungere nell'html
aria-haspopup="true" */
/* In questo caso la media query @media all and (hover: none) serve perchè altrimenti se tieni premuto
una voce di menu si attiva il popup e rimane aperto (perchè è active) e rimarrà aperto finchè non cliccki altrove.
Per capirlo prova il codice su un computer con mouse rimuovendo la media query @media all and (hover: none)
Nota che stiamo trascurando altri dispositivi di puntamento (come i pennini)
*/
@media all and (hover: none) {
.sidebar__menu__item a:focus .sidebar__menu__tooltip,
.sidebar__menu__item a:active .sidebar__menu__tooltip {
background-color: red;
display: block;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Dashboard</title>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"
integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA=="
crossorigin="anonymous" />
<link rel="stylesheet" href="../css/dashboard.css" />
<script src="../js/dashboard.js" defer></script>
</head>
<body>
<input type="checkbox" name="sidebar-toggle" id="sidebar-toggle" />
<header class="sidebar">
<div class="sidebar__header">
<div class="sidebar__header__logo">
<!-- <i class="fa-brands fa-codepen"></i> -->
<img src="../../assets/img/logo.png" alt="" />
<span>Wardiere</span>
</div>
<label for="sidebar-toggle">
<i class="fa-solid fa-bars sidebar__header__hamburger"></i>
</label>
</div>
<div class="sidebar__user">
<img
src="https://i.ibb.co/tP3Vryt/foto.jpg"
class="sidebar__user__img"
alt="foto profilo" />
<p class="sidebar__user__name">Marco Rossi</p>
</div>
<nav class="sidebar__menu">
<ul>
<li class="sidebar__menu__item">
<a href="#">
<i
class="fa-solid fa-window-maximize fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Dashboard</span>
<span class="sidebar__menu__tooltip">Dashboard</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="#">
<i
class="fa-solid fa-message fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Messages</span>
<span class="sidebar__menu__tooltip">Messages</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="#">
<i
class="fa-solid fa-dollar-sign fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Revenue</span>
<span class="sidebar__menu__tooltip">Revenue</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="#">
<i class="fa-solid fa-bell fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Notifications</span>
<span class="sidebar__menu__tooltip">Notifications</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="#">
<i class="fa-solid fa-heart fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Likes</span>
<span class="sidebar__menu__tooltip">Likes</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="#">
<i
class="fa-solid fa-wallet fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Wallet</span>
<span class="sidebar__menu__tooltip">Wallet</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="#">
<i class="fa-solid fa-gear fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Settings</span>
<span class="sidebar__menu__tooltip">Settings</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="../../index.html">
<i class="fa-solid fa-house fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Home</span>
<span class="sidebar__menu__tooltip">Home</span>
</a>
</li>
</ul>
</nav>
</header>
<main class="main-content" style="margin-top: 2000px">
<h1 style="color: red">DASHBOARD</h1>
</main>
<script defer src="../js/dashboard.js"></script>
</body>
</html>
我的垂直菜单上有(带有
position:fixed
和overflow-y:auto
和overflow-x:visible
)垂直滚动条,但是我也有一个水平滚动条。我可以用 overflow-x:hidden
隐藏它,但这样,项目菜单上的 :hover
上出现的工具提示(在垂直菜单的右侧)就不再可见。相反,水平滚动条可见(没有 overflow-x:hidden
),此工具提示位于侧边栏菜单内,并且仅在水平滚动时可见。
这让我抓狂。我该如何解决?
const ulInsideNav = document.querySelector(".sidebar__menu > ul");
//uso anche il touch e non solo l'hover per supportare anche il mobile.
//Uso event delegation
ulInsideNav.addEventListener("mouseover", displayTooltip);
ulInsideNav.addEventListener("touch", displayTooltip);
function displayTooltip(e) {
if (e.type === "touch") {
//dopo l'evento touch potrebbe essere innescato anche l'hover e quindi per
//evitare due volte l'esecuzione uso preventDefault
e.preventDefault();
}
let elClicked = e.target;
let elClickedType = e.target.tagName.toLowerCase();
//Se ho cliccato sul tag i(l'icona font-awesome) mi faccio tornare il tag a genitore
if (elClickedType === "i") {
elClicked = elClicked.parentElement;
elClickedType = "a";
}
console.log("DENTRO");
console.log("🚀 ~ displayTooltip ~ elClickedType:", elClickedType);
//Mi assicuro che il click sia avvenuto su un tag a (se è avvenuto sul tag i ho già provveduto a farmi tornare il tag a genitore)
if (elClickedType === "a") {
const iconTooltip = elClicked.querySelector(".sidebar__menu__tooltip");
const sidebarWrapper = document.querySelector(".sidebar--wrapper");
iconTooltip.style.cssText = `
top:${
elClicked.offsetTop +
Math.round(elClicked.offsetHeight) / 2 -
Math.round(iconTooltip.offsetHeight) / 2 +
"px"
};
left: ${Math.round(sidebarWrapper.offsetWidth + 10) + "px"};
`;
//Quando perdi l'hover non c'è bisogno di togliere lo stile inline perchè perdendo l'hover
//il tooltip ha il display:none
}
}
/*#region BASE */
@import url("https://fonts.googleapis.com/css2?family=Anta&family=Madimi+One&display=swap");
*,
*::after,
*::before {
margin: 0;
padding: 0;
list-style: none;
box-sizing: border-box;
font-family: inherit;
}
:root {
font-size: 16px;
}
body {
background-image: url("https://i.ibb.co/gDgZ3c9/background-Template.png");
background-size: cover;
background-attachment: fixed;
font-family: "Anta", sans-serif;
/* Non uso gridbox perchè gridbox imposta la dimensione delle colonne nell'elemento genitore(quindi qui nel body) con la
proprietà grid-template-columns e non riuscirei con il meccanismo dell'input:checkbox a cambiarne la dimensione
(perchè non posso selezionare il body quando l'input è checked perchè il body è l'elemento genitore).
Con flexbox invece quando clicco sull'hamburger menu basta cambiare la dimensione della sidebar */
display: flex;
/* Questa serve affinchè */
align-items: start;
}
a {
text-decoration: none;
}
/*#region SCROLLBAR*/
/* Il predisso webkit è per browser come Safari Chrome
ed Edge. Tuttavia queste regole non funzioneranno
per Firefox per il quale possiamo usare
scrollbar-color: hsl(240, 78%, 50%) hsl(240, 88%, 86%);
scrollbar-width: auto;
Tuttavia queste due sono supportate anche da
Chrome e altri browser e andrebbero a sovrascrivere
le regole date con ::-webkit
per cui utilizzo @supports
@supports not (selector(::-webkit-scrollbar))
Cioè se non supporto -webkit-scrollbar (e se
non lo supporto non saranno supportate neanche le
altre proprità allora attivo la fallback).
Nota che uso il not e selector() perchè
::-webkit-scrollbar non è una proprietà
ma un selettore. */
::-webkit-scrollbar {
width: 12px;
height: 12px;
}
/* Larghezza della scrollbar nel body */
.sidebar::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: hsl(240, 88%, 86%);
border-radius: 100vw;
/* margin-block di default definisce il margin-top e il margin-bottom */
margin-block: 1px;
}
::-webkit-scrollbar-thumb {
background: linear-gradient(hsl(240, 78%, 50%), hsl(289, 88%, 33%));
border: 2px solid hsl(289, 88%, 83%);
border-radius: 100vw;
}
::-webkit-scrollbar-thumb:hover {
background: linear-gradient(hsl(240, 88%, 20%), hsl(289, 98%, 23%));
}
@supports not (selector(::-webkit-scrollbar)) {
* {
scrollbar-color: hsl(240, 78%, 50%) hsl(240, 88%, 86%);
scrollbar-width: auto; /* auto none thin */
}
}
/* @supports (scrollbar-color: hsl(240, 78%, 50%) hsl(240, 88%, 86%)) {
* {
scrollbar-color: hsl(240, 78%, 50%) hsl(240, 88%, 86%);
scrollbar-width: auto;
}
} */
/*#endregion SCROLLBAR*/
/*#endregion BASE */
/*#region SIDEBAR*/
/* Uso position:sticky e top:0 left:0 perchè non voglio */
.sidebar--wrapper {
position: fixed;
top: 0;
bottom: 0;
left: 0;
/* min-height: 100vh;
min-height: 100svh; */
width: 68px;
transition: width 0.35s;
}
header.sidebar {
overflow-y: auto;
overflow-x: hidden;
height: 100%;
background-image: linear-gradient(
30deg,
rgba(5, 5, 75, 0.85),
rgba(5, 5, 75, 0.85) 20%,
rgb(5, 5, 75)
);
padding: 0.4rem 0.8rem;
transition: all 0.5s ease;
}
/*#region SIDEBAR HEADER*/
.sidebar__header {
display: flex;
align-items: center;
justify-content: center;
}
.sidebar__header__logo {
display: flex;
align-items: center;
display: none;
}
.sidebar__header__logo img {
width: 50px;
}
.sidebar__header__logo span {
color: white;
}
[for="sidebar-toggle"] {
display: none;
}
.sidebar__header__hamburger {
cursor: col-resize;
margin-top: 0.4rem;
}
/*#endregion SIDEBAR HEADER*/
/*#region SIDEBAR USER*/
.sidebar__user {
display: flex;
justify-content: center;
}
.sidebar__user__img {
width: 50px;
height: 50px;
object-fit: cover;
border: 3px solid rgb(182, 5, 152);
border-top-color: rgb(23, 23, 201);
border-bottom-color: rgb(23, 23, 201);
border-radius: 50%;
margin-top: 20px;
}
.sidebar__user__name {
display: none;
}
/*#endregion SIDEBAR USER*/
/*#region SIDEBAR MENU*/
.sidebar__menu__item {
min-height: 40px;
margin: 10px 0;
display: flex;
align-items: center;
justify-content: center;
}
.sidebar__menu__item:hover {
border-radius: 10px;
background-color: white;
}
/* L'icona rispetto al tag a è più in basso nel markup quindi sta davanti e quindi quando ci vai con
il mouse sopra tanti eventi mouseover sono innescati passando dal tag a all'icona (tag i), per
motivi di efficienza cioè per evitare di chiamare più volte il gestore di evento del mouse
ho messo il pointer-events:none sul tag i(icona) */
.sidebar__menu__item__icon {
pointer-events: none;
}
.sidebar__menu__item:hover .sidebar__menu__item__icon::before {
/* background-image: red; */
background-image: linear-gradient(rgb(5, 5, 75), rgb(5, 5, 75));
font-size: larger;
}
.sidebar__menu__item a {
/* position: relative; */ /* Serve per posizionare il tooltip */
display: block;
/* Le seguenti due regole servono per far si che il
tag a si sovrapponga perfettamente all'li
genitore in modo che la superficie cliccabile
del link cresca e sia uguale a quella dell'li */
width: 100%;
min-height: inherit;
display: flex;
justify-content: center;
align-items: center;
}
.sidebar__menu__item__text {
height: 3.2em;
min-width: 100px;
display: none;
font-size: 1rem;
background-color: rgb(182, 5, 152);
background-image: linear-gradient(
to right,
rgb(23, 23, 201),
rgb(182, 5, 152)
);
background-clip: text;
-webkit-text-fill-color: transparent;
}
/* Nota che per background-clip c'è un bug noto quando lo
usi */
:is(.sidebar__menu__item__icon, .sidebar__header__hamburger)::before {
background-image: linear-gradient(
to right,
rgb(23, 23, 201),
rgb(182, 5, 152)
);
background-clip: text;
-webkit-text-fill-color: transparent;
}
/* Questa regola funge da fallback in caso -webkit-text-fill-color o background-clip: text;
non siano supportati. Ad esempio in Opera senza
queste regole non riuscirei a vedere le icone */
@supports not (
(background-clip: text) and (-webkit-text-fill-color: transparent)
) {
:is(.sidebar__menu__item__icon, .sidebar__header__hamburger)::before {
-webkit-text-fill-color: unset;
background-image: none;
background-clip: unset;
color: rgb(23, 23, 201);
}
.sidebar__menu__item__text {
-webkit-text-fill-color: unset;
background-image: none;
background-clip: unset;
color: rgb(23, 23, 201);
}
.sidebar__menu__item:hover .sidebar__menu__item__icon::before {
background-image: none;
}
}
.sidebar__menu__tooltip {
position: absolute;
/* right: 0;
top: 50%; */
/* 0.8rem è la dimensione del padding destro della sidebar */
/* 10px è la distanza con cui voglio distanziare il
tooltip dal bordo della sidebar */
/* transform: translate(calc(100% + 0.8rem + 10px), -50%); */
background-color: white;
border-radius: 8px;
min-width: 75px;
text-align: center;
font-size: 0.7rem;
font-weight: 500;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
padding: 5px;
letter-spacing: -0.2px;
display: none;
color: rgb(5, 5, 75);
}
.sidebar__menu__item a:hover .sidebar__menu__tooltip {
display: block;
}
/*#endregion SIDEBAR MENU*/
/*#region SIDEBAR INPUT*/
input#sidebar-toggle {
display: none;
}
input#sidebar-toggle:checked ~ main.main-content {
margin-left: 250px;
}
/*#endregion SIDEBAR INPUT*/
/*#endregion SIDEBAR*/
/*#region MAIN */
/* input#sidebar-toggle:checked ~ main.main-content {
} */
main.main-content {
flex-grow: 1;
margin-left: 68px;
}
/*#endregion MAIN */
/* per i devices che non supportano l'hover aggiungo il focus e l'active per intercettare il touch.
In questo modo avrò la comparsa del tooltip al touch (long touch).
Così più che realizzare l'hover ho realizzato il click ma mi sta bene
Questa soluzione potrebbe non funzionare per i browser mobile Edge per i quali devi aggiungere nell'html
aria-haspopup="true" */
/* In questo caso la media query @media all and (hover: none) serve perchè altrimenti se tieni premuto
una voce di menu si attiva il popup e rimane aperto (perchè è active) e rimarrà aperto finchè non cliccki altrove.
Per capirlo prova il codice su un computer con mouse rimuovendo la media query @media all and (hover: none)
Nota che stiamo trascurando altri dispositivi di puntamento (come i pennini)
*/
@media all and (hover: none) {
.sidebar__menu__item a:focus .sidebar__menu__tooltip,
.sidebar__menu__item a:active .sidebar__menu__tooltip {
/* background-color: red; */
display: block;
}
}
@media all and (min-width: 600px) {
[for="sidebar-toggle"] {
display: block;
}
/* Questa regola dice che se il menu è espanso il tooltip non lo si deve vedere
e siccome può essere espanso solo sopra il breakpoint corrente è idoneo mettere
questa regola in questa media query
*/
input#sidebar-toggle:checked
+ .sidebar--wrapper
.sidebar__menu__item
a:hover
.sidebar__menu__tooltip {
display: none;
}
/* Devo consentire di espandere il menu a 250px solo oltre il breakpoint prescelto corrente
quindi anche questa regola va inserita qui */
input#sidebar-toggle:checked + .sidebar--wrapper {
width: 250px;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Dashboard</title>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"
integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA=="
crossorigin="anonymous" />
<link rel="stylesheet" href="./b.css" />
</head>
<body>
<input type="checkbox" name="sidebar-toggle" id="sidebar-toggle" />
<!-- Ad [1] in fondo alla pagina spiego il perchè serve questo wrapper -->
<div class="sidebar--wrapper">
<header class="sidebar">
<div class="sidebar__header">
<div class="sidebar__header__logo">
<!-- <i class="fa-brands fa-codepen"></i> -->
<img src="../../assets/img/logo.png" alt="" />
<span>Wardiere</span>
</div>
<label for="sidebar-toggle">
<i class="fa-solid fa-bars sidebar__header__hamburger"></i>
</label>
</div>
<div class="sidebar__user">
<img
src="https://i.ibb.co/tP3Vryt/foto.jpg"
class="sidebar__user__img"
alt="foto profilo" />
<p class="sidebar__user__name">Marco Rossi</p>
</div>
<nav class="sidebar__menu">
<ul>
<li class="sidebar__menu__item">
<a href="#">
<i
class="fa-solid fa-window-maximize fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Dashboard</span>
<span class="sidebar__menu__tooltip">Dashboard</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="#">
<i
class="fa-solid fa-message fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Messages</span>
<span class="sidebar__menu__tooltip">Messages</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="#">
<i
class="fa-solid fa-dollar-sign fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Revenue</span>
<span class="sidebar__menu__tooltip">Revenue</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="#">
<i
class="fa-solid fa-bell fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Notifications</span>
<span class="sidebar__menu__tooltip">Notifications</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="#">
<i
class="fa-solid fa-heart fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Likes</span>
<span class="sidebar__menu__tooltip">Likes</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="#">
<i
class="fa-solid fa-wallet fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Wallet</span>
<span class="sidebar__menu__tooltip">Wallet</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="#">
<i
class="fa-solid fa-gear fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Settings</span>
<span class="sidebar__menu__tooltip">Settings</span>
</a>
</li>
<li class="sidebar__menu__item">
<a href="../../index.html">
<i
class="fa-solid fa-house fa-2xs sidebar__menu__item__icon"></i>
<span class="sidebar__menu__item__text">Home</span>
<span class="sidebar__menu__tooltip">Home</span>
</a>
</li>
</ul>
</nav>
</header>
</div>
<main class="main-content" style="margin-top: 2000px">
<h1 style="color: red">DASHBOARD</h1>
</main>
<script src="./c.js"></script>
</body>
</html>
<!-- [1] Se l'altezza della viewport del browser non riesce a contenere tutti gli
elementi nella sidebar viene introdotta automaticamente una barra di scorrimento
alla pagina. Tuttavia se poi nel tag main ho più contenuto rispetto alla sidebar
avrò una sidebar più corta rispetto al tag main affianco che è brutto da vedere.
Allora fisso l'altezza della sidebar (con position:fixed ed
height:100vh) in modo che scrollando la pagina la sidebar rimane fissa a
sinistra. Però in questo modo se l'altezza della viewport è piccola rischio di
non vedere più la parte finale della sidebar e voglio che sulla sidebar venga
introdotta la barra di scorrimento (non alla pagina, ma proprio alla sidebar). E
questo è facile da fare, basta dare overflow-y:auto. Però in questo modo non
riesco più a vedere i tooltip (che sono un overflow orizzontale) quando vado con
il mouse sopra alle icone. Mettendo overflow-x:visible non funziona. Siamo
incappati in uno di quei comportamenti stranissimi del css che lo fanno odiare.
Se setti l'overflow in una direzione ad auto nell'altra direzione anche se lo
setti a visible sarà comunque auto e quindi compare una barra di scorrimento
orizzontale e il tooltip non lo vedi più se non scorrendo orizzontalmente Il
tutto è documentato qui
https://css--tricks-com.translate.goog/popping-hidden-overflow/?_x_tr_sl=en&_x_tr_tl=it&_x_tr_hl=it&_x_tr_pto=sc
AL link che ti ho messo c'è anche la soluzione che richiede anche l'intervento
di javascript e una modifica al css e all'html. Alla sidebar possiamo dare
overflow-y:auto e overflow-x:hidden. E ora il tooltip come lo vedo dato che
overflow-x:hidden? Grazie a un meccanismo particolare di css:
Se voglio vedere un elemento contenuto dentro un elemento con overflow:hidden all'elemento che voglio vedere posso
dare position:absolute o position:relative e poi il suo antenato più vicino con position diverso da static deve
essere anche un antenato dell'elemento con position:hidden.
Nel nostro caso il tooltip ha un genitore (il tag a) con il position relative (e il tag a non è un antenato della sidebar)
quindi dobbiamo togliere il position:relative al tag a .
Mettiamo la sidebar dentro un elemento wrapper (quello con classe .sidebar-wrapper) al quale daremo position:fixed
e vedremo i nostri tooltip fuori dalla sidebar all'hover. Tuttavia i tooltip con top,left ecc. saranno posizionati
rispetto alla sidebar e non rispetto al link. Ed a questo punto subentra javascript.
Nota che il gestore di evento javascript al mouseover mi serve solo se c'è un overflow verticale della sidebar.
Potrei quindi rilevare tramite js se non c'è overflow verticale e in tal caso togliere i gestori di evento del mouse
(e gestire tramite css la centratura) e viceversa. Ma sarebbe un complicarsi le cose senza nessun grande guadagno.
-->
在我提供的链接中,还有一个解决方案,需要JavaScript的介入以及对CSS和HTML的修改。我们可以给侧边栏赋予overflow-y:auto和overflow-x:hidden。现在,我如何查看 Overflow-x:hidden 后的工具提示?得益于特殊的 CSS 机制:
如果我想查看包含在具有overflow:hidden的元素中的元素,我可以给我想要查看的元素提供position:absolute或position:relative,然后其最近的祖先位置除了static之外也必须是一个具有位置:隐藏的元素的祖先。在我们的例子中,工具提示有一个具有相对位置的父级(“a”标签)(并且“a”标签不是侧边栏的祖先),因此我们需要从“a”标签中删除position:relative。我们将侧边栏放在一个包装元素(具有 .sidebar-wrapper 类的元素)内,我们将为其指定位置:固定,并且我们将在悬停时在侧边栏外部看到我们的工具提示。但是,顶部、左侧等工具提示将相对于侧边栏而不是链接定位。这时,JavaScript 就派上用场了。
请注意,仅当侧边栏垂直溢出时才需要鼠标悬停的 JavaScript 事件处理程序。因此,我可以通过 JS 检测是否没有垂直溢出,在这种情况下删除鼠标事件处理程序(并通过 CSS 管理居中),反之亦然。但这会使事情变得复杂,而且没有任何好处。