问题 在悬停时显示下拉菜单,仅使用CSS单击关闭


有人可以帮我解释为什么当我点击它们时,下拉菜单中的链接无效吗?也许是因为指针事件?我正在尝试在单击链接或单击关闭按钮后关闭下拉菜单。我添加了一些很酷的东西,比如在点击链接时隐藏父容器。

有很多选择:

  1. 运用 :focus 但是当使用焦点时,下拉列表将不会 在下一次悬停在下拉菜单上触发。

  2. 运用 :active 在容器和 pointer-events 只指向 活动链接,但指针事件是错误的

  3. 运用 :target 但有同样的问题:焦点,不会触发 第二个胡佛。

body {
    padding: 20px;
}
.container {
    border: 1px solid lime;
    padding: 10px;
    width: 200px;
}
.test1 {
    display: none;
    border: 1px dashed orange;
    background: green;
    padding: 10px;
    pointer-events: none;
}
.container:hover .test1 {
    display: inline-block;
}
.container:hover .test1:active {
    display: none;
}
a {
    pointer-events: auto;
    color: lime;
    font-weight: bold;
}
<ul class="container">
	 Drop down menu
	<li class="test1">
	<a class="dropdown" href="#">X Close</a>
	<ul class="content">
		 CLOSE THIS CONTENT
		<li class="link"><a href="http://www.google.com">Go to link 1</a></li>
		<li class="link"><a href="https://www.google.co.uk">Go to link 2</a></li>
		<li class="link"><a href="https://www.google.co.uk">Go to link 3</a></li>
	</ul>

5065
2017-12-09 14:09


起源

@hungerstar nope,不在Chrome上工作。正确的行为应该是在点击链接时将您重定向到谷歌页面。 - RulerNature
li和ul结束标签丢失。 - Immran Mohammed
你说的是“在单击链接后尝试关闭下拉菜单”。链接会有吗? target="blank"?否则你怎么知道菜单是否被关闭,因为你将被重定向到链接? - Theodore K.
你需要 X Close 或者它可以是可选的?实际上它像关闭按钮或链接将工作,因为悬停效果是冲突他们。 - pradeep1991singh
@ pradeep1991singh我需要一个关闭按钮,因为我原来的下拉菜单实际上非常大,所以我需要那里。 - RulerNature


答案:


快速检查 : 工作JSFiddle

有人可以帮我解释为什么当我点击它们时,下拉菜单中的链接无效吗?也许是因为指针事件?

解释为什么会出现这种行为: 是的你是对的,这是因为你使用的方式 :active 选择器逻辑,要详细解释,请考虑您的CSS规则

.container:hover .test1:active {
    display: none;
}

您的主菜单下有菜单链接 li.test1 并且内部链接上的任何点击也会冒泡到此元素,因此它与点击该元素一样好 li。因此,只要按住鼠标(鼠标按下事件),它就会触发 :active 事件,你隐藏了 links (即: li.test1),但是 只有当鼠标向下和向上时,单击事件才会完成。所以到现在为止 li 被隐藏了 mouse up 不再在链接上。所以当你看到没有机会触发点击事件。这是问题所在。


I saw other answers which you seem to be interested in and this really doesn't need any kind of hack, It can be done by just formatting your HTML and with some CSS changes.


解: 而不是包裹内部菜单链接 li.test1 您可以 与两个不同的工作 li ,一个为 X CLose 和其他持有 menu links。有了这个,我们可以确保 什么时候 li.test1 活跃 (即鼠标已经关闭)我们可以 隐藏它以及其他新的 li 与它相邻的。所以这意味着当用户点击时 X Close  li 我们隐藏菜单,如果他点击您重定向的其他菜单项。

所以你的HTML结构的变化应该是这样的

<ul class="container">
  Drop down menu
  <li class="test1">
    <a class="dropdown" href="#">X Close</a>
  </li>
  <li class="MenuLinks">
    <ul class="content">
      <!-- all your links go here-->
    </ul>
  </li>
</ul>

主要CSS规则是

.container:hover .test1:active,
.container:hover .test1:active + .MenuLinks {
  display: none;
}

下面是一个SO工作片段

body {
  padding: 20px;
}
.container {
  border: 1px solid lime;
  padding: 10px;
  width: 200px;
  list-style-type: none;
}
.test1,
.MenuLinks {  
  display: none;
  border-color: orange;
  border-style: dashed;
  background: green;
  pointer-events: none;
}
.test1 {
  padding: 10px;
  border-width: 1px 1px 0px 1px;
}
.MenuLinks {
  border-width: 0px 1px 1px 1px;
}
.container:hover li {
  display: block;
}

/*Rule to hide both test1 and MenuLinks when X Close is clicked*/
.container:hover .test1:active,
.container:hover .test1:active + .MenuLinks {
  display: none;
}


a {
  pointer-events: auto;
  color: lime;
  font-weight: bold;
}
<ul class="container">
  Drop down menu
  <li class="test1">
    <a class="dropdown" href="#">X Close</a>
  </li>
  <!--seperate li for close-->

  <li class="MenuLinks">
    <!--wrap all your menu items here-->
    <ul class="content">
      CLOSE THIS CONTENT
      <li class="link"><a href="http://www.google.com">Go to link 1</a>
      </li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 2</a>
      </li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 3</a>
      </li>
    </ul>
    <li>
</ul>


注意: 单击链接时出现空白屏幕是由于谷歌的安全限制交叉原始策略在控制台中出现此错误

Refused to display 'https://www.google.co.in/?gfe_rd=cr&ei=x2VWWLL2Ae-K8Qfwx4ngDQ' in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'.

但是,单击链接时,您可以在网络选项卡中看到请求。

希望这可以帮助!!


3
2017-12-18 10:10



@Rajshekar Reddy你的答案非常好并保持<ul> <li>结构非常重要,但当我点击链接时,没有任何反应......应该重定向到谷歌页面,我不知道为什么 - RulerNature
@RulerNature看到了我的理由 注意 部分..它实际上是重定向..因为代码在iframe中运行,你会看到这个错误。创建自己的HTML文件并放置此代码..您可以看到它重定向到指定的链接 - Rajshekar Reddy
@RulerNature在这里我将所有上述代码添加到一个html文件中并上传到此处 sendspace.com/file/j1kss3 。您可以下载并查看所需的行为。需要帮助请叫我 - Rajshekar Reddy
@Rajshekar Reddy非常感谢你,让我测试一下你的工作,我会告诉你:) - RulerNature
@RulerNature在这里你去..我改变了CSS选择器来选择使用的所有兄弟姐妹 ~  jsfiddle.net/RajReddy/DTcHh/28013 - Rajshekar Reddy


我会这样做通常使用JS - 但在那里使用CSS  黑客:

首先使用id创建输入 close 和a label 为此包装了我们的关闭按钮:

  <input type="radio" id="close" />
  <li class="test1">
    <label for="close">
      <a class="dropdown" href="#">X Close</a>
    </label>

并添加此样式而不是当前样式 .test1:active

.container:hover #close:active + .test1{
  display: none;
}
#close {
  display: none;
}

见下面的演示:

body {
  padding: 20px;
}
.container {
  border: 1px solid lime;
  padding: 10px;
  width: 200px;
}
.test1 {
  display: none;
  border: 1px dashed orange;
  background: green;
  padding: 10px;
  pointer-events: none;
}
.container:hover .test1 {
  display: inline-block;
}
#close {
  display: none;
}
.container:hover #close:active + .test1 {
  display: none;
}
a {
  pointer-events: auto;
  color: lime;
  font-weight: bold;
}
<ul class="container">
  Drop down menu
  <input type="radio" id="close" />
  <li class="test1">
    <label for="close">
      <a class="dropdown" href="#">X Close</a>
    </label>
    <ul class="content">
      CLOSE THIS CONTENT
      <li class="link"><a href="http://www.google.com">Go to link 1</a>
      </li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 2</a>
      </li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 3</a>
      </li>
    </ul>
  </li>
</ul>

但上面的代码无效 input 里面的元素 ul - 防止您可以稍微编辑标记以创建一个更多的包装器 ul (可能由于标记更改,您必须稍微调整宽度/填充) - 请参阅下面的代码:

body {
  padding: 20px;
}
.container {
  border: 1px solid lime;
  padding: 10px;
}
ul {
  width: 200px;
}
.test1 {
  display: none;
  border: 1px dashed orange;
  background: green;
  padding: 10px;
  pointer-events: none;
}
.container:hover .test1 {
  display: inline-block;
}
#close {
  display: none;
}
.container:hover #close:active + ul > li.test1 {
  display: none;
}
a {
  pointer-events: auto;
  color: lime;
  font-weight: bold;
}
<div class="container">
  Drop down menu
  <input type="radio" id="close" />
  <ul>
    <li class="test1">
      <label for="close">
        <a class="dropdown" href="#">X Close</a>
      </label>
      <ul class="content">
        CLOSE THIS CONTENT
        <li class="link"><a href="http://www.google.com">Go to link 1</a>
        </li>
        <li class="link"><a href="https://www.google.co.uk">Go to link 2</a>
        </li>
        <li class="link"><a href="https://www.google.co.uk">Go to link 3</a>
        </li>
      </ul>
    </li>
  </ul>
</div>


4
2017-12-14 10:17



但链接没有将您重定向到谷歌页面:| - RulerNature
该片段不起作用,但我根据你的代码创建了一个小提琴,是的,工作。只有一个问题,在该级别的ul内部不允许输入:) - RulerNature
@RulerNature你是对的,我完全错过了...用标记中的额外包装器查看带有更正代码的编辑答案... - kukkuz
该代码段无法正常工作,因为重定向在其iframe中被阻止(不是您的错,它是堆栈溢出安全性) - vals
想法非常好 - Jishnu V S


它似乎没有用,因为鼠标按下了 :hover用于保持下拉菜单打开的类消失了。因此,鼠标注册事件不会在链接上执行,因为下拉列表已经再次关闭,因此不会执行任何单击操作。您应该使用javascript打开和关闭下拉菜单。


1
2017-12-09 14:15



是的,我看到了,但为什么?这是正常的吗? - RulerNature
如果你拿走 .container:hover .test1:active { display: none; }它似乎工作。 - Martin Cup
这样做时,单击关闭顶部按钮或链接时,容器将不会关闭... - RulerNature
是的CSS在交互性方面不是很强大,这就是我建议使用Javascript的原因,因为它要么是CSS中的一个非常复杂的事情,要么是不可能的,但我不能证明它是不可能的。 - Martin Cup


我建议删除

.container:hover .test1:active {
    display: none;
}

并且当您单击“X关闭”链接时,找到另一种方式(几行javascript将会这样做)关闭面板。 (顺便修复了一些html缺失的标签)。现在链接正在运行:

body {
    padding: 20px;
}
.container {
    border: 1px solid lime;
    padding: 10px;
    width: 200px;
}
.test1 {
    display: none;
    border: 1px dashed orange;
    background: green;
    padding: 10px;
    pointer-events: none;
}
.container:hover .test1 {
    display: inline-block;
}
a {
    pointer-events: auto;
    color: lime;
    font-weight: bold;
}
<ul class="container">
  Drop down menu
  <li class="test1">
    <a class="dropdown" href="#">X Close</a>
    <ul class="content">
      CLOSE THIS CONTENT
      <li class="link"><a href="http://www.google.com">Go to link 1</a></li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 2</a></li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 3</a></li>
    </ul>
  </li>
</ul>


1
2017-12-09 14:26



不是一个选项,我需要激活,以便在访问链接或单击顶部的“关闭”按钮后关闭容器。 - RulerNature


您可以使用 label 和 button 到位 a 关闭链接,可以做类似下面的事情 -

body {
  padding: 20px;
}

.container {
  border: 1px solid lime;
  padding: 10px;
  width: 200px;
}

.test1 {
  display: none;
  border: 1px dashed orange;
  background: green;
  padding: 10px;
  pointer-events: none;
}

.container:hover .test1 {
  display: inline-block;
}

a, label {
  pointer-events: auto;
  color: lime;
  font-weight: bold;
}

/* close button */
#xclose:active + .test1 {
  display:none;
}

#xclose {
  display: none;
}
<ul class="container">
  Drop down menu
  <button id="xclose">X close</button>
  <li class="test1">    
    <label class="dropdown" for="xclose">X Close</label>        
    <ul class="content">
      CLOSE THIS CONTENT
      <li class="link"><a href="http://www.google.com">Go to link 1</a></li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 2</a></li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 3</a></li>
    </ul>
  </li>
</ul>

希望这会以某种方式帮助你(y)。


1
2017-12-14 16:26





你为什么补充 "pointer-events: none;" 到列表元素.test1?这会覆盖你的 pointer-events: auto;。尝试删除它,因为它会绑定您的click事件。


0
2017-12-09 14:14



需要那里的指针事件,以便仅在链接上关闭容器,而不是在单击整个容器时。因此,使用指针事件可以指示仅在链接上执行此操作;) - RulerNature


我建议尝试使用 jQuery 仅在按下链接时处理关闭容器。 pointer-events 有很多问题。因此他们决定将该功能推迟到CSS4。

我也想 pointer-events: none; 防止任何点击事件被触发,所以使用jQuery只是为了链接不会工作。我想你必须用jQuery修复容器的打开和关闭。


0
2017-12-14 08:51



使用javascript可以在一分钟内完成,但我不想使用js,它可能只使用css,我看到类似的事情:target和:active但在我的情况下,我需要将这种行为应用于那些链接。 - RulerNature
@RulerNature但是你不想使用JS的原因是什么?为什么要花这么多时间来尝试实现CSS功能,他们说这些功能在CSS4之前不会得到很好的支持。 - Kevinvhengst


在CSS中,您可以绑定 label 要素 inputs。鉴于此,您可以将关闭按钮绑定到输入 - 当处于活动状态时 - 再次隐藏列表。

body{
  padding: 20px;
}

a, label{
  text-decoration: none;
  cursor: pointer;
  color: lime;
  font-weight: bold;
}

.container{
  border: 1px solid lime;
  padding: 10px;
  width: 200px;
}

.dropdown{
  display: none;
  border: 1px solid orange;
  background: green;
  margin-top: 10px;
  padding: 10px;
}

#close, #close:active + .dropdown{
  display: none;
}

.container:hover .dropdown{
  display: block;
}

.dropdown > ul{
  padding: 0;
  list-style: none;
}
<div class="container">
  Drop down menu
  <button id="close"></button>
  <div class="dropdown">
    <label for="close">X Close</label>
    <ul>
      <li class="link"><a href="http://www.google.com">Go to link 1</a></li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 2</a></li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 3</a></li>
    </ul>
  </div>
</div>

input 同 id="close" 在列表之前插入,并由标签触发 for="close"
触发后,以下规则将生效:

#close, #close:active + .dropdown{
  display: none;
}

这隐藏了这个清单。
但是当你将鼠标悬停在 .container,它会再次出现,让您重复这个过程。 这里不需要不必要的JavaScript。输入会做。

您的代码也存在一些问题。你有文字 Drop down menu 和 CLOSE THIS CONTENT 直接在里面 ul,这是无法做到的。一个 ul 只能包含 li没什么别的。

希望这可以帮助


0
2017-12-16 00:08