Есть ли способ выбрать родительский элемент на основе класса дочернего элемента в классе? Пример, который имеет отношение ко мне и связан с выводом HTML с помощью красивого плагина меню для http://drupal.org. Результат выглядит так:
<ul class = "menu">
<li>
<a class = "active">Active Page</a>
</li>
<li>
<a>Some Other Page</a>
</li>
</ul>
Мой вопрос в том, можно ли применить стиль к элементу списка, который содержит якорь с активным классом на нем. Очевидно, я бы предпочел, чтобы элемент списка был помечен как активный, но у меня нет контроля над создаваемым кодом. Я мог бы выполнять такие вещи с помощью javascript (на ум приходит JQuery), но мне было интересно, есть ли способ сделать это с помощью селекторов CSS.
Чтобы быть ясным, я хочу применить стиль к элементу списка, а не к привязке.
При поиске в Google у меня возникла противоположная проблема, и я столкнулся с этим вопросом, пытаясь выбрать дочерний элемент элемента, и это так же просто, как: #nav_sub li.active a
@Kieran, чтобы быть придирчивым, x y соответствует y, если это потомокx, а x>y соответствует y, если это ребенокx
В дополнение к приведенным очень полезным ответам я счел полезным посмотреть подробное описание селекторов css по следующему адресу: w3.org/TR/CSS2/selector.html
Есть уловка: parent в вашем css. касса stackoverflow.com/a/50657951/1249617
Там, где другие могут сказать вам еще нет или использовать JavaScript, я скажу вам, что но может быть любым способом трогать, кроме body и :root, откуда угодно с помощью только CSS и HTML. Однако я не можешь рекомендую это в производстве.
Хотелось бы, чтобы было несколько селекторов CSS, которые позволяют выбирать предков на основе потомков :(






К сожалению, с помощью CSS это невозможно.
Однако с JavaScript это не очень сложно:
// JavaScript code:
document.getElementsByClassName("active")[0].parentNode;
// jQuery code:
$('.active').parent().get(0); // This would be the <a>'s parent <li>.
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.
И для тех, кто будет искать SO в будущем, это также может называться селектором предков.
Обновлять:
Селекторы уровня 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-childHowever the following one represents an ordered list OL having a unique child, that child being a LI:
$OL > LI:only-childThe structures represented by these two selectors are the same, but the subjects of the selectors are not.
Хотя это недоступно (в настоящее время, ноябрь 2011 г.) ни в одном браузере или в качестве селектора в jQuery.
Спецификация CSS Selectors 4 теперь включает возможность для селекторов подниматься вверх. stackoverflow.com/q/1014958/392
К вашему сведению, MooTools уже пару лет поддерживает селекторы CSS уровня 4 - и, по иронии судьбы, механизм выбора Slick в MooTools действительно смог обработать эти селекторы еще до того, как был опубликован проект спецификации -> github.com/mootools/slick/wiki/…
@csuwldcat: Селектор темы обсуждается уже несколько лет, возможно, почти через десять лет после безмятежных дней CSS2.0. Но теперь, когда sel4 был обновлен для использования ! для выбора темы (через несколько месяцев после вашего комментария), эта реализация предварительно устарела / не соответствует требованиям / отключена / и т. д. Интересно, обновят ли они свою реализацию соответствующим образом или дождутся ее стабилизации.
Доступна ли сейчас спецификация CSS Selectors 4? (Декабрь 2012 г.)
Для тех, кто все еще смотрит на это, модуль уровня 4 действительно говорит, что селектор :has() (ранее $) доступен только в JavaScript, а не буду доступен в CSS. Это связано с однопроходной природой синтаксического анализатора CSS.
У меня была такая же проблема с Drupal. Учитывая ограничения CSS, способ заставить это работать - добавить «активный» класс к родительским элементам при генерации HTML меню. Это хорошее обсуждение на http://drupal.org/node/219804, результатом которого является то, что эта функциональность была добавлена в версию 6.x-2.x модуля nicemenus. Поскольку он все еще находится в разработке, я перенес патч на 6.x-1.3 в http://drupal.org/node/465738, чтобы я мог продолжать использовать готовую к производству версию модуля.
Опять поздно на вечеринку, но, несмотря на то, что стоит, можно использовать jQuery, чтобы быть немного более лаконичным. В моем случае мне нужно было найти родительский тег <ul> для тега <span>, содержащегося в дочернем <li>. jQuery имеет селектор :has, поэтому можно идентифицировать родителя по дочерним элементам, которые он содержит (обновлено в соответствии с комментарием @ Afrowave ref: https://api.jquery.com/has-selector/):
$("ul").has("#someId")
выберет элемент ul, у которого есть дочерний элемент с идентификатором someId. Или, чтобы ответить на исходный вопрос, что-то вроде следующего должно помочь (непроверено):
$("li").has(".active")
jQuery рекомендует изменить :has(selector) на $("li").has('active'). Я реализовал это в демонстрации @revoke JSFiddle выше. api.jquery.com/has-selector
Первый черновик Селекторы уровня 4 описывает способ явной установки предмет селектора. Это позволит OP стилизовать элемент списка с помощью селектора $li > a.active.
От Определение темы селектора:
For example, the following selector represents a list item LI unique child of an ordered list OL:
OL > LI:only-childHowever the following one represents an ordered list OL having a unique child, that child being a LI:
$OL > LI:only-childThe structures represented by these two selectors are the same, but the subjects of the selectors are not.
Обновлено: Учитывая, насколько «сквозняком» может быть черновик спецификации, лучше следить за этим, проверяя Страница CSSWG о селекторах 4-го уровня.
На самом деле я столкнулся с той же проблемой, что и исходный плакат. Существует простое решение - просто использовать селектор jQuery .parent(). Моя проблема заключалась в том, что я использовал .parent вместо .parent(). Я знаю глупую ошибку.
Свяжите события (в этом случае, поскольку мои вкладки находятся в модальном режиме, мне нужно было связать их с .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;
})
Вот 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>
Конечно, вы можете повторить этот шаблон ... с большим количеством LI.
Между прочим ... если шаблон сбивает вас с толку из-за того, что он не является стандартным шаблоном вкладки jQuery, то это потому, что нам пришлось создать его с нуля, чтобы он был доступен для чтения с экрана JAWS. Я скоро напишу об этом.
Еще одна мысль пришла мне в голову только что, что могло бы быть решением на чистом 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;
}
Для тех из вас, кто хочет использовать javascript без jquery ...
Выбор родителя тривиален. Вам нужна какая-то функция getElementsByClass, если вы не можете заставить свой плагин drupal назначать активному элементу идентификатор вместо класса. Функцию, которую я предоставил, я позаимствовал у другого гения на 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;
}
Поздно к вечеринке, но тем временем document.getElementsByClassName () стал широко доступным.
Новые спецификации CSS содержат экспериментальный псевдоселектор :has, который может делать это.
li:has(a:active) {
/* ... */
}
поддержка браузера для этого в основном не существует в настоящее время, но он учитывается в официальные спецификации.
Хотя верно, что CSS не может ASCEND, неверно, что вы не можете захватить родительский элемент другого элемента. Позвольте мне повторить:
Используя пример кода HTML, вы можете получить li без указания li
ul * a {
property:value;
}
В этом примере ul является родительским элементом некоторого элемента, а этот элемент является родительским элементом привязки. Обратной стороной использования этого метода является то, что если существует ul с любым дочерним элементом, содержащим якорь, он наследует указанные стили.
Вы также можете использовать дочерний селектор, так как вам все равно придется указать родительский элемент.
ul>li a {
property:value;
}
В этом примере якорь должен быть потомком li, который ДОЛЖЕН быть дочерним элементом ul, то есть он должен находиться в дереве, следующем за объявлением ul. Это будет немного более конкретным и будет захватывать только элемент списка, который содержит якорь И является дочерним элементом ul.
ТАК, чтобы ответить на ваш вопрос по коду.
ul.menu > li a.active {
property:value;
}
Это должно захватить ul с классом меню и элемент дочернего списка, который содержит только привязку с классом active.
К сожалению, это не отвечает на вопрос, поскольку информация о стиле будет применяться к тегу привязки, а не к тегу элемента списка. Проблема не в том, как использовать селекторы, а в том, как ВЫБРАТЬ элемент списка на основе класса дочернего элемента. Таким образом, ваш ответ по-прежнему будет выбирать только якоря с активным классом.
Прямо сейчас нет возможности выбрать родительский элемент в CSS (даже в CSS3). Но с CSS4 наиболее важной новостью в текущем проекте W3C является поддержка родительского селектора.
$ul li:hover{
background: #fff;
}
Используя вышеизложенное, при наведении курсора на элемент списка весь неупорядоченный список будет выделен путем добавления к нему белого фона.
Официальная документация: https://www.w3.org/TR/2011/WD-selectors4-20110929/#overview (последняя строка).
Согласно текущий проект текущий синтаксис - !subject > selector. Я нашел css4-selectors.com хорошим справочником по этому поводу. На момент написания этого комментария ни один браузер не поддерживает этот селектор.
Многие люди ответили с помощью родителя jQuery, но просто чтобы добавить к этому, я хотел поделиться быстрым фрагментом кода, который я использую для добавления классов в свои навигационные системы, чтобы я мог добавить стиль к li, у которых есть только подменю, а не li, которые не т.
$("li ul").parent().addClass('has-sub');
Точно такая же проблема с Telerik ASP.NET Rad Tabstrip Control ...