Как выбрать элемент <li>, который является прямым родительским элементом элемента привязки?

Например, мой CSS будет примерно таким:

li < a.active {
    property: value;
}

Очевидно, есть способы сделать это с помощью JavaScript, но я надеюсь, что есть какое-то обходное решение, которое существует в CSS уровня 2.

Меню, которое я пытаюсь стилизовать, извергается CMS, поэтому я не могу переместить активный элемент в элемент <li> ... (если я не оформлю модуль создания меню, который я бы предпочел не делать).

Любые идеи?

3681
jcuenod 18 Июн 2009 в 23:59
2
Сегодня Safari Tech Preview 137 представила первая реализация селектора :has().
 – 
TylerH
21 Дек 2021 в 09:32
Скоро: хром!
 – 
Eliran Malka
24 Дек 2021 в 22:31

31 ответ

Лучший ответ

В настоящее время нет возможности выбрать родительский элемент в CSS.

Если бы и был способ сделать это, он был бы в любой из текущих спецификаций селекторов CSS:

При этом рабочий проект уровня 4 селекторов включает : has () псевдокласс, который предоставит эту возможность. Он будет похож на реализацию jQuery.

li:has(> a.active) { /* styles to apply to the li tag */ }

Однако по состоянию на 2021 год это все еще не поддерживается ни одним браузером .

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

2980
TylerH 21 Дек 2021 в 19:01
78
Казалось бы, это уже было предложено и отклонено: stackoverflow.com/questions/45004/…
 – 
RobM
27 Окт 2010 в 16:22
18
Похоже, селектор темы был пересмотрен, за исключением использования ! сейчас: The subject of the selector can be explicitly identified by appending an exclamation mark (!) to one of the compound selectors in a selector.
 – 
animuson
30 Янв 2012 в 01:30
16
Добавленный $ мне показался лучше ... добавленный ! легче не заметить.
 – 
Christoph
13 Фев 2012 в 15:25
56
Главный поворот сюжета! Selectors 4 WD только что был обновлен сегодня, чтобы исключить индикатор темы из быстрый профиль, который будет использоваться реализациями CSS. Если это изменение останется, это означает, что вы больше не сможете использовать индикатор темы в таблицах стилей (если только вы не добавите какой-либо полифилл, подобный описанному в другой ответ) - вы можете использовать его только с Selectors API и в любом другом месте, где может быть реализован полный профиль.
 – 
BoltClock
2 Май 2013 в 19:19
63
Еще одно крупное обновление: похоже, они рассматривают возможность полностью отказаться от синтаксиса селектора темы и заменить его псевдо-псевдо :has(), которое все знают и любят от jQuery. Последний ED удалил все ссылки на предметный индикатор и заменил его псевдо :has(). Я не знаю точных причин, но CSSWG некоторое время назад провела опрос, и результаты, должно быть, повлияли на это решение. Скорее всего, это связано с совместимостью с jQuery (чтобы он мог использовать qSA без изменений) и потому, что синтаксис индикатора объекта оказался слишком запутанным.
 – 
BoltClock
4 Май 2014 в 18:28

Как упоминалось несколькими другими, нет способа стилизовать родительский элемент / элементы с использованием только CSS, но следующее работает с jQuery:

$("a.active").parents('li').css("property", "value");
118
Alastair 2 Май 2013 в 09:11
23
Селектора < не существует (проверено с помощью jQuery 1.7.1).
 – 
Rob W
23 Фев 2012 в 21:53
7
Возможно, этот < - синтаксис работал в 2009 году, но я его обновил (на 2013 год).
 – 
Alastair
2 Май 2013 в 09:10
6
Еще лучше использовать встроенный в jQuery :has() селектор: $("li:has(a.active)").css("property", "value");. Он читается аналогично предложенному в CSS 4 селектору !. См. Также: :parent селектор, .parents() метод, .parent() метод.
 – 
Rory O'Kane
9 Май 2013 в 02:12
8
И вместо того, чтобы использовать .css("property", "value") для стилизации выбранных элементов, вы обычно должны .addClass("someClass") и иметь в своем CSS .someClass { property: value } (через). Таким образом, вы можете записать стиль со всей мощью CSS и любых препроцессоров, которые вы используете.
 – 
Rory O'Kane
9 Май 2013 в 02:20

Родительского селектора нет; точно так же, как нет предыдущего селектора братьев и сестер. Одна из веских причин отсутствия этих селекторов заключается в том, что браузер должен пройти через всех дочерних элементов элемента, чтобы определить, следует ли применять класс. Например, если вы написали:

body:contains-selector(a.active) { background: red; }

Затем браузеру придется подождать, пока он загрузится, и проанализировать все до </body>, чтобы определить, должна ли страница быть красной или нет.

Статья Почему у нас нет родительского селектора подробно это объясняет.

82
Peter Mortensen 25 Июл 2019 в 01:29
14
Так сделайте браузер быстрее. сам интернет быстрее. этот селектор определенно необходим, и причина, по которой он не реализован, к сожалению, потому что мы живем в медленном, примитивном мире.
 – 
vsync
20 Фев 2014 в 01:33
13
На самом деле, селектор сделал бы очень быстрый браузер медленным.
 – 
Salman A
20 Фев 2014 в 08:09
7
Я верю, что разработчики браузеров придумают реализацию, которая (по крайней мере) так же быстра, как и версия javascript, которую люди все равно используют.
 – 
Marc.2377
9 Июн 2018 в 03:15
1
@ Marc.2377 Если вы попробуете приведенный выше пример в JS на своем сайте, я никогда не буду его посещать. С другой стороны, я бы сказал, что большую часть времени вы заботитесь только о непосредственных детях, поэтому, если бы это ограничивалось только непосредственными детьми, это было бы хорошим дополнением без особого воздействия.
 – 
xryl669
7 Сен 2019 в 15:41

В CSS 2 нет способа сделать это. Вы можете добавить класс в li и сослаться на a:

li.active > a {
    property: value;
}
62
Peter Mortensen 25 Июл 2019 в 01:19
3
Сделав элемент display: block, вы можете оформить его так, чтобы он соответствовал всей области li. если вы можете объяснить, какой стиль вы ищете, возможно, я мог бы помочь с решением.
 – 
Josh
19 Июн 2009 в 01:53
На самом деле это простое и элегантное решение, и во многих случаях имеет смысл установить класс на родительский.
 – 
Ricardo
19 Мар 2016 в 02:17

Псевдоэлемент :focus-within позволяет выбрать родителя, если у потомка есть фокус.

Элемент может быть сфокусирован, если у него есть атрибут tabindex.

Поддержка браузера для фокусировки внутри

Табиндекс

Пример

.parent:focus-within {
  background: hsl(199deg, 65%, 73%);
}

/* demo styles */
body {
  margin: 0;
}
.parent {
  background: hsl(0, 0%, 80%);
  min-height: 100vh;
  display: grid;
  place-content: center;
}
.child {
  background: hsl(0, 0%, 0%);
  color: white;
  padding: 3rem;
  outline: 0;
  cursor: pointer;
  font: 18px/1.25 sans-serif;
  width: 20ch;
}
<div class="parent">
  <div class="child" tabindex="1">
    Click or Focus on me, my parent will change.
  </div>
</div>
44
sol 21 Авг 2021 в 12:55
2
В моем случае это отлично работает, спасибо! Просто нет, пример будет более наглядным, если вы измените цвет на родительский, а не на родственный, это заменит .color:focus-within .change на .color:focus-within. В моем случае я использую загрузочную панель навигации, которая добавляет класс к дочерним элементам, когда они активны, и я хочу добавить класс к родительской панели .nav. Я думаю, что это довольно распространенный сценарий, когда я владею разметкой, но компонент css + js является загрузочным (или другим), поэтому я не могу изменить поведение. Хотя я могу добавить tabindex и использовать этот css. Спасибо!
 – 
cancerbero
29 Июн 2018 в 18:13

Селектор CSS «General Sibling Combinator» может быть использован для ты хочешь:

E ~ F {
    property: value;
}

Это соответствует любому элементу F, которому предшествует элемент E.

31
Cody Gray 23 Авг 2017 в 15:27

Насколько мне известно, не в CSS 2. CSS 3 имеет более надежные селекторы, но не во всех браузерах единообразно. Я не верю, что даже с улучшенными селекторами он выполнит именно то, что вы указали в своем примере.

26
Mark Hurd 19 Июн 2009 в 00:09

Я знаю, что OP искал решение CSS, но этого легко добиться с помощью jQuery. В моем случае мне нужно было найти родительский тег <ul> для тега <span>, содержащегося в дочернем <li>. jQuery имеет селектор :has, поэтому можно идентифицировать родителя по дочерним элементам, которые он содержит:

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

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

$("li:has(.active)")
23
David Clarke 17 Май 2013 в 02:04
3
Или используйте $yourSpan.closest("ul"), и вы получите родительский UL вашего элемента span. Тем не менее ваш ответ полностью оффтопен imho. Мы можем ответить на все вопросы с тегами CSS с помощью решения jQuery.
 – 
Robin van Baalen
18 Июл 2013 в 21:40
1
Как указывалось в других ответах, нет способа сделать это с помощью CSS 2. Учитывая это ограничение, ответ, который я предоставил, является одним из тех, которые я знаю, является эффективным и является самым простым способом ответить на вопрос с использованием javascript imho.
 – 
David Clarke
19 Дек 2015 в 22:27
Учитывая ваши голоса, некоторые люди согласны с вами. Но единственный ответ остается принятым; просто и ясно "это не может быть сделано так, как вы этого хотите". Если вопрос заключается в том, как собрать 60 миль в час на велосипеде, а вы отвечаете «просто: садитесь в машину и нажимайте на газ», это все равно не ответ. Отсюда мой комментарий.
 – 
Robin van Baalen
19 Дек 2015 в 22:36
1
Такой подход сделает SO почти полностью бесполезным. Я ищу так, чтобы решить проблемы, а не найти «единственный ответ» не решает проблему. Вот почему ТАК такой классный, потому что у кошки всегда есть более одного способа.
 – 
David Clarke
20 Дек 2015 в 21:35

Это наиболее обсуждаемый аспект спецификации Селекторы уровня 4 . При этом селектор сможет стилизовать элемент в соответствии с его дочерним элементом, используя восклицательный знак после данного селектора (!).

Например:

body! a:hover{
   background: red;
}

Установит красный цвет фона, если пользователь наводит курсор на любую привязку.

Но надо дождаться реализации браузеров :(

23
Peter Mortensen 25 Июл 2019 в 01:33

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

a.active h1 {color:red;}

a.active:hover h1 {color:green;}

a.active h2 {color:blue;}

a.active:hover h1 {color:yellow;}

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

23
TylerH 16 Апр 2020 в 00:17
1
Это правильно, но ограничивает код разметки в теге a только определенными элементами, если вы хотите соответствовать стандартам XHTML. Например, вы не можете использовать div в a, не получив предупреждения о нарушении схемы.
 – 
Ivaylo Slavov
24 Июл 2012 в 22:22
2
Совершенно верно Ивайло! «a» не является блочным элементом, поэтому не может использовать внутри него блочные элементы.
 – 
riverstorm
13 Дек 2012 в 02:34
1
В HTML5 прекрасно размещать блочные элементы внутри ссылок.
 – 
Matthew James Taylor
6 Апр 2014 в 11:47
2
... если бы это было семантически неправильно, они бы не допустили этого в HTML5, где это было раньше.
 – 
BoltClock
28 Дек 2015 в 18:54

Вот хак с использованием pointer-events с hover:

<!doctype html>
<html>
    <head>
        <title></title>
        <style>
/* accessory */
.parent {
    width: 200px;
    height: 200px;
    background: gray;
}
.parent, 
.selector {
    display: flex;
    justify-content: center;
    align-items: center;
}
.selector {
    cursor: pointer;
    background: silver;
    width: 50%;
    height: 50%;
}
        </style>
        <style>
/* pertinent */
.parent {
    background: gray;
    pointer-events: none;
}
.parent:hover {
    background: fuchsia;
}
.parent 
.selector {
    pointer-events: auto;
}
        </style>
    </head>
    <body>
        <div class="parent">
            <div class="selector"></div>
        </div>
    </body>
</html>
20
Jan Kyu Peblik 3 Окт 2020 в 10:57

Идея горизонтального меню ...

Часть HTML

<div class='list'>
  <div class='item'>
    <a>Link</a>
  </div>
  <div class='parent-background'></div>
  <!-- submenu takes this place -->
</div>

Часть CSS

/* Hide parent backgrounds... */
.parent-background {
  display: none; }

/* ... and show it when hover on children */
.item:hover + .parent-background {
  display: block;
  position: absolute;
  z-index: 10;
  top: 0;
  width: 100%; }

Обновленная демонстрация и остальной код

Другой пример того, как использовать его с вводом текста - выберите родительский набор полей

15
Community 20 Июн 2020 в 12:12
3
Мне совсем не ясно, как вы хотите обобщить это для некоторых / многих / большинства случаев использования родительского селектора, или даже точно, какие части этого CSS-кода делают что. Можете ли вы добавить подробное объяснение?
 – 
Nathan Tuggy
28 Окт 2015 в 10:57
2
Я не пытался применить это к сценариям реального мира, поэтому я говорю «Не для производства». Но я думаю, что это можно применить к 2-уровневому меню только с фиксированной шириной элемента. «какие части этого CSS делают, что» - здесь .test-sibling фактически является фоном родительского элемента (последняя строка CSS).
 – 
Ilya B.
28 Окт 2015 в 11:08
2
Добавлено объяснение (раздел css в jsfiddle, начиная с «MAIN PART») ... И я ошибся - может быть любое количество подуровней.
 – 
Ilya B.
28 Окт 2015 в 15:59

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

Здесь много технических объяснений.

Джонатан Снук объясняет, как оценивается CSS.

Крис Койер о разговорах о родительском селекторе.

Гарри Робертс снова о написании эффективных селекторов CSS.

Но Николь Салливан поделился некоторыми интересными фактами о положительных тенденциях..

Все эти люди высшего класса в области фронтенд-разработки.

14
Nathan Tuggy 2 Ноя 2017 в 03:38
12
need определяется требованиями веб-разработчиков, включение его в спецификацию зависит от других факторов.
 – 
nicodemus13
15 Май 2014 в 13:04

Есть плагин, который расширяет CSS и включает некоторые нестандартные функции, которые действительно могут помочь при разработке веб-сайтов. Это называется EQCSS.

Одна из вещей, добавленных EQCSS, - это родительский селектор. Он работает во всех браузерах, начиная с Internet Explorer 8 и выше. Вот формат:

@element 'a.active' {
  $parent {
    background: red;
  }
}

Итак, здесь мы открыли элементный запрос для каждого элемента a.active, и для стилей внутри этого запроса такие вещи, как $parent, имеют смысл, потому что есть точка отсчета. Браузер может найти родительский объект, потому что он очень похож на parentNode в JavaScript.

Вот демонстрация $parent и еще одна $parent демонстрация, которая работает в Internet Explorer 8, а также снимок экрана на случай, если у вас нет Internet Explorer 8 для тестирования.

EQCSS также включает мета-селекторы: $prev для элемента перед выбранным элементом и $this только для тех элементов, которые соответствуют запросу элемента, и т. Д.

14
Peter Mortensen 25 Июл 2019 в 01:43

Технически прямого способа сделать это нет. Однако вы можете разобраться с этим с помощью jQuery или JavaScript.

Однако вы тоже можете сделать что-то подобное.

a.active h1 {color: blue;}
a.active p {color: green;}

jQuery

$("a.active").parents('li').css("property", "value");

Если вы хотите добиться этого с помощью jQuery, вот ссылка на родительский селектор jQuery .

11
Peter Mortensen 25 Июл 2019 в 01:36

Короткий ответ: НЕТ . на данном этапе у нас нет parent selector в 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 :

$('a.active').parents('li').css('color', 'red'); // Your property: value;
11
Peter Mortensen 25 Июл 2019 в 01:45
Или parentElement, самешинг - просто document.getElementById().parentElement и т. д.
 – 
Andrew
11 Авг 2020 в 23:04

Сейчас 2019 год, и в последней версии модуля CSS Nesting действительно есть что-то вроде этого. . Представляем @nest at-rules.

3.2. Правило вложенности: @nest

Хотя прямое гнездование выглядит красиво, оно несколько хрупкое. Некоторые допустимые селекторы вложенности, такие как .foo &, запрещены, и изменение селектора определенными способами может неожиданно сделать правило недействительным. Кроме того, некоторым людям сложно визуально отличить вложенность от окружающих деклараций.

Чтобы помочь во всех этих проблемах, эта спецификация определяет правило @nest, которое налагает меньше ограничений на то, как правильно размещать правила стиля. Его синтаксис:

@nest = @nest <selector> { <declaration-list> }

Правило @nest работает так же, как правило стиля: оно начинается с селектора и содержит объявления, которые применяются к элементам, которым соответствует селектор. Единственное отличие состоит в том, что селектор, используемый в правиле @nest, должен содержать вложение, что означает, что он где-то содержит селектор вложенности. Список селекторов содержит вложения, если все его отдельные сложные селекторы содержат вложения.

(Скопируйте и вставьте из URL выше).

Пример допустимых селекторов в соответствии с этой спецификацией:

.foo {
  color: red;
  @nest & > .bar {
    color: blue;
  }
}
/* Equivalent to:
   .foo { color: red; }
   .foo > .bar { color: blue; }
 */

.foo {
  color: red;
  @nest .parent & {
    color: blue;
  }
}
/* Equivalent to:
   .foo { color: red; }
   .parent .foo { color: blue; }
 */

.foo {
  color: red;
  @nest :not(&) {
    color: blue;
  }
}
/* Equivalent to:
   .foo { color: red; }
   :not(.foo) { color: blue; }
 */
12
Community 20 Июн 2020 в 12:12

Любые идеи?

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;
}

/* &#9660; - \u2630 - Three Bars */
/*
.menu__trigger__selection::before {
  content: '\2630';
  display: inline-block;
}
*/

/* &#9660; - 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 можно коснуться и повторно коснуться чего угодно, кроме body и :root практически из любого места, связав Свойства id и for триггеров radio / checkbox input и label ; вероятно, в какой-то момент кто-то покажет, как их повторно коснуться.

Еще одно предостережение: может быть использован только один input из определенного id, первый checkbox / radio побеждает иными словами, переключенное состояние ... Но все несколько ярлыков могут указывать на один и тот же input, хотя это сделало бы и HTML, и CSS еще грубее.


... Я надеюсь, что есть какое-то обходное решение, которое существует в CSS уровня 2 ...

Я не уверен насчет других псевдоклассов, но я :checked для pre-CSS 3. Если я правильно помню, это было что-то вроде [checked], поэтому вы можете найти его в приведенном выше коде для пример,

.menu__checkbox__selection:checked ~ .menu__hidden,
.menu__checkbox__selection[checked] ~ .menu__hidden {
 /* rules: and-stuff; */
}

... но для таких вещей, как ::after и :hover, я совершенно не уверен, в какой версии CSS они появились впервые.

С учетом всего сказанного, пожалуйста, никогда не используйте это в продакшене, даже в гневе. Конечно, в шутку или, другими словами, просто потому, что что-то можно сделать, не всегда означает, что это должно .

4
S0AndS0 18 Сен 2020 в 20:55
1
«CSS4» никогда не планировался, и даже CSS3 был объединен в просто «CSS» задолго до 2019 года.
 – 
TylerH
12 Авг 2021 в 17:43
Тайлер CSS4 рассматривается теми, кто поддерживает эту спецификацию. Ссылка объявления → w3.org/community/css4 Ссылка для обсуждения → github.com/w3c/csswg-drafts/issues/4770
 – 
S0AndS0
13 Авг 2021 в 18:44
Это просто название дискуссионной группы. Технологии под названием CSS4 не будет. Модули CSS имеют независимую версию версий уже много лет. Поскольку фактические участники CSSWG в запросе GitHub этого случайного пользователя уже ответили < i> и написал отзыв о , это плохая идея. К тому же этот запрос был мертв уже больше года (вы можете видеть, что учетная запись GH w3c удаляла недавние комментарии от сторонников, пытаясь его отключить).
 – 
TylerH
13 Авг 2021 в 19:04
Эта статья выражает мнение, и в целом отвлекает от обсуждения спецификации. Несколько помеченных не по теме комментариев и один удаленный комментарий не имеют отношения к necro , и я ожидаю, что Проблема будет помечена как Закрытая, если рабочая группа намерена прекратить обсуждение CSS4. Это нормально, и это хорошо для больших проектов, что версии модулей контролируются независимо; версии модуля не конфликтуют со спецификацией версий.
 – 
S0AndS0
13 Авг 2021 в 19:56
1
Это мнение одного из участников CSSWG, экстраполирующего ее ответ «нет» на запрос GitHub, в котором языки неактивны более года. Можно с уверенностью сказать, что он не продвигается вперед. Версии модуля будут сильно конфликтовать со спецификациями версий, как это видно из нескольких комментариев в теме. Послушайте, как бы вы ни хотели, чтобы это было вещью, это не так. Важно принять это и не вводить читателей в заблуждение упоминанием несуществующих вещей.
 – 
TylerH
13 Авг 2021 в 21:41

Хотя в настоящее время в стандартном CSS нет родительского селектора, я работаю над (личным) проектом под названием ax (т. Е. расширенный синтаксис селектора CSS / ACSSSS ), который, среди прочего, его 7 новых селекторов включают в себя:

  1. селектор непосредственного родителя < (который включает выбор, противоположный >)
  2. селектор любого предка ^ (который включает выбор, противоположный [SPACE])

ax в настоящее время находится на относительно ранней стадии бета-разработки.

Смотрите демонстрацию здесь:

.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

9
Rounin 8 Авг 2021 в 14:48
3
В настоящее время проект находится на ранней стадии бета-тестирования. Вы можете (по крайней мере в настоящее время) активировать селекторы ax в стилях CSS, включив <script src="https://rouninmedia.github.io/axe/axe.js"></script> в самом конце вашего html-документа, непосредственно перед </body>.
 – 
Rounin
12 Июл 2017 в 19:40

W3C исключил такой селектор из-за огромного влияния на производительность браузера.

11
rgb 16 Авг 2011 в 08:43
29
Ложный. поскольку DOM - это дерево, они должны перейти к родителю, прежде чем перейти к потомку, поэтому просто вернитесь на один узел назад. o.o
 – 
NullVoxPopuli
10 Ноя 2011 в 20:56
9
Селекторы CSS представляют собой очередь, поэтому порядок выбора, а не иерархия XPath или DOM документа.
 – 
Paul Sweatte
18 Авг 2012 в 20:14
4
По крайней мере, так они нам сказали.
 – 
yunzen
16 Апр 2013 в 19:35

По крайней мере, до CSS 3 включительно вы не можете так выбрать. Но в настоящее время это можно сделать довольно легко с помощью 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>
5
Peter Mortensen 25 Июл 2019 в 01:50

Нет, вы не можете выбрать родителя только в CSS.

Но поскольку у вас уже есть класс .active, было бы проще переместить этот класс в li (вместо a). Таким образом, вы можете получить доступ как к li, так и к a только через CSS.

4
Peter Mortensen 25 Июл 2019 в 01:40

Я бы нанял для этого код JavaScript. Например, в React, когда вы перебираете массив, добавьте еще один класс к родительскому компоненту, что указывает на то, что он содержит ваших дочерних элементов:

<div className={`parent ${hasKiddos ? 'has-kiddos' : ''}`}>
    {kiddos.map(kid => <div key={kid.id} />)}
</div>

А потом просто:

.parent {
    color: #000;
}

.parent.has-kiddos {
    color: red;
}
2
Damiano 2 Янв 2020 в 18:41

Попробуй это...

Это решение использует простые правила CSS2 без Javascript и работает во всех браузерах, как старых, так и новых . При нажатии дочерний тег anchor активирует событие псевдокласса active. Затем он просто скрывается, позволяя событию active всплывать в родительский тег li, который затем изменяет свой стиль и снова открывает своего дочернего якоря в новом стиле. Ребенок стилизовал родителя.

Используя ваш пример:

<ul>
    <li class="listitem">
        <a class="link" href="#">This is a Link</a>
    </li>
</ul>

Теперь примените эти стили с псевдоклассом active на a, чтобы изменить стиль родительского тега 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;
}

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

enter image description here

Превращается в

enter image description here

По щелчку.

3
Stokely 1 Мар 2021 в 20:35

Изменение родительского элемента на основе дочернего элемента в настоящее время может происходить только тогда, когда у нас есть элемент <input> внутри родительского элемента. Когда вход получает фокус, соответствующий родительский элемент может быть затронут с помощью CSS.

Следующий пример поможет вам понять использование :focus-within в CSS.

.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>
4
VFDan 7 Июл 2019 в 03:56
The :focus-within CSS pseudo-class matches an element if the element or any of its descendants are focused. Он работает со всеми элемент, а не только input
 – 
LS_
6 Сен 2021 в 18:36

Я не думаю, что вы можете выбрать родителя только в CSS.

Но поскольку у вас уже есть класс .active, было бы проще переместить этот класс в li (вместо a). Таким образом, вы можете получить доступ как к li, так и к a только через CSS.

170
Peter Mortensen 25 Июл 2019 в 01:21
4
Вы не можете сместить псевдоселектор на элемент списка, поскольку он не является фокусируемым элементом. Он использует селектор: active, поэтому, когда привязка активна, он хочет, чтобы элемент списка был затронут. Элементы списка никогда не будут в активном состоянии. Кроме того, к сожалению, такого селектора не существует. Получение чистого CSS-меню, которое полностью доступно с клавиатуры, кажется невозможным без него (используя селекторы одноуровневых элементов, вы можете создавать подменю, созданные с использованием вложенных списков, но как только список получает фокус, он снова становится скрытым). Если есть какие-либо CSS-решения для этого конкретного conun
 – 
user914183
26 Авг 2011 в 17:46
15
Aquilina Взгляните на вопрос, OP использует класс, а не псевдоселектор.
 – 
jeroen
26 Авг 2011 в 18:34

Да: :has()

Поддержка браузера: нет

246
RockPaperLz- Mask it or Casket 10 Июн 2020 в 13:20
1
Как отметил @Rodolfo Хорхе Немер Ногейра, это возможно с помощью sass (scss), используя знак &. Затем он компилируется в желаемый CSS. Было бы неплохо, если бы следующая версия css поддерживала &
 – 
TamusJRoyce
5 Авг 2020 в 14:48
3
На самом деле, я думаю, что есть экспериментальный синтаксис, эквивалентный синтаксису Эндрю заявление: @supports selector(:has(a))
 – 
xdhmoore
24 Окт 2020 в 00:38

Родительский селектор, также известный как has-selector , наконец-то появился в Safari TP 137. Пока идет работа над его реализацией в Chrome. (Документация по MDN)

Родительский выбор выполняется с помощью псевдокласса :has(), например div:has(> .child) выберет все элементы <div> с дочерним элементом, имеющим имя класса .child

Другие примеры:

Выбор прямого родителя элемента

<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 на предмет совместимости с браузером.

2
Metabolic 23 Дек 2021 в 15:27

Вы можете использовать этот скрипт:

*! > input[type=text] { background: #000; }

Это выберет любого родителя текстового ввода. Но подождите, это еще не все. При желании можно выбрать указанного родителя:

.input-wrap! > input[type=text] { background: #000; }

Или выберите его, когда он активен:

.input-wrap! > input[type=text]:focus { background: #000; }

Посмотрите этот HTML:

<div class="input-wrap">
    <input type="text" class="Name"/>
    <span class="help hide">Your name sir</span>
</div>

Вы можете выбрать этот span.help, когда input активен, и показать его:

.input-wrap! .help > input[type=text]:focus { display: block; }

Есть еще много возможностей; просто ознакомьтесь с документацией плагина.

Кстати, это работает в Internet Explorer.

144
Peter Mortensen 25 Июл 2019 в 01:24
5
Предположим, что использование jquery patent() будет быстрее. Однако это требует тестирования.
 – 
Dan
22 Сен 2011 в 23:30
2
Он не работает, если у вас есть объявление CSS объекта селектора без дочернего селектора (только #a! вызывает ошибку, #a! p работает), и поэтому другие не будут работать из-за Uncaught TypeError: Cannot call method 'split' of undefined: см. jsfiddle.net/HerrSerker/VkVPs
 – 
yunzen
16 Апр 2013 в 19:33
4
Я думаю #a! является недопустимым селектором, что следует выбрать?
 – 
Idered
17 Апр 2013 в 17:41
2
Я не знаю. В спецификации не говорится, что это незаконно. #a! должен выбрать сам. По крайней мере, у них не должно быть ошибок в JavaScript.
 – 
yunzen
17 Апр 2013 в 19:31
5
Согласно моему комментарию к принятому ответу, похоже, что полифил может потребоваться даже в ближайшем будущем, потому что индикатор темы никогда не может быть реализован браузерами в CSS.
 – 
BoltClock
2 Май 2013 в 19:35

Попробуйте переключить a на отображение block, а затем используйте любой стиль, который хотите. Элемент a заполнит элемент li, и вы сможете изменить его внешний вид по своему усмотрению. Не забудьте установить отступ li равным 0.

li {
  padding: 0;
  overflow: hidden;
}
a {
  display: block;
  width: 100%;
  color: ..., background: ..., border-radius: ..., etc...
}
a.active {
  color: ..., background: ...
}
37
Peter Mortensen 25 Июл 2019 в 01:25

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

3
Dmitry Sokolov 31 Янв 2020 в 18:53