【问题标题】:Why CSS hover with pseudo element failed?为什么 CSS 用伪元素悬停失败?
【发布时间】:2023-01-19 16:38:44
【问题描述】:

我今天写了一个列表项悬停效果,但是结果行为很奇怪:

从Item6悬停到Item2时,一切正常, 但是当从 Item2 悬停到 Item6 并悬停空白区域时(<li> 内,<p> 外), 似乎有什么东西挡住了悬停。

感觉伪元素有点问题。

任何人都可以帮我吗?谢谢!

这是我的代码:

var li = document.querySelectorAll('li')
li.forEach((e) => {
  e.addEventListener('click', (event) => {
    li.forEach((l) => {
      l.classList.remove('active')
    })
    e.classList.add('active')
  })
})
:root {
  --el-color-primary: #409eff;
  --el-color-info: #909399;
  --el-color-primary-rgb: 64, 158, 255;
}

.categories {
  width: 200px;
}

li {
  list-style-type: none;
  box-sizing: border-box;
  height: 2.2rem;
  cursor: pointer;
  color: var(--el-color-info);
  z-index: 0;
  border-radius: .5rem;
}

li {
  margin: .3rem;
}

li p {
  font-size: 1rem;
  line-height: 1rem;
  padding: .6rem 0 .6rem .8rem;
  margin: 0;
  color: var(--el-color-info);
}

li.active p {
  font-weight: 600;
  color: var(--el-color-primary);
}

li.active {
  background-color: rgba(var(--el-color-primary-rgb), .2);
}

li:not(.active)::after {
  content: "";
  display: inline-block;
  width: 0;
  height: 2.2rem;
  position: relative;
  top: -2.2rem;
  left: 0;
  border-radius: .5rem;
  background-color: rgba(var(--el-color-primary-rgb), .1);
  z-index: -99;
  transition: width .4s ease-out;
}

li:not(.active):hover p {
  color: var(--el-color-primary);
}

li:not(.active):hover::after {
  width: 100%;
}
<ul class="categories">
  <li class="active">
    <p>Item 1</p>
  </li>
  <li>
    <p>Item 2</p>
  </li>
  <li>
    <p>Item 3</p>
  </li>
  <li>
    <p>Item 4</p>
  </li>
  <li>
    <p>Item 5</p>
  </li>
  <li>
    <p>Item 6</p>
  </li>
</ul>

【问题讨论】:

  • 我添加了一个 sn-p,您的代码似乎工作正常……问题出在哪里?
  • 正如我提到的...从 Item6 悬停到 Item2 没问题,但是从 Item2 悬停到 Item 6,Item3 和 Item5 似乎不会悬停
  • sn-p 对我来说工作正常 (Edge/WIndows10)。您使用的是什么浏览器和操作系统?你在这里试过 sn-p 了吗,这仍然会给你带来问题吗?
  • 悬停空白区域(<li>内,<p>外)时出现问题
  • position: relativeli 你放 z-index: 0 的地方。

标签: css hover pseudo-element


【解决方案1】:

该问题通过修改放置 display: block at li:not(.active)::after 而不是 inline-block 来解决

var li = document.querySelectorAll('li')
li.forEach((e) => {
  e.addEventListener('click', (event) => {
    li.forEach((l) => {
      l.classList.remove('active')
    })
    e.classList.add('active')
  })
})
:root {
  --el-color-primary: #409eff;
  --el-color-info: #909399;
  --el-color-primary-rgb: 64, 158, 255;
}

.categories {
  width: 200px;
}

li {
  list-style-type: none;
  box-sizing: border-box;
  height: 2.2rem;
  cursor: pointer;
  color: var(--el-color-info);
  z-index: 0;
  border-radius: .5rem;
}

li {
  margin: .3rem;
}

li p {
  font-size: 1rem;
  line-height: 1rem;
  padding: .6rem 0 .6rem .8rem;
  margin: 0;
  color: var(--el-color-info);
}

li.active p {
  font-weight: 600;
  color: var(--el-color-primary);
}

li.active {
  background-color: rgba(var(--el-color-primary-rgb), .2);
}

li:not(.active)::after {
  content: "";
  display: block;
  width: 0;
  height: 2.2rem;
  position: relative;
  top: -2.2rem;
  left: 0;
  border-radius: .5rem;
  background-color: rgba(var(--el-color-primary-rgb), .1);
  z-index: -99;
  transition: width .4s ease-out;
}

li:not(.active):hover p {
  color: var(--el-color-primary);
}

li:not(.active):hover::after {
  width: 100%;
}
<ul class="categories">
  <li class="active">
    <p>Item 1</p>
  </li>
  <li>
    <p>Item 2</p>
  </li>
  <li>
    <p>Item 3</p>
  </li>
  <li>
    <p>Item 4</p>
  </li>
  <li>
    <p>Item 5</p>
  </li>
  <li>
    <p>Item 6</p>
  </li>
</ul>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-16
    • 1970-01-01
    • 2011-10-29
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    • 2012-09-21
    • 2019-09-12
    相关资源
    最近更新 更多