li元素使用translate移动后被遮挡

HTML代码:

        <div id="nav-left">
            <div id="nav-left-top">上</div>
            <ul id="left-ul">
                <li><a>第一章</a></li>
                <li><a>第二章</a></li>
                <li><a>第三章</a></li>
                <li><a>第四章</a></li>
                <li><a>第五章</a></li>
                <li><a>第一章</a></li>
            </ul>
            <div id="nav-left-bottom">下</div>
        </div>

CSS代码:

div#nav-left {
    left: 9%;
    text-align: center;
    position: fixed;
    width: 10%;
    box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
    cursor: pointer;
    background-color: #c97546;
    max-height: 70%;
}

div#nav-left-top,
div#nav-left-bottom {
    height: 30px;
    vertical-align: middle;
    line-height: 30px;
    background-color: white;
    transition-duration: 300ms;
}

div#nav-left-top:hover {
    transform: translateY(-10px);
}

div#nav-left-bottom:hover {
    transform: translateY(10px);
}

ul#left-ul {
    margin: 0;
    padding: 0;
    max-height: calc(70vh - 60px);
    overflow-y: scroll;
    overscroll-behavior: none;
}

ul#left-ul::-webkit-scrollbar {
    display: none;
}

ul#left-ul > li {
    background-color: white;
    transition-duration: 300ms;
    box-shadow: 8px 0 8px -8px rgba(0, 0, 0, 0.2),
        20px 0 20px -20px rgba(0, 0, 0, 0.19);
    border: solid;
}

ul#left-ul > li:hover {
    transform: translateX(8px);
    position: relative;
}

ul#left-ul a {
    color: black;
    text-decoration: none;
}

当鼠标移到li元素上时,li元素会向右移动,但是明显右边被遮挡不见,(右边的border已经不见)。想实现的效果是translateX右移时,li元素的右边依然不会被遮挡。
li:hover中有一个{position: relative}是从网上找的办法,但是似乎并没有用。

阅读 4.9k
1 个回答

先看下这个 demo,应该可以解决你的问题。demo

原因

这个现象确实很奇怪,具体原因我也搜了一下,搜到这个问题里面提到 W3C 的规范:

The computed values of ‘overflow-x’ and ‘overflow-y’ are the same as their specified values, except that some combinations with ‘visible’ are not possible: if one is specified as ‘visible’ and the other is ‘scroll’ or ‘auto’, then ‘visible’ is set to ‘auto’. The computed value of ‘overflow’ is equal to the computed value of ‘overflow-x’ if ‘overflow-y’ is the same; otherwise it is the pair of computed values of ‘overflow-x’ and ‘overflow-y’.

重点注意上面红色的字,如果(‘overflow-x’、‘overflow-y’)其中一个指定为 visible,另一个指定为 scrollauto,那么 visible 值就会被置为 auto

这个就是导致你 demo 里面 ul 设置 overflow-x: visible 不生效的原因,因为此时 overflow-x 的值相当于是 auto,你可以试着在你的 demo 里面把滚动条显示出来,当 hover 到 li 时就能看到横向的滚动条出现了。

不过上面这段规范我没有搜到,估计是现在规定已经改了措辞,我搜到了规范里面的另一个类似定义,看起来感觉是一个意思,但是我自己翻译不出来,我贴在下面,英语好的可以翻译一下看我理解的是不是有问题。文档地址

(overflow-x | overflow-y Com­puted value): as specified, except with visible/clip computing to auto/hidden (respectively) if one of overflow-x or overflow-y is neither visible nor clip

解决办法

搜到的很多解决办法都是这个思路:既然这种 overflow-x y 的值组合不能同时在一个元素上设置这样的,就多套一层元素,两层来分别设置。

但是我试了一下这个方案没法解决你的问题,因为:

  • overflow-x: visible 放在内层,overflow-y: scroll 放在外层,这样就算内层把超出 x 方向的内容显示出来了,但是外层 x 方向还是会隐藏掉,除非外层设置 overflow-x: visible,这样就又回到起点了
  • overflow-x: visible 放在外层,overflow-y: scroll 放在内层,这样就需要你的 ul 元素宽度大于 li 右移之后占据的 x 方向的宽度,也不太适合你的 demo

我上面的 demo 主要是加了这部分代码,ul hover 时宽度增大 8px,用来补偿 li 右移导致展示不出来的 8px,同时加 8pxpadding-rightbox-sizing: border-box 用来保持 ul 元素的内容尺寸不变,避免其他未 hoverli 元素宽度变化。

ul#left-ul:hover {
  width: calc(100% + 8px);
  padding-right: 8px;
  box-sizing: border-box;
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题