如何选择作为锚点元素的直接父级的 <li>
元素?
例如,我的 CSS 如下:
li < a.active {
property: value;
}
很明显可以用JavaScript做到这一点,但我希望存在CSS Level 2本身的解决方法。
我正在尝试样式化的菜单是由CMS生成的,所以我不能将活动元素移动到<li>
元素中...(除非我主题化菜单创建模块,但我宁愿不这样做)。
如何选择作为锚点元素的直接父级的 <li>
元素?
例如,我的 CSS 如下:
li < a.active {
property: value;
}
很明显可以用JavaScript做到这一点,但我希望存在CSS Level 2本身的解决方法。
我正在尝试样式化的菜单是由CMS生成的,所以我不能将活动元素移动到<li>
元素中...(除非我主题化菜单创建模块,但我宁愿不这样做)。
CSS父级选择器(也称为:has()选择器)已经在Safari TP 137中最终实现。该功能目前也正在Chrome中实现。(MDN文档)
通过伪类:has()
进行父级选择。例如,div:has(> .child)
将选择所有具有child
类的子元素的<div>
元素。
其他示例:
选择元素的直接父元素
<div>
<p>Child Element</p>
</div>
div:has(> p)
选择一个元素的所有父级元素
<div id="grandparent">
<div id="parent">
<div id="child"></div>
<div>
</div>
以下选择器将同时选择grandparent
和parent
。div:has(.child)
您还可以将其用于嵌套选择器,甚至与其他伪类一起使用:
div:has(> :nth-child(10))
其他有效的CSS运算符可以用来自定义查询。
关注caniuse.com/css-has了解浏览器兼容性。
document.querySelector('section:has(h1.heading1)').style.padding = 0
,但它可能尚未在所有浏览器中起作用。 - MetabolicUncaught DOMException: Document.querySelector: 'section:has(h1.heading1)' 不是一个有效的选择器
错误。 - CodeForGood简短的回答是 不行;在CSS中,我们目前没有父选择器
,但是如果您不必交换元素或类,第二个选项是使用JavaScript。类似这样:
var activeATag = Array.prototype.slice.call(document.querySelectorAll('a.active'));
activeATag.map(function(x) {
if(x.parentNode.tagName === 'LI') {
x.parentNode.style.color = 'red'; // Your property: value;
}
});
如果您在应用程序中使用jQuery,也可以使用更短的方式:
或者如果你在你的应用程序中使用 jQuery,这是更短的方法:
$('a.active').parents('li').css('color', 'red'); // Your property: value;
parentElement
,类似的东西 - 只需使用 document.getElementById().parentElement
等。 - Andrew从技术上讲,没有直接的方法来实现这一点。但是,您可以使用jQuery或JavaScript解决这个问题。
不过,您也可以像这样做。
a.active h1 {color: blue;}
a.active p {color: green;}
jQuery
$("a.active").parents('li').css("property", "value");
如果您想使用jQuery实现此操作,以下是jQuery parent选择器的参考文献。
$('section:has(h1.heading1)').css('padding', 0);
转换成纯JavaScript代码? - CodeForGood<
(与>
相反)^
(与[SPACE]
相反)axe目前处于相对早期的BETA开发阶段。
在此处查看演示:
.parent {
float: left;
width: 180px;
height: 180px;
margin-right: 12px;
background-color: rgb(191, 191, 191);
}
.child {
width: 90px;
height: 90px;
margin: 45px;
padding-top: 12px;
font-family: sans-serif;
text-align: center;
font-size: 12px;
background-color: rgb(255, 255, 0);
}
.child.using-axe < .parent {
background-color: rgb(255, 0, 0);
}
<div class="parent">
<div class="child"></div>
</div>
<div class="parent">
<div class="child using-axe">Here, the axe parent selector turns the outer square red.</div>
</div>
<script src="https://rouninmedia.github.io/axe/axe.js"></script>
在上面的例子中,<
是直接父选择器,因此
.child.using-axe < .parent
表示:
.child.using-axe
的任何直接父级,它是.parent
你也可以使用以下方式:
.child.using-axe < div
这将意味着:
.child.using-axe
的任何直接父级,它是一个div
</body>
之前包含<script src="https://rouninmedia.github.io/axe/axe.js"></script>
,以便在CSS样式中启用辅助功能选择器。 - RouninW3C排除了这样一个选择器,因为它对浏览器的性能会产生巨大的影响。
有什么想法吗?
如果CSS4在“向后走”方面添加一些钩子,那就会变得很花哨。但在那之前,我们可以(虽然不建议)使用checkbox
和/或radio
input
来打破通常连接事物的方式,并且通过这个方法允许CSS在其正常范围之外进行操作...
/* Hide things that may be latter shown */
.menu__checkbox__selection,
.menu__checkbox__style,
.menu__hidden {
display: none;
visibility: hidden;
opacity: 0;
filter: alpha(opacity=0); /* Old Microsoft opacity */
}
/* Base style for content and style menu */
.main__content {
background-color: lightgray;
color: black;
}
.menu__hidden {
background-color: black;
color: lightgray;
/* Make list look not so _listy_ */
list-style: none;
padding-left: 5px;
}
.menu__option {
box-sizing: content-box;
display: block;
position: static;
z-index: auto;
}
/* ▼ - \u2630 - Three Bars */
/*
.menu__trigger__selection::before {
content: '\2630';
display: inline-block;
}
*/
/* ▼ - Down Arrow */
.menu__trigger__selection::after {
content: "\25BC";
display: inline-block;
transform: rotate(90deg);
}
/* Customize to look more `select` like if you like */
.menu__trigger__style:hover,
.menu__trigger__style:active {
cursor: pointer;
background-color: darkgray;
color: white;
}
/**
* Things to do when checkboxes/radios are checked
*/
.menu__checkbox__selection:checked + .menu__trigger__selection::after,
.menu__checkbox__selection[checked] + .menu__trigger__selection::after {
transform: rotate(0deg);
}
/* This bit is something that you may see elsewhere */
.menu__checkbox__selection:checked ~ .menu__hidden,
.menu__checkbox__selection[checked] ~ .menu__hidden {
display: block;
visibility: visible;
opacity: 1;
filter: alpha(opacity=100); /* Microsoft!? */
}
/**
* Hacky CSS only changes based off non-inline checkboxes
* ... AKA the stuff you cannot unsee after this...
*/
.menu__checkbox__style[id="style-default"]:checked ~ .main__content {
background-color: lightgray;
color: black;
}
.menu__checkbox__style[id="style-default"]:checked ~ .main__content .menu__trigger__style[for="style-default"] {
color: darkorange;
}
.menu__checkbox__style[id="style-one"]:checked ~ .main__content {
background-color: black;
color: lightgray;
}
.menu__checkbox__style[id="style-one"]:checked ~ .main__content .menu__trigger__style[for="style-one"] {
color: darkorange;
}
.menu__checkbox__style[id="style-two"]:checked ~ .main__content {
background-color: darkgreen;
color: red;
}
.menu__checkbox__style[id="style-two"]:checked ~ .main__content .menu__trigger__style[for="style-two"] {
color: darkorange;
}
<!--
This bit works, but will one day cause troubles,
but truth is you can stick checkbox/radio inputs
just about anywhere and then call them by id with
a `for` label. Keep scrolling to see what I mean
-->
<input type="radio"
name="colorize"
class="menu__checkbox__style"
id="style-default">
<input type="radio"
name="colorize"
class="menu__checkbox__style"
id="style-one">
<input type="radio"
name="colorize"
class="menu__checkbox__style"
id="style-two">
<div class="main__content">
<p class="paragraph__split">
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
</p>
<input type="checkbox"
class="menu__checkbox__selection"
id="trigger-style-menu">
<label for="trigger-style-menu"
class="menu__trigger__selection"> Theme</label>
<ul class="menu__hidden">
<li class="menu__option">
<label for="style-default"
class="menu__trigger__style">Default Style</label>
</li>
<li class="menu__option">
<label for="style-one"
class="menu__trigger__style">First Alternative Style</label>
</li>
<li class="menu__option">
<label for="style-two"
class="menu__trigger__style">Second Alternative Style</label>
</li>
</ul>
<p class="paragraph__split">
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
这段代码看起来有点复杂,但是只使用CSS和HTML就可以在链接radio
/checkbox
input
和label
触发器的id
和for
属性时,从任何地方触摸和重新触摸除了body
和:root
以外的任何东西。可能会有人展示如何重新触摸它们。
还有一个额外的注意事项是,特定id
的input
只能使用一个,也就是说,第一个checkbox
/radio
处于切换状态... 但是多个标签可以都指向同一个input
,尽管这会使HTML和CSS看起来更加复杂。
...我希望有一种本地CSS Level 2的解决方法...
我不确定其他伪类,但是我记得在CSS 3之前使用:checked
,如果我没记错的话,它是像[checked]
这样的东西,这就是为什么你可以在上面的代码中找到它的原因。
.menu__checkbox__selection:checked ~ .menu__hidden,
.menu__checkbox__selection[checked] ~ .menu__hidden {
/* rules: and-stuff; */
}
对于像::after
和:hover
这样的内容,我不确定它们是在哪个CSS版本中首次出现。
总之,请不要在生产环境中使用这种方法,即使你很生气也不要。当然可以作为一个笑话,或者换句话说仅仅因为某件事情能够做到,并不意味着它应该这么做。
anchor
标记会激活其active
伪类事件。然后它只需隐藏自己,允许active
事件冒泡到父li
标记,然后重新设置样式并使用新样式显示其锚定子元素。子元素已经为父元素设置了样式。<ul>
<li class="listitem">
<a class="link" href="#">This is a Link</a>
</li>
</ul>
a
上的active
伪类应用这些样式,以便在链接被点击时重新设置父级li
标签的样式:a.link {
display: inline-block;
color: white;
background-color: green;
text-decoration: none;
padding: 5px;
}
li.listitem {
display: inline-block;
margin: 0;
padding: 0;
background-color: transparent;
}
/* When this 'active' pseudo-class event below fires on click, it hides itself,
triggering the active event again on its parent which applies new styles to itself and its child. */
a.link:active {
display: none;
}
.listitem:active {
background-color: blue;
}
.listitem:active a.link {
display: inline-block;
background-color: transparent;
}
转向
点击时。
不,你不能仅使用CSS选择父元素。
但是由于您已经有一个.active
类,将该类移动到li
(而不是a
)会更容易。这样您就可以仅使用CSS访问li
和a
。
至少在CSS3及之前的版本中,您不能像那样进行选择。 但是现在在JavaScript中很容易实现,您只需要添加一些基本的JavaScript代码即可,注意代码非常简短。
cells = document.querySelectorAll('div');
[].forEach.call(cells, function (el) {
//console.log(el.nodeName)
if (el.hasChildNodes() && el.firstChild.nodeName=="A") {
console.log(el)
};
});
<div>Peter</div>
<div><a href="#">Jackson link</a></div>
<div>Philip</div>
<div><a href="#">Pullman link</a></div>
目前仅在父元素内包含<input>
元素时,才能根据子元素更改父元素。当输入框获得焦点时,可以使用CSS影响其相应的父元素。
以下示例将帮助您了解如何在CSS中使用:focus-within
。
.outer-div {
width: 400px;
height: 400px;
padding: 50px;
float: left
}
.outer-div:focus-within {
background: red;
}
.inner-div {
width: 200px;
height: 200px;
float: left;
background: yellow;
padding: 50px;
}
<div class="outer-div">
<div class="inner-div">
I want to change outer-div(Background color) class based on inner-div. Is it possible?
<input type="text" placeholder="Name" />
</div>
</div>
The :focus-within CSS pseudo-class matches an element if the element or any of its descendants are focused.
It works with every element, not just input
- LS_
:has()
选择器的实现。 - TylerHel.parenteElement.parenteElement...
一致的工作方式,比如a:active:parent:parent
或者甚至是a::active::parent::parent
,用两个分号。这不仅更符合现有伪类的逻辑,而且更易于使用和链接,以便在需要时向上多级。我真的希望有这种实现,因为我真的很讨厌使用:has(something)
:它既没有逻辑性,也没有直观性和人体工程学可用性。JavaScript 的方式更好,远胜于 :has()。 - willy wonka