我正在学习一些CSS,今天我发现自己想要实现一个类似的上下文菜单(点击youtube卡上的垂直elipsis时显示的那个菜单),但是我的尝试并没有做多大的努力:D。我要说的是:
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.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;
style-type: none;
}
.dropdown .dropdown-toggle:checked+ul {
display: block;
}
.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;
}
</style>
</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-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>
</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-opener1">...</label>
<input class="dropdown-toggle" id="menu-opener1" type="checkbox">
<ul class="dropdown-menu">
<li>Foo2</li>
<li>Bar2</li>
<li>Baz2</li>
</ul>
</nav>
</div>
<div class="container">
<img alt="sample" src="https://via.placeholder.com/200x200">
<nav class="dropdown layer--topright">
<icon-button id="button" class="dropdown-opener dropdown-trigger style-scope menu-renderer">
<button id="button" class="style-scope icon-button" aria-label="Action menu">
<icon class="style-scope menu-renderer">
<svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope icon" style="pointer-events: none; display: block; width: 100%; height: 100%;">
<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>
</icon>
</button>
</icon-button>
<input class="dropdown-toggle" id="menu-opener2" type="checkbox">
<ul class="dropdown-menu">
<li>Foo3</li>
<li>Bar3</li>
<li>Baz3</li>
</ul>
</nav>
</div>
</body>
</html>
如你所见,代码又脏又坏.但我的尝试中有一些主要问题,我不知道如何解决:
所以,如果你能解释一下如何解决这些问题,以便让我的尝试有用,那就太棒了。
或者如果我的方法是错误的,无法使用,并且准备扔进垃圾箱.你能解释一下怎样才能达到我的目标吗?
提前谢谢。
发布于 2020-06-17 04:29:53
问题1
单击“溢出”菜单按钮时,将上下文菜单错误放置。上下文菜单实际上并没有被放错位置。for元素中的<label>属性引用了错误的上下文菜单。例如,第一个for中的<label>元素的for值为menu-opener1,但是第二个 .container中<label>元素的for值具有完全相同的值。单击任一标签将导致打开第一个容器中的下拉菜单,因为这两个标签都会导致选中第一个容器上的隐藏复选框。
我们能做什么?只需更改id值,以便每个下拉菜单都有一个唯一的id值。然后,在您的for元素中使用这个id值作为<label>值。
问题2
要在list-style-type: none中隐藏li元素的公告,您必须在ul上使用而不是 style-type: none。
问题3
这是一个非常主观的问题。一个设计在一个人看来是干净的,但在其他人看来却是不干净的。尽管如此,我还是努力实现我想要看到的。以下是一些您可以更改以改进设计方面的内容。
li元素之间添加空格。在这里,我使用了line-height。您还可以对每个padding元素使用margin或li。box-shadow以显示海拔。谷歌的材料设计公司建议使用这种技术来证明元素的z位更高。visibility和display)。在这里,我选择使用transform: scale和opacity转换。其他关切
在语义上,HTML标记是不正确的。
<nav> (导航)元素用于在页面之间导航。在这里,您可能应该使用元素代替。然而,由于它仍然是实验性的,我选择使用<section>。<icon-button>和<icon>)。尝试咨询这里有有效的HTML标记和这里有有效的SVG标签。.container项有一个按钮,将检查隐藏复选框。然而,元素.因此,尝试使<label>元素看起来像一个按钮。您可以使用:active和:hover CSS伪选择器分别在按钮样式按下和悬停时更改它。此外,这减少了嵌套。.container来包含整个页面,因此我选择使用类名.box而不是.container。这是可运行的片段。
* {
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>
更新
由于无法清楚地理解OP的含义,即在鼠标悬停时使菜单项改变状态有多难,所以我决定在鼠标悬停上创建一个效果,在单击<li>元素时创建一个不同的效果(纹波)。我建议阅读这个关于产生涟漪效应的写作。
此外,根据请求,添加了菜单框外单击时隐藏菜单的功能。这是可运行的片段。
// 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>
发布于 2020-06-17 06:44:10
$(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>
嗨,请检查一下这把小提琴,希望这个能帮你
发布于 2020-06-13 23:26:22
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.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;
style-type: none;
}
.dropdown .dropdown-toggle:checked+ul {
display: block;
}
ul.dropdown-menu {
background-color: white;
padding: 1rem 2rem;
list-style-type: none;
line-height: 2rem;
}
ul.dropdown-menu li a {
color: orange;
}
.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;
}
</style>
</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-opener1">...</label>
<input class="dropdown-toggle" id="menu-opener1" type="checkbox">
<ul class="dropdown-menu">
<li><a href="#">Foo1</a></li>
<li>Bar1</li>
<li>Baz1</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">...</label>
<input class="dropdown-toggle" id="menu-opener2" type="checkbox">
<ul class="dropdown-menu">
<li>Foo2</li>
<li>Bar2</li>
<li>Baz2</li>
</ul>
</nav>
</div>
<div class="container">
<img alt="sample" src="https://via.placeholder.com/200x200">
<nav class="dropdown layer--topright">
<icon-button id="button" class="dropdown-opener dropdown-trigger style-scope menu-renderer">
<button id="button" class="style-scope icon-button" aria-label="Action menu">
<icon class="style-scope menu-renderer">
<svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope icon" style="pointer-events: none; display: block; width: 100%; height: 100%;">
<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>
</icon>
</button>
</icon-button>
<input class="dropdown-toggle" id="menu-opener2" type="checkbox">
<ul class="dropdown-menu">
<li>Foo3</li>
<li>Bar3</li>
<li>Baz3</li>
</ul>
</nav>
</div>
</body>
</html>
https://stackoverflow.com/questions/62366173
复制相似问题