web-dev-qa-db-ja.com

CSSのみを使用して、ホバー時にドロップダウンメニューを表示し、クリック時に閉じる

ドロップダウンメニューのリンクをクリックしてもリンクが機能しない理由について誰かが説明してくれますか?たぶん、ポインタイベントのためでしょうか?リンクをクリックするか、閉じるボタンをクリックした後に閉じるドロップダウンメニューを作成しようとしています。リンクがクリックされたときに親コンテナーを非表示にするなどのクールな機能を追加しました。

それを行う多くのオプションがあります:

  1. :focusを使用しますが、フォーカスが使用されている場合、ドロップダウンの上にカーソルを置いたときにドロップダウンがトリガーされません。

  2. コンテナで:activeを使用し、アクティブなリンクのみを指すようにpointer-eventsを使用しているが、ポインタイベントにバグがある

  3. :targetを使用しても、:focusと同じ問題があり、2番目のフーバーがトリガーされません。
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>
13
RulerNature

クイックチェック:Working 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内の内部メニューリンクをまとめるのではなく、2つの異なるliを使用して、1つをX CLoseおよびmenu linksを保持するためのその他。これを実行すると、[li.test1がアクティブなとき(つまり、マウスがダウンしているとき)が確認できます非表示にし、他の新しいliも非表示にします隣接しています。つまり、これは、ユーザーがX Closeliをクリックするたびにメニューを非表示にすることを意味します。ユーザーが他のメニュー項目をクリックすると、リダイレクトされます。

したがって、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>

注:リンクをクリックすると空白の画面が表示されるのは、Googleのセキュリティ制限により、コンソールでこのエラーが発生するクロスオリジンポリシーに関する制限です。

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
Rajshekar Reddy

私は通常JSを使用してこれを行います-しかし、CSSがあるとisハック:

最初に、ID closelabelを使用して入力を作成します。これにより、閉じるボタンがラップされます。

  <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のラッパーをもう1つ作成できないようにするためです(おそらくマークアップの変更による幅/パディングの調整)-以下のコードを参照してください:

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
kukkuz

labelbuttonaの代わりに使用してリンクを閉じることができ、以下のようなことができます-

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

削除することをお勧めします

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

そして、「X Close」リンクをクリックしたときにパネルを閉じる別の方法(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
Theodore K.

ドロップダウンメニューを開いたままにするための:hover- classがマウスで押されているため、機能しないようです。そのため、ドロップダウンがすでに閉じているため、リンク上でマウスアップイベントは実行されず、クリックは実行されません。ドロップダウンメニューを開いたり閉じたりするには、JavaScriptを使用する必要があります。

1
Martin Cup

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>

id="close"を含むinputはリストの前に挿入され、for="close"を含むラベルによってトリガーされます
トリガーされると、次のルールが有効になります:

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

リストを非表示にします。
しかし、.containerにカーソルを合わせると、再び表示され、プロセスを繰り返すことができます。ここでは不要なJavaScriptは必要ありません。入力で十分です。

コードにも問題がありました。テキストDrop down menuCLOSE THIS CONTENTulの中に直接ありましたが、これは実行できません。 ulにはliのみを含めることができ、他には何も含めることができません。

お役に立てれば

0
Gust van de Wal

jQueryを使用して、リンクが押されたときにのみコンテナーを閉じる処理を試みることをお勧めします。 pointer-eventsには多くの問題があります。このため、機能をCSS4に延期することを決定しました。

私も思います pointer-events: none;は、クリックイベントが発生しないようにするため、リンクにjQueryを使用するだけでは機能しません。私はあなたがjQueryでコンテナの開閉を修正する必要があると思います。

0
Kevinvhengst

オプションの1つはanimateを使用することです。opacityを使用したコードの例を示しました。 visibility:hiddenまたはoverflow:hiddenを使用すると、コードが拡張されます。

    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;
    }


.container .test1 {
  -webkit-animation: seconds 1.0s forwards;
  -webkit-animation-iteration-count: 1;
  -webkit-animation-delay: 2s;
  animation: seconds 1.0s forwards;
  animation-iteration-count: 1;
  animation-delay: 2s;
  position: relative;
}
@-webkit-keyframes seconds {
  0% {
    opacity: 1;
  }
  100% {
    opacity: 0;

  }

@keyframes seconds {
  0% {
    opacity: 1;
  }

  100% {
    opacity: 0;

  }
} </ code>
    <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>
0
shubham agrawal
.container:hover .test1:active {
display: none;
}

これを次のように変更します

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

ここで何が起こっているかというと、divがリンクのクリックから「アクティブな」疑似コードを受け取っているとき、DOMがリンクにバブルしてリダイレクトを行う前に、divが非表示になっているということです。フォーカスに変更すると、クリックが実際に通過する可能性がありますか?

0
jjeining

なぜ"pointer-events: none;"をリスト要素.test1に追加したのですか?これはpointer-events: auto;を上書きします。クリックイベントをバインドするため、削除してみてください。

0
ReAlPeNx