是否有可能将焦点放在父元素内而不被所有子元素应用,但只有一个特定的子元素?
is it possible to focus-within a parent element and not get applied by all child elements but one specific?
问题来了:
focus-within 适用于标签内的所有子元素
示例:
<a class="open" href="#">open menu</a>
<div class="parent">
<a class="link1" href="#">link1</a>
<a class="link2" href="#">link2</a>
<div class="menu2">...123</div>
<a class="link3" href="#">link3</a>
<div class="menu3">...456</div>
</div>
在此示例中,我使用 a.link2 和 a.link3 在它们处于焦点时打开菜单。
我需要设置 a.link1 来关闭 div.parent
我通过以下方式做到了:
<style>
.parent{width:200px;height:100%;position:fixed;left:-30em;background:lightyellow;}
.open:focus + .parent,.parent:hover{left:0;}/*opening sidebar*/
.parent:focus-within{left:-20em;}/*closing sidebar*/
.parent:focus-within + a.link1{left:-20em}/*closing sidebar*/
</style>
当我点击 a.link2 和 a.link3 时它也关闭了侧边栏,我只想申请 a.link1 才能关闭侧边栏!
如何设置 a.link1 关闭侧边栏而不是(a.link2 & a.link3 和 ....)只有 css,没有 JavaScript?
有什么办法吗?
.parent{width:200px;height:100%;position:fixed;left:-30em;background:lightyellow;}
.open:focus + .parent,.parent:hover{left:0;}/*opening sidebar*/
.parent:focus-within{left:-20em;}/*closing sidebar*/
.parent:focus-within + a.link1{left:-20em}/*closing sidebar*/
<a class="open" href="#">open menu</a>
<div class="parent">
<a class="link1" href="#">link1</a>
<a class="link2" href="#">link2</a>
<div class="menu2">...123</div>
<a class="link3" href="#">link3</a>
<div class="menu3">...456</div>
</div>
简短的回答是,您尝试使用的方法是不可能的。
原因是选择器只能自上而下。这意味着虽然 parent div 可以通过单击其中一个 children 来关闭,但这只是因为 focus-within
选择器才成为可能。它与 parent 的 children 无关。如果您希望元素 A 影响 CSS 中的元素 B,元素 A 需要是兄弟元素或至少比元素 B 高一级才能影响它。
为了仅使用 CSS 创建这种侧边栏,您必须使用“复选框 hack”。我会在这里留下一个小例子然后解释它是如何工作的:
* {
font-family: 'Segoe UI', monospace;
}
#toggler {
display: none;
}
nav {
position: fixed;
top: 0;
left: -150px;
width: 200px;
height: 100vh;
box-shadow: 1px 2px 3px rgb(30 30 30 / 50%);
transition: left 0.2s;
}
img {
width: 30px;
}
label {
display: block;
text-align: right;
padding: 10px;
cursor: pointer;
}
#toggler:checked + nav {
left: 0;
}
<input type="checkbox" id="toggler">
<nav>
<label for="toggler">
<img src="https://cdn4.iconfinder.com/data/icons/website-library/32/hamburger_List_hamburger_right_menu_website-512.png" alt="">
</label>
</nav>
基本上,实际的复选框在导航之外。这样,无论它是否被选中都会影响导航,它是它的兄弟。但是,该复选框的标签仍在导航内,这会创建您似乎想要的行为。单击标签时,它会影响其对应的复选框是否被选中。这让我们解决了 children 无法影响 CSS.
中的 parent 的问题
编辑:
所以,我刚刚发现了另一个使用锚标记和 :target
伪选择器的技巧。
这是另一个片段:
nav {
position: absolute;
top: 0;
left: -150px;
width: 200px;
height: 100vh;
box-shadow: 1px 2px 3px rgb(30 30 30 / 50%);
text-align: right;
padding: 5px;
box-sizing: border-box;
transition: left 0.2s;
}
a {
display: block;
margin: 5px 0;
font-family: 'Segoe UI', monospace;
color: blue;
}
#open:target ~ nav {
left: 0;
}
#close:target ~ nav {
left: -150px;
}
<div id="open"></div>
<div id="close"></div>
<nav>
<a href="#open">Open</a>
<a href="#close">Close</a>
</nav>
它的工作方式是,首先,我们需要一些至少与我们的 nav
处于同一级别的元素,以便它们能够影响它。每个元素都有一个 id,锚标签可以将其用作目标。单击锚标记时,锚标记 href 中具有 id 的元素会触发其 :target
伪选择器。由于此示例中的目标元素是 nav
的兄弟元素,因此它们在目标时会影响其样式。 ~
只是一个兄弟选择器,它针对任何兄弟,而不仅仅是像 +
那样的相邻兄弟。
问题来了: focus-within 适用于标签内的所有子元素 示例:
<a class="open" href="#">open menu</a>
<div class="parent">
<a class="link1" href="#">link1</a>
<a class="link2" href="#">link2</a>
<div class="menu2">...123</div>
<a class="link3" href="#">link3</a>
<div class="menu3">...456</div>
</div>
在此示例中,我使用 a.link2 和 a.link3 在它们处于焦点时打开菜单。 我需要设置 a.link1 来关闭 div.parent 我通过以下方式做到了:
<style>
.parent{width:200px;height:100%;position:fixed;left:-30em;background:lightyellow;}
.open:focus + .parent,.parent:hover{left:0;}/*opening sidebar*/
.parent:focus-within{left:-20em;}/*closing sidebar*/
.parent:focus-within + a.link1{left:-20em}/*closing sidebar*/
</style>
当我点击 a.link2 和 a.link3 时它也关闭了侧边栏,我只想申请 a.link1 才能关闭侧边栏!
如何设置 a.link1 关闭侧边栏而不是(a.link2 & a.link3 和 ....)只有 css,没有 JavaScript? 有什么办法吗?
.parent{width:200px;height:100%;position:fixed;left:-30em;background:lightyellow;}
.open:focus + .parent,.parent:hover{left:0;}/*opening sidebar*/
.parent:focus-within{left:-20em;}/*closing sidebar*/
.parent:focus-within + a.link1{left:-20em}/*closing sidebar*/
<a class="open" href="#">open menu</a>
<div class="parent">
<a class="link1" href="#">link1</a>
<a class="link2" href="#">link2</a>
<div class="menu2">...123</div>
<a class="link3" href="#">link3</a>
<div class="menu3">...456</div>
</div>
简短的回答是,您尝试使用的方法是不可能的。
原因是选择器只能自上而下。这意味着虽然 parent div 可以通过单击其中一个 children 来关闭,但这只是因为 focus-within
选择器才成为可能。它与 parent 的 children 无关。如果您希望元素 A 影响 CSS 中的元素 B,元素 A 需要是兄弟元素或至少比元素 B 高一级才能影响它。
为了仅使用 CSS 创建这种侧边栏,您必须使用“复选框 hack”。我会在这里留下一个小例子然后解释它是如何工作的:
* {
font-family: 'Segoe UI', monospace;
}
#toggler {
display: none;
}
nav {
position: fixed;
top: 0;
left: -150px;
width: 200px;
height: 100vh;
box-shadow: 1px 2px 3px rgb(30 30 30 / 50%);
transition: left 0.2s;
}
img {
width: 30px;
}
label {
display: block;
text-align: right;
padding: 10px;
cursor: pointer;
}
#toggler:checked + nav {
left: 0;
}
<input type="checkbox" id="toggler">
<nav>
<label for="toggler">
<img src="https://cdn4.iconfinder.com/data/icons/website-library/32/hamburger_List_hamburger_right_menu_website-512.png" alt="">
</label>
</nav>
基本上,实际的复选框在导航之外。这样,无论它是否被选中都会影响导航,它是它的兄弟。但是,该复选框的标签仍在导航内,这会创建您似乎想要的行为。单击标签时,它会影响其对应的复选框是否被选中。这让我们解决了 children 无法影响 CSS.
中的 parent 的问题编辑:
所以,我刚刚发现了另一个使用锚标记和 :target
伪选择器的技巧。
这是另一个片段:
nav {
position: absolute;
top: 0;
left: -150px;
width: 200px;
height: 100vh;
box-shadow: 1px 2px 3px rgb(30 30 30 / 50%);
text-align: right;
padding: 5px;
box-sizing: border-box;
transition: left 0.2s;
}
a {
display: block;
margin: 5px 0;
font-family: 'Segoe UI', monospace;
color: blue;
}
#open:target ~ nav {
left: 0;
}
#close:target ~ nav {
left: -150px;
}
<div id="open"></div>
<div id="close"></div>
<nav>
<a href="#open">Open</a>
<a href="#close">Close</a>
</nav>
它的工作方式是,首先,我们需要一些至少与我们的 nav
处于同一级别的元素,以便它们能够影响它。每个元素都有一个 id,锚标签可以将其用作目标。单击锚标记时,锚标记 href 中具有 id 的元素会触发其 :target
伪选择器。由于此示例中的目标元素是 nav
的兄弟元素,因此它们在目标时会影响其样式。 ~
只是一个兄弟选择器,它针对任何兄弟,而不仅仅是像 +
那样的相邻兄弟。