Комплексный селектор CSS для родителя активного ребенка [дубликат]

этот вопрос уже есть ответ здесь:

есть ли способ выбрать родительский элемент на основе класса дочернего элемента в классе? Пример, который актуален для меня, касающиеся вывода 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.

просто для ясности, я требуется применить стиль к элементу списка, а не к привязке.

10 ответов


к сожалению, нет способа сделать это с помощью CSS.

Это не очень сложно с JavaScript, хотя:

// JavaScript code:
document.getElementsByClassName("active")[0].parentNode;

// jQuery code:
$('.active').parent().get(0); // This would be the <a>'s parent <li>.

согласно Википедии:

селекторы не могут подняться

CSS не предлагает способа выбрать родителя или предка элемента, который удовлетворяет определенным критериям. Более продвинутая схема селектора (например, XPath) позволит использовать более сложные таблицы стилей. Однако основные причины отклонения рабочей группой CSS предложений по родительским селекторам связаны с производительностью браузера и инкрементным вопросы рендеринга.

и для тех, кто ищет так в будущем, это также может быть названо селектором предков.

обновление:

на Селекторы Уровень 4 Spec позволяет выбрать, какая часть select является предметом:

тема селектора может быть явно определена путем добавления знак доллара ( $ ) к одному из составных селекторов в селекторе. Хотя структура элемента, которую представляет селектор, является то же самое со знаком доллара или без него, указывая на предмет в этом способ может изменить, какой составной селектор представляет предмет в этом структура.

Пример 1:

например, следующий селектор представляет уникальный дочерний элемент списка LI упорядоченный список OL:

OL > LI:only-child

однако следующий представляет собой упорядоченный список OL с уникальным дочерним элементом, что ребенок будучи ли:

$OL > LI:only-child

структуры, представленные этими двумя селекторами, одинаковы, но субъекты селекторов-нет.

хотя это недоступно (в настоящее время, ноябрь 2011) в любом браузере или в качестве селектора в jQuery.


поздно на вечеринку снова, но для чего это стоит, можно использовать jQuery, чтобы быть немного более кратким. В моем случае мне нужно было найти <ul> Родительский тег для <span> тег, содержащийся в ребенке <li>. в jQuery есть :has селектор, чтобы можно было идентифицировать родителя по детям, которые он содержит (Обновлено в комментарии @Afrowave ref:https://api.jquery.com/has-selector/):

$("ul").has("#someId")

выберите ul элемент, имеющий дочерний элемент с id someId. Или ответить на исходный вопрос, что-то вроде следующего следует сделать трюк (непроверенных):

$("li").has(".active")

СЕЛЕКТОР" РОДИТЕЛЬСКИЙ"

прямо сейчас нет возможности выбрать родителя элемента в CSS (даже CSS3). Но с CSS4, наиболее важной новостью в текущем проекте W3C является поддержка родительского селектора.

$ul li:hover{
    background: #fff;
}

используя вышеизложенное, при наведении на элемент списка весь неупорядоченный список будет выделен путем добавления к нему белого фона.

официальной документации: https://www.w3.org/TR/2011/WD-selectors4-20110929/#overview (последняя строка).


первый вариант Селекторы Уровня 4 описывает способ явно указать теме селектора. Это позволит OP стилизовать элемент списка с помощью селектора $li > a.active

С определение предмета селектора:

например, следующий селектор представляет элемент списка LI уникальный дочерний элемент упорядоченного списка OL:

OL > LI:only-child

однако следующий представляет упорядоченный список OL с уникальным ребенком, который является LI:

$OL > LI:only-child

структуры, представленные этими двумя селекторами, одинаковы, но субъекты селекторов-нет.

Edit: учитывая, как" сквозняк " может быть черновой спецификацией, лучше всего следить за этим, проверяя страница CSSWG на селекторах уровня 4.


У меня была такая же проблема с Drupal. Учитывая ограничения CSS, способ получить эту работу-добавить "активный" класс к родительским элементам при создании HTML-меню. Есть хорошее обсуждение этого в http://drupal.org/node/219804, в результате чего эта функциональность была свернута до версии 6.x-2.x модуля nicemenus. Поскольку это все еще находится в разработке, я перевел патч на 6.x-1.3 at http://drupal.org/node/465738 чтобы я мог продолжать использовать готовую к производству версию модуля.


многие люди ответили с jQuery parent, но просто чтобы добавить к этому, я хотел поделиться быстрым фрагментом кода, который я использую для добавления классов в мои navs, чтобы я мог добавить стиль в li ' s, которые имеют только подменю, а не liэто не так.

$("li ul").parent().addClass('has-sub');

Я на самом деле столкнулся с той же проблемой, что и оригинальный плакат. Существует простое решение просто использовать .parent() селектор jQuery. Моя проблема заключалась в том, что я использовал .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>

конечно, вы можете повторить эту схему..с более ли


хотя верно, что CSS не может подняться, неверно, что вы не можете захватить родительский элемент другого элемента. Позвольте мне повторить:

используя код примера 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. Покажите свой активный класс как абсолютно позиционированный блок и установите его стиль, чтобы скрыть Родительский 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;
}