How to implement context menus similarly to youtube cards?

Issue #1

Misplaced context menus when clicking the overflow menu button. The context menus are not actually misplaced. The for attribute in your <label> element refers to the wrong context menus. For example, the for value of your <label> element in the first .container has a value of menu-opener1, but the for value on the <label> element in the second .container has the exact same value. Clicking either label causes the dropdown menu in the first container to be opened because both labels cause the hidden checkbox on the first container to be checked.

What can we do? Simply change the id value so that each dropdown menu has a unique id value. Then, use that id value for the for value inside your <label> element.


Issue #2

To hide the bulletins of li elements inside a ul, you have to use list-style-type: none on your CSS and not style-type: none.


Issue #3

This is a very subjective matter. A design can look clean to one but look unclean to others. Nevertheless, I tried to achieve what I wanted to see. Here are some things that you can change to improve the design aspect.

  • Change your font-family so that it suits your theme. I chose a sans-serif font family here.
  • Add a background to your context menu. Here, I chose the color white.
  • Add space between each li element. Here, I used line-height. You can also use padding or margin on each li element.
  • Add a box-shadow to show elevation. Google's Material Design recommends using this technique to show that an element's z-position is higher.
  • Allow transition from when the context menu changes from visible to invisible and vice-versa. This means avoiding using un-transition-able CSS properties (e.g. visibility and display). Here, I chose to use transform: scale and opacity transition.

Other concerns

Semantically, your HTML tags are incorrect.

  • The <nav> (navigation) element is used to navigate between pages. Here, you should probably use <menu> element instead. However, as it is still experimental, I chose to use <section>.
  • You are using some nonexistant HTML tags (e.g. <icon-button> and <icon>). Try consulting here for valid HTML tags and here for valid SVG tags.
  • The last .container item has a button that will check the hidden checkbox. However, the <button> element does not work with <label> element. So, try to make the <label> element visually look like a button instead. You can use :active and :hover CSS pseudoselectors to change the button style when it is pressed and hovered respectively. Furthermore, this reduces nesting.
  • Try to always avoid using inline styles when styling using CSS is possible (e.g. your inline SVG styles)
  • Personal preference. Most frameworks use .container to contain the whole page, so I have opted to use the class name .box instead of .container.

Here's the runnable snippet.

* {
  font-family: Helvetica;
  box-sizing: border-box;
}

.box {
  display: inline-block;
  position: relative;
}

.dropdown {
  position: absolute;
  right: 0;
  top: 8px;
}

.dropdown-opener {
  cursor: pointer;
  user-select: none;
  position: absolute;
  width: 24px;
  height: 24px;
  background: url('https://i.imgur.com/Qt3Qwgp.png');
  background-repeat: no-repeat;
  background-position: right;
  right: 0;
}

.dropdown .dropdown-toggle {
  display: none;
}

.dropdown .dropdown-menu {
  list-style-type: none;
  transform: scale(0);
  opacity: 0;
  transition:
    transform 0.25s ease,
    opacity 0.25s ease;
  
  position: absolute;
  top: 1.5em;
  right: 10px;
  line-height: 1.75em;
  background: white;
  box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.5);
  border-radius: 5px;
  padding: 20px;
  margin: 0;
  transform-origin: top right;
}

.dropdown .dropdown-toggle:checked + ul {
  transform: scale(1);
  opacity: 1;
}

.dropdown-opener-button {
  position: absolute;
  width: 24px;
  height: 24px;
  right: 8px;
  top: 0;
}

.icon-button {
  padding: 0;
  border: 0;
  border-radius: 5px;
  cursor: pointer;
  transition: 
    box-shadow .25s ease,
    background .25s ease,
    transform .25s ease;
  background: #ffffffdd;
}

.icon-button:hover {
  box-shadow: 0px 0px 2px 0px rgba(0,0,0,0.35);
}

.icon-button:active {
  background: #ffffff77;
  transform: scale(0.9);
}

.icon-button ~ .dropdown-menu {
  top: 1.75em;
}
<div class="box">
  <img alt="sample" src="https://via.placeholder.com/200x200">
  <section class="dropdown layer--topright">
    <label class="dropdown-opener" for="menu-opener1"></label>
    <input class="dropdown-toggle" id="menu-opener1" type="checkbox">
    <ul class="dropdown-menu">
      <li>Foo1</li>
      <li>Bar1</li>
      <li>Baz1</li>
    </ul>
  </section>
</div>
<div class="box">
  <img alt="sample" src="https://via.placeholder.com/200x200">
  <section class="dropdown layer--topright">
    <label class="dropdown-opener" for="menu-opener2"></label>
    <input class="dropdown-toggle" id="menu-opener2" type="checkbox">
    <ul class="dropdown-menu">
      <li>Foo2</li>
      <li>Bar2</li>
      <li>Baz2</li>
    </ul>
  </section>
</div>
<div class="box">
  <img alt="sample" src="https://via.placeholder.com/200x200">
  <section class="dropdown layer--topright">
    <label class="dropdown-opener-button icon-button" for="menu-opener3">
      <svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope icon">
        <g class="style-scope icon">
          <path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" class="style-scope icon"></path>
        </g>
      </svg>
    </label>
    <input class="dropdown-toggle" id="menu-opener3" type="checkbox">
    <ul class="dropdown-menu">
      <li>Foo3</li>
      <li>Bar3</li>
      <li>Baz3</li>
    </ul>
  </section>
</div>


Update

Not having a crystal-clear understanding of what the OP meant by how hard would it be to make the menu items change the state when hovering with the mouse, I decided to create an effect on hovered and a different effect (ripple) on click for the <li> elements. I recommend reading this writing on creating a ripple effect.

Also, as per request, the functionality to hide the menus when a click outside of the menu's box has been added. Here's the runnable snippet.

// Closing menu on outside click
const outsideClickListener = event => {
  let checkedToggle = document.querySelector('.dropdown-toggle:checked')
  let openedMenu = document.querySelector('.dropdown-toggle:checked + .dropdown-menu')
  
  // If click is performed on checkbox (through label), do nothing
  if (event.target.classList.contains('dropdown-toggle')) {
    return
  }
  
  // If click is performed on label, uncheck all other dropdown-toggle
  if (event.target.classList.contains('dropdown-opener') ||
      event.target.classList.contains('dropdown-opener-button')) {
    let forId = event.target.getAttribute('for')
    document.querySelectorAll('.dropdown-toggle').forEach(toggle => {
      if (forId !== toggle.getAttribute('id'))
        toggle.checked = false
    })
    return
  }
  
  // If click is performed outside opened menu
  if (openedMenu && !openedMenu.contains(event.target)) {
    checkedToggle.checked = false
  }
}
document.addEventListener('click', outsideClickListener)

// Ripple effect on li elements
const createRipple = event => {
  let li = event.target
  let liBox = li.getBoundingClientRect()
  let x = event.pageX - liBox.left
  let y = event.pageY - liBox.top
  let animDuration = 350
  let animationStart, animationFrame
  
  let animationStep = timestamp => {
    if (!animationStart) animationStart = timestamp
    let frame = timestamp - animationStart
    if (frame < animDuration) {
      let easing = (frame / animDuration) * (2 - (frame / animDuration))
      let circle = `circle at ${x}px ${y}px`
      let color = `rgba(0, 0, 0, ${0.2 * (1 - easing)})`
      let stop = `${100 * easing}%`
      li.style.backgroundImage = `radial-gradient(${circle}, ${color} ${stop}, transparent ${stop})`
      animationFrame = window.requestAnimationFrame(animationStep)
    }
    else {
      li.style.backgroundImage = ''
      window.cancelAnimationFrame(animationStep)
    }
  }
  
  animationFrame = window.requestAnimationFrame(animationStep)
}
const listItems = document.querySelectorAll('li')
listItems.forEach(li => {
  li.addEventListener('click', createRipple)
})
* {
  font-family: Helvetica;
  box-sizing: border-box;
}

.box {
  display: inline-block;
  position: relative;
}

.dropdown {
  position: absolute;
  right: 0;
  top: 8px;
}

.dropdown-opener {
  cursor: pointer;
  user-select: none;
  position: absolute;
  width: 24px;
  height: 24px;
  background: url('https://i.imgur.com/Qt3Qwgp.png');
  background-repeat: no-repeat;
  background-position: right;
  right: 0;
}

.dropdown .dropdown-toggle {
  display: none;
}

.dropdown .dropdown-menu {
  list-style-type: none;
  transform: scale(0);
  opacity: 0;
  transition:
    transform 0.25s ease,
    opacity 0.25s ease;
  
  position: absolute;
  top: 1.5em;
  right: 10px;
  background: white;
  box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.5);
  border-radius: 5px;
  margin: 0;
  transform-origin: top right;
  padding: 7.5px 0 7.5px 0;
}

.dropdown .dropdown-toggle:checked + ul {
  transform: scale(1);
  opacity: 1;
}

.dropdown-menu li {
  padding: 7.5px;
  padding-left: 25px;
  cursor: pointer;
  transition: background .15s ease;
}

.dropdown-menu li:hover {
  background: #00000012;
}

.dropdown-opener-button {
  position: absolute;
  width: 24px;
  height: 24px;
  right: 8px;
  top: 0;
}

.dropdown-opener-button svg {
  pointer-events: none;
}

.icon-button {
  padding: 0;
  border: 0;
  border-radius: 5px;
  cursor: pointer;
  transition: 
    box-shadow .25s ease,
    background .25s ease,
    transform .25s ease;
  background: #ffffffdd;
}

.icon-button:hover {
  box-shadow: 0px 0px 2px 0px rgba(0,0,0,0.35);
}

.icon-button:active {
  background: #ffffffaa;
  box-shadow: 0px 0px 4px 0px rgba(0,0,0,0.35);
  transform: scale(0.9);
}

.icon-button ~ .dropdown-menu {
  top: 1.75em;
}
<div class="box">
  <img alt="sample" src="https://via.placeholder.com/200x200">
  <section class="dropdown layer--topright">
    <label class="dropdown-opener" for="menu-opener1"></label>
    <input class="dropdown-toggle" id="menu-opener1" type="checkbox">
    <ul class="dropdown-menu">
      <li>Foo1</li>
      <li>Bar1</li>
      <li>Baz1</li>
    </ul>
  </section>
</div>
<div class="box">
  <img alt="sample" src="https://via.placeholder.com/200x200">
  <section class="dropdown layer--topright">
    <label class="dropdown-opener" for="menu-opener2"></label>
    <input class="dropdown-toggle" id="menu-opener2" type="checkbox">
    <ul class="dropdown-menu">
      <li>Foo2</li>
      <li>Bar2</li>
      <li>Baz2</li>
    </ul>
  </section>
</div>
<div class="box">
  <img alt="sample" src="https://via.placeholder.com/200x200">
  <section class="dropdown layer--topright">
    <label class="dropdown-opener-button icon-button" for="menu-opener3">
      <svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope icon">
        <g class="style-scope icon">
          <path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" class="style-scope icon"></path>
        </g>
      </svg>
    </label>
    <input class="dropdown-toggle" id="menu-opener3" type="checkbox">
    <ul class="dropdown-menu">
      <li>Foo3</li>
      <li>Bar3</li>
      <li>Baz3</li>
    </ul>
  </section>
</div>


$(document).ready(function() {
  $('.dropdown-opener').on('click', function() {
    $('.dropdown-menu').removeClass('show');
    $(this).parents('.dropdown').children('.dropdown-menu').toggleClass('show')
  });
  $(document).on('click', function(e) {
    if (!(e.target.matches('.dropdown-opener') || e.target.matches('.fa.fa-ellipsis-v'))) {
      $('.dropdown-menu').removeClass('show');      
    	//debugger;
    }
  });
});
.container {
  display: inline-block;
  position: relative;
}

.dropdown {
  position: absolute;
  right: 1rem;
  top: 1rem;
}

.dropdown-opener {
  cursor: pointer;
  user-select: none;
  position: absolute;
  right: 0;
}

.dropdown .dropdown-toggle,
.dropdown .dropdown-menu {
  display: none;
  list-style-type: none;
}

.dropdown .dropdown-toggle:checked+ul {
  display: block;
}

ul.dropdown-menu {
  background-color: #efefef;
  list-style-type: none;
  line-height: 1.5rem;
  border-radius: 3px;
  padding: 0;
  min-width: 60px;
  float: left;
  font-size: 14px;
  font-weight: bold;
  -webkit-box-shadow: 2px 3px 3px -1px rgba(196, 186, 196, 1);
  -moz-box-shadow: 2px 3px 3px -1px rgba(196, 186, 196, 1);
  box-shadow: 2px 3px 3px -1px rgba(196, 186, 196, 1);
}

ul.dropdown-menu.show {
  display: block;
}

ul.dropdown-menu li a {
  text-decoration: none;
  color: #030303;
  width: 100%;
  float: left;
  padding: 7px 15px;
  box-sizing: border-box;
}

ul.dropdown-menu li a:hover {
  background: #ddd;
}

ul.dropdown-menu li a i {
  margin-right: 10px;
}

.style-scope .menu-renderer {
  --layout-inline_-_display: inline-flex;
  --icon-button-icon-height: 24px;
  --icon-button-icon-width: 24px;
  --spec-icon-active-other: #606060;
  --spec-icon-inactive: #909090;
  --spec-text-disabled: #909090;
  --spec-text-secondary: #606060;
  align-items: var(--layout-center-center_-_align-items);
  color: var(--menu-renderer-button-color, var(--spec-icon-inactive));
  cursor: pointer;
  display: var(--layout-inline_-_display);
  fill: var(--iron-icon-fill-color, currentcolor);
  width: var(--icon-button-icon-width, 100%);
  background: transparent;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.0-2/css/all.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>

  <head>
  </head>

  <body>
    <div class="container">
      <img alt="sample" src="https://via.placeholder.com/200x200">
      <nav class="dropdown layer--topright">
        <label class="dropdown-opener" for="menu-opener2"><i class="fa fa-ellipsis-v" aria-hidden="true"></i></label>
        <input class="dropdown-toggle" type="checkbox">
        <ul class="dropdown-menu">
          <li><a href="#"> <i class="fa fa-heart" aria-hidden="true"></i> Wishlist</a></li>
          <li><a href="#"><i class="fa fa-share-alt" aria-hidden="true"></i>
              Share</a></li>
          <li><a href="#"><i class="fa fa-ban" aria-hidden="true"></i> Not interested</a></li>
        </ul>
      </nav>
    </div>

    <div class="container">
      <img alt="sample" src="https://via.placeholder.com/200x200">
      <nav class="dropdown layer--topright">
        <label class="dropdown-opener" for="menu-opener2"><i class="fa fa-ellipsis-v" aria-hidden="true"></i></label>
        <input class="dropdown-toggle" type="checkbox">
        <ul class="dropdown-menu">
          <li><a href="#"> <i class="fa fa-heart" aria-hidden="true"></i> Wishlist</a></li>
          <li><a href="#"><i class="fa fa-share-alt" aria-hidden="true"></i>
              Share</a></li>
          <li><a href="#"><i class="fa fa-ban" aria-hidden="true"></i> Not interested</a></li>
        </ul>
      </nav>
    </div>
  </body>

</html>

Hi Please check this fiddle, Hope this will help you

https://jsfiddle.net/hm2zuo3r/2/