活动子项的父项的复杂 CSS 选择器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45004/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Complex CSS selector for parent of active child
提问by Deeksy
Is there a way to select a parent element based on the class of a child element in the class? The example that is relevant to me relating to HTML output by a nice menu plugin for http://drupal.org. The output renders like this:
有没有办法根据类中子元素的类来选择父元素?与我相关的示例与http://drupal.org的漂亮菜单插件的 HTML 输出相关。输出呈现如下:
<ul class="menu">
<li>
<a class="active">Active Page</a>
</li>
<li>
<a>Some Other Page</a>
</li>
</ul>
My question is whether or not it is possible to apply a style to the list item that contains the anchor with the active class on it. Obviously, I'd prefer that the list item be marked as active, but I don't have control of the code that gets produced. I could perform this sort of thing using javascript (JQuery springs to mind), but I was wondering if there is a way to do this using CSS selectors.
我的问题是是否可以将样式应用于包含带有活动类的锚点的列表项。显然,我更希望将列表项标记为活动,但我无法控制生成的代码。我可以使用 javascript 执行此类操作(我会想到 JQuery),但我想知道是否有办法使用 CSS 选择器来执行此操作。
Just to be clear, I want to apply a style to the list item, not the anchor.
为了清楚起见,我想将样式应用于列表项,而不是锚点。
采纳答案by Dave Ward
Unfortunately, there's no way to do that with CSS.
不幸的是,CSS 无法做到这一点。
It's not very difficult with JavaScript though:
不过使用 JavaScript 并不是很困难:
// JavaScript code:
document.getElementsByClassName("active")[0].parentNode;
// jQuery code:
$('.active').parent().get(0); // This would be the <a>'s parent <li>.
回答by Sam Hasler
Selectors are unable to ascend
CSS offers no way to select a parent or ancestor of element that satisfies certain criteria. A more advanced selector scheme (such as XPath) would enable more sophisticated stylesheets. However, the major reasons for the CSS Working Group rejecting proposals for parent selectors are related to browser performance and incremental rendering issues.
选择器无法上升
CSS 无法选择满足特定条件的元素的父元素或祖先元素。更高级的选择器方案(例如 XPath)将支持更复杂的样式表。但是,CSS 工作组拒绝父选择器提案的主要原因与浏览器性能和增量渲染问题有关。
And for anyone searching SO in future, this might also be referred to as an ancestor selector.
对于将来搜索 SO 的任何人,这也可能称为祖先选择器。
Update:
更新:
The Selectors Level 4 Specallows you to select which part of the select is the subject:
该选择器4级规格,您可以选择其中选择的部分是主题:
The subject of the selector can be explicitly identified by prepending a dollar sign ($) to one of the compound selectors in a selector. Although the element structure that the selector represents is the same with or without the dollar sign, indicating the subject in this way can change which compound selector represents the subject in that structure.
Example 1:
For example, the following selector represents a list item LI unique child of an ordered list OL:
OL > LI:only-child
However the following one represents an ordered list OL having a unique child, that child being a LI:
$OL > LI:only-child
The structures represented by these two selectors are the same, but the subjects of the selectors are not.
选择器的主题可以通过在选择器中的复合选择器之一前面添加美元符号 ($) 来明确标识。尽管选择器所代表的元素结构有无美元符号都是一样的,但是通过这种方式来指示主语可以改变哪个复合选择器代表该结构中的主语。
示例 1:
例如,以下选择器表示有序列表 OL 的列表项 LI 唯一子项:
OL > LI:only-child
然而,下面的表示一个有序列表 OL 有一个唯一的孩子,那个孩子是一个 LI:
$OL > LI:only-child
这两个选择器所代表的结构是相同的,但选择器的主体不同。
Although this isn't available (currently, November 2011) in any browser or as a selector in jQuery.
尽管这在任何浏览器中都不可用(目前,2011 年 11 月)或作为 jQuery 中的选择器。
回答by David Clarke
Late to the party again but for what it's worth it is possible using jQuery to be a little more succinct. In my case I needed to find the <ul>
parent tag for a <span>
tag contained in the child <li>
. jQuery has the :has
selector so it's possible to identify a parent by the children it contains (updated per @Afrowave's comment ref: https://api.jquery.com/has-selector/):
聚会又迟到了,但就其价值而言,使用 jQuery 可能会更简洁一些。就我而言,我需要为child 中包含<ul>
的<span>
标签找到父标签<li>
。jQuery 具有:has
选择器,因此可以通过它包含的子项来识别父项(根据 @Afrowave 的评论引用更新:https: //api.jquery.com/has-selector/ ):
$("ul").has("#someId")
will select the ul
element that has a child element with id someId. Or to answer the original question, something like the following should do the trick (untested):
将选择ul
具有 id someId子元素的元素。或者要回答原始问题,以下内容应该可以解决问题(未经测试):
$("li").has(".active")
回答by Praveen Kumar Purushothaman
THE “PARENT” SELECTOR
“父母”选择器
Right now, there is no option to select the parent of an element in CSS (not even CSS3). But with CSS4, the most important news in the current W3C draft is the support for the parent selector.
现在,没有选项可以选择 CSS 中元素的父元素(甚至 CSS3)。但是对于CSS4,当前 W3C 草案中最重要的消息是对父选择器的支持。
$ul li:hover{
background: #fff;
}
Using the above, when hovering an list element, the whole unordered list will be highlighted by adding a white background to it.
使用上面的方法,当鼠标悬停一个列表元素时,整个无序列表将通过添加一个白色背景来突出显示。
Official documentation: https://www.w3.org/TR/2011/WD-selectors4-20110929/#overview(last row).
官方文档:https: //www.w3.org/TR/2011/WD-selectors4-20110929/#overview(最后一行)。
回答by Brian
The first draft of Selectors Level 4outlines a way to explicitly set the subjectof a selector. This would allow the OP to style the list element with the selector $li > a.active
Selectors Level 4 的初稿概述了一种明确设置选择器主题的方法。这将允许 OP 使用选择器设置列表元素的样式$li > a.active
From Determining the Subject of a Selector:
从确定选择器的主题:
For example, the following selector represents a list item LI unique child of an ordered list OL:
OL > LI:only-child
However the following one represents an ordered list OL having a unique child, that child being a LI:
$OL > LI:only-child
The structures represented by these two selectors are the same, but the subjects of the selectors are not.
例如,以下选择器表示有序列表 OL 的列表项 LI 唯一子项:
OL > LI:only-child
然而,下面的表示一个有序列表 OL 有一个唯一的孩子,那个孩子是一个 LI:
$OL > LI:only-child
这两个选择器所代表的结构是相同的,但选择器的主体不同。
Edit: Given how "drafty" a draft spec can be, it's best to keep tabs on this by checking the CSSWG's page on selectors level 4.
编辑:鉴于草案规范的“草稿”程度,最好通过检查CSSWG 的选择器级别 4 页面来密切关注这一点。
回答by Matt Wagner
Future answer with CSS4 selectors
CSS4 选择器的未来答案
New CSS Specs contain an experimental :has
pseudo selector that might be able to do this thing.
新的 CSS 规范包含一个实验性的:has
伪选择器,它可能能够做到这一点。
li:has(a:active) {
/* ... */
}
The browser supporton this is basically non-existent at this time, but it is in consideration on the official specs.
该浏览器支持在这基本上是在这个时候不存在的,但考虑到对官方的规格。
Answer in 2012 that was wrong in 2012 and is even more wrong in 2018
2012 年的答案 2012 年错了,2018 年更错了
While it is true that CSS cannot ASCEND, it is incorrect that you cannot grab the parent element of another element. Let me reiterate:
虽然 CSS 确实不能 ASCEND,但不能抓取另一个元素的父元素是不正确的。让我重申:
Using your HTML example code, you are able to grab the li without specifying li
使用您的 HTML 示例代码,您可以在不指定 li 的情况下获取 li
ul * a {
property:value;
}
In this example, the ul is the parent of some element and that element is the parent of anchor. The downside of using this method is that if there is a ul with any child element that contains an anchor, it inherits the styles specified.
在这个例子中,ul 是某个元素的父元素,而那个元素是锚点的父元素。使用此方法的缺点是,如果 ul 包含任何包含锚点的子元素,它将继承指定的样式。
You may also use the child selector as well since you'll have to specify the parent element anyway.
您也可以使用子选择器,因为无论如何您都必须指定父元素。
ul>li a {
property:value;
}
In this example, the anchor must be a descendant of an li that MUST be a child of ul, meaning it must be within the tree following the ul declaration. This is going to be a bit more specific and will only grab a list item that contains an anchor AND is a child of ul.
在这个例子中,锚点必须是 li 的后代,而 li 必须是 ul 的孩子,这意味着它必须在 ul 声明之后的树中。这将更具体一点,并且只会抓取包含锚点并且是 ul 的子项的列表项。
SO, to answer your question by code.
所以,用代码回答你的问题。
ul.menu > li a.active {
property:value;
}
This should grab the ul with the class of menu, and the child list item that contains only an anchor with the class of active.
这应该获取具有菜单类的 ul,以及仅包含具有活动类的锚点的子列表项。
回答by ggedde
Many people answered with jQuery
parent, but just to add on to that I wanted to share a quick snippet of code that I use for adding classes to my navs so I can add styling to li
's that only have sub-menus and not li
's that don't.
许多人回答了jQuery
父母,但只是补充一点,我想分享一个快速的代码片段,我用来向导航添加类,这样我就可以将样式添加到li
只有子菜单的li
's而不是's that别。
$("li ul").parent().addClass('has-sub');
回答by John Drefahl
I actually ran into the same issue as the original poster. There is a simple solution of just using .parent()
jQuery selector. My problem was, I was using .parent
instead of .parent()
. Stupid mistake I know.
我实际上遇到了与原始海报相同的问题。有一个只使用.parent()
jQuery 选择器的简单解决方案。我的问题是,我使用的是.parent
而不是.parent()
. 愚蠢的错误我知道。
Bind the events (in this case since my tabs are in Modal I needed to bind them with .live
instead of a basic .click
.
绑定事件(在这种情况下,因为我的选项卡在 Modal 中,我需要将它们绑定到.live
而不是基本的.click
.
$('#testTab1 .tabLink').live('click', function() {
$('#modal ul.tabs li').removeClass("current"); //Remove any "current" class
$(this).parent().addClass("current"); //Add "current" class to selected tab
$('#modal div#testTab1 .tabContent').hide();
$(this).next('.tabContent').fadeIn();
return false;
})
$('#testTab2 .tabLink').live('click', function() {
$('#modal ul.tabs li').removeClass("current"); //Remove any "current" class
$(this).parent().addClass("current"); //Add "current" class to selected tab
$('#modal div#testTab2 .tabContent').hide();
$(this).next('.tabContent').fadeIn();
return false;
})
Here is the HTML..
这是 HTML ..
<div id="tabView1" style="display:none;">
<!-- start: the code for tabView 1 -->
<div id="testTab1" style="width:1080px; height:640px; position:relative;">
<h1 class="Bold_Gray_45px">Modal Header</h1>
<div class="tabBleed"></div>
<ul class="tabs">
<li class="current"> <a href="#" class="tabLink" id="link1">Tab Title Link</a>
<div class="tabContent" id="tabContent1-1">
<div class="modalCol">
<p>Your Tab Content</p>
<p><a href="#" class="tabShopLink">tabBased Anchor Link</a> </p>
</div>
<div class="tabsImg"> </div>
</div>
</li>
<li> <a href="#" class="tabLink" id="link2">Tab Title Link</a>
<div class="tabContent" id="tabContent1-2">
<div class="modalCol">
<p>Your Tab Content</p>
<p><a href="#" class="tabShopLink">tabBased Anchor Link</a> </p>
</div>
<div class="tabsImg"> </div>
</div>
</li>
</ul>
</div>
</div>
Of course you can repeat that pattern..with more LI's
当然,你可以重复那个模式……更多的 LI
回答by Mark B
I had the same problem with Drupal. Given the limitations of CSS, the way to get this working is to add the "active" class to the parent elements when the menu HTML is generated. There's a good discussion of this at http://drupal.org/node/219804, the upshot of which is that this functionality has been rolled in to version 6.x-2.x of the nicemenus module. As this is still in development, I've backported the patch to 6.x-1.3 at http://drupal.org/node/465738so that I can continue to use the production-ready version of the module.
我在使用 Drupal 时遇到了同样的问题。鉴于 CSS 的局限性,实现此功能的方法是在生成菜单 HTML 时将“active”类添加到父元素。在http://drupal.org/node/219804上对此进行了很好的讨论,其结果是该功能已被引入到 nicemenus 模块的 6.x-2.x 版中。由于这仍在开发中,我已将补丁移植到http://drupal.org/node/465738上的 6.x-1.3,以便我可以继续使用该模块的生产就绪版本。
回答by Jared
Another thought occurred to me just now that could be a pure CSS solution. Display your active class as an absolutely positioned block and set its style to cover up the parent li.
我刚刚想到的另一个想法可能是纯 CSS 解决方案。将您的活动类显示为绝对定位块,并将其样式设置为覆盖父 li。
a.active {
position:absolute;
display:block;
width:100%;
height:100%;
top:0em;
left:0em;
background-color: whatever;
border: whatever;
}
/* will also need to make sure the parent li is a positioned element so... */
ul.menu li {
position:relative;
}
For those of you who want to use javascript without jquery...
对于那些想在没有 jquery 的情况下使用 javascript 的人...
Selecting the parent is trivial. You need a getElementsByClass
function of some sort, unless you can get your drupal plugin to assign the active item an ID instead of Class. The function I provided I grabbed from some other genius on SO. It works well, just keep in mind when you're debugging that the function will always return an array of nodes, not just a single node.
选择父级是微不足道的。您需要某种getElementsByClass
功能,除非您可以让您的 drupal 插件为活动项目分配一个 ID 而不是 Class。我提供的功能是从 SO 上的其他一些天才那里获取的。它运行良好,只需在调试时记住该函数将始终返回节点数组,而不仅仅是单个节点。
active_li = getElementsByClass("active","a");
active_li[0].parentNode.style.whatever="whatever";
function getElementsByClass(node,searchClass,tag) {
var classElements = new Array();
var els = node.getElementsByTagName(tag); // use "*" for all elements
var elsLen = els.length;
var pattern = new RegExp("\b"+searchClass+"\b");
for (i = 0, j = 0; i < elsLen; i++) {
if ( pattern.test(els[i].className) ) {
classElements[j] = els[i];
j++;
}
}
return classElements;
}