Сложный селектор 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.

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

Точно такая же проблема с Telerik ASP.NET Rad Tabstrip Control ...

Juan Calero 11.05.2010 18:21

При поиске в Google у меня возникла противоположная проблема, и я столкнулся с этим вопросом, пытаясь выбрать дочерний элемент элемента, и это так же просто, как: #nav_sub li.active a

Kieran Andrews 18.10.2010 07:27

@Kieran, чтобы быть придирчивым, x y соответствует y, если это потомокx, а x>y соответствует y, если это ребенокx

MatrixFrog 20.01.2011 06:49

В дополнение к приведенным очень полезным ответам я счел полезным посмотреть подробное описание селекторов css по следующему адресу: w3.org/TR/CSS2/selector.html

green-i 13.09.2010 22:52

Есть уловка: parent в вашем css. касса stackoverflow.com/a/50657951/1249617

Ton 03.06.2018 11:13

Там, где другие могут сказать вам еще нет или использовать JavaScript, я скажу вам, что но может быть любым способом трогать, кроме body и :root, откуда угодно с помощью только CSS и HTML. Однако я не можешь рекомендую это в производстве.

S0AndS0 09.06.2019 08:42

Хотелось бы, чтобы было несколько селекторов CSS, которые позволяют выбирать предков на основе потомков :(

pouya 01.11.2020 00:50
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
329
7
328 845
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

Ответ принят как подходящий

К сожалению, с помощью 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-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.

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

Спецификация CSS Selectors 4 теперь включает возможность для селекторов подниматься вверх. stackoverflow.com/q/1014958/392

Dan Herbert 22.11.2011 21:22

К вашему сведению, MooTools уже пару лет поддерживает селекторы CSS уровня 4 - и, по иронии судьбы, механизм выбора Slick в MooTools действительно смог обработать эти селекторы еще до того, как был опубликован проект спецификации -> github.com/mootools/slick/wiki/…

csuwldcat 25.04.2012 21:57

@csuwldcat: Селектор темы обсуждается уже несколько лет, возможно, почти через десять лет после безмятежных дней CSS2.0. Но теперь, когда sel4 был обновлен для использования ! для выбора темы (через несколько месяцев после вашего комментария), эта реализация предварительно устарела / не соответствует требованиям / отключена / и т. д. Интересно, обновят ли они свою реализацию соответствующим образом или дождутся ее стабилизации.

BoltClock 19.10.2012 18:41

Доступна ли сейчас спецификация CSS Selectors 4? (Декабрь 2012 г.)

Sukanta Paul 12.12.2012 19:21

Для тех, кто все еще смотрит на это, модуль уровня 4 действительно говорит, что селектор :has() (ранее $) доступен только в JavaScript, а не буду доступен в CSS. Это связано с однопроходной природой синтаксического анализатора CSS.

jhpratt 22.08.2017 06:07

У меня была такая же проблема с 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")
Демо JSFiddle for testing...
revoke 08.10.2014 13:38

jQuery рекомендует изменить :has(selector) на $("li").has('active'). Я реализовал это в демонстрации @revoke JSFiddle выше. api.jquery.com/has-selector

Afrowave 25.09.2017 14:28

Первый черновик Селекторы уровня 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-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.

Обновлено: Учитывая, насколько «сквозняком» может быть черновик спецификации, лучше следить за этим, проверяя Страница 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. Я скоро напишу об этом.

John Drefahl 29.10.2011 05:23

Еще одна мысль пришла мне в голову только что, что могло бы быть решением на чистом 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 () стал широко доступным.

CONTRACT SAYS I'M RIGHT 14.04.2016 15:51

Будущий ответ с селекторами CSS4

Новые спецификации CSS содержат экспериментальный псевдоселектор :has, который может делать это.

li:has(a:active) {
  /* ... */
}

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


Ответ 2012 года, который был неправильным в 2012 году и еще более неправильным в 2018 году.

Хотя верно, что 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.

К сожалению, это не отвечает на вопрос, поскольку информация о стиле будет применяться к тегу привязки, а не к тегу элемента списка. Проблема не в том, как использовать селекторы, а в том, как ВЫБРАТЬ элемент списка на основе класса дочернего элемента. Таким образом, ваш ответ по-прежнему будет выбирать только якоря с активным классом.

Deeksy 14.06.2012 03:34

«РОДИТЕЛЬСКИЙ» СЕЛЕКТОР

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

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

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

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

Согласно текущий проект текущий синтаксис - !subject > selector. Я нашел css4-selectors.com хорошим справочником по этому поводу. На момент написания этого комментария ни один браузер не поддерживает этот селектор.

Rob Hall 16.06.2017 04:36

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

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

Другие вопросы по теме