当视口高度不足以显示垂直菜单时,如何使垂直菜单可滚动,同时允许菜单中水平溢出

问题描述 投票:0回答:1

我创建了一个垂直菜单,我想将其扩展到视口的整个高度,但如果这不足以容纳它,我想要一些滚动机制(在页面或垂直菜单上,这两种情况都可以) )这使我能够这样做。我尝试了多种方法,但都达不到想要的效果。

有了这个解决方案,

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
),此工具提示位于侧边栏菜单内,并且仅在水平滚动时可见。 这让我抓狂。我该如何解决?

html css menu overflow vertical-scroll
1个回答
0
投票

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.

-->
上面的解决方案: 这是一个我已经解决过但我忘记了的问题: 我对上述解决方案的解释是: 如果浏览器视口的高度无法容纳侧边栏中的所有元素,则会自动在页面中引入滚动条。但是,如果主标签包含的内容比侧边栏多,那么侧边栏就会比旁边的主标签短,这看起来很糟糕。因此,我修复了侧边栏的高度(位置:固定和高度:100vh),以便滚动页面时,侧边栏保持固定在左侧。但是,这样,如果视口高度很小,我就有看不到侧边栏最后部分的风险,并且我希望在侧边栏本身上引入滚动条(不是在页面上,而是直接在侧边栏上)。这很容易做到,只需提供overflow-y:auto即可。但是,这样,当我将鼠标悬停在图标上时,我将无法再看到工具提示(水平溢出)。设置overflow-x:visible不起作用。我们遇到过一种令人讨厌的非常奇怪的 CSS 行为。如果你把一个方向的overflow设置为auto,那么在另一个方向,即使你设置为visible,它仍然是auto,所以会出现水平滚动条,除非水平滚动,否则你将不再看到工具提示。这一切都记录在这里:CSS-Tricks。

在我提供的链接中,还有一个解决方案,需要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 管理居中),反之亦然。但这会使事情变得复杂,而且没有任何好处。

© www.soinside.com 2019 - 2024. All rights reserved.