it-swarm.com.ru

Есть ли родительский селектор CSS?

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

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

li < a.active {
    property: value;
}

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

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

Есть идеи?

2829
jcuenod

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

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

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


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

Используя :has(), оригинальный вопрос можно решить с помощью этого:

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

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

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

143
jeroen

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

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

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

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

114
Idered

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

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

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

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

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

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

60
Salman A

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

li.active > a {
    property: value;
}
50
Josh

да: :has()

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

34
Yukulélé

Попробуйте переключить 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: ...
}
33
Raseko

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

E ~ F {
    property: value;
}

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

32
cobaasta

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

25
Mark Hurd

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

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

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

$("li:has(.active)")
23
David Clarke

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

Например:

body! a:hover{
   background: red;
}

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

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

20
Marco Allori

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

a.active h1 {color:red;}

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

a.active h2 {color:blue;}

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

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

19
riverstorm

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

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

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

TabIndex

Пример

.click {
  cursor: pointer;
}

.color:focus-within .change {
  color: red;
}

.color:focus-within p {
  outline: 0;
}
<div class="color">
  <p class="change" tabindex="0">
    I will change color
  </p>
  <p class="click" tabindex="1">
    Click me
  </p>
</div>
18
sol

Кто-нибудь предлагал что-то подобное? Просто идея для горизонтального меню ...

часть 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%; }

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

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

13
Ilya B.

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

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

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

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

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

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

Эти люди все высшего класса в области разработки переднего плана.

13
Suraj Naik

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

EQCSS добавляет родительский селектор. Работает во всех браузерах IE8 и выше. Вот формат:

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

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

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

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

12
innovati

Технически нет прямого способа сделать это, однако, вы можете отсортировать это с помощью jquery или javascript.

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

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

JQuery

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

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

11
Prabhakar

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

9
rgb

Краткий ответ: НЕТ, у нас нет 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;
8
Alireza

Сейчас 2019 год, и последний проект модуля вложенности CSS на самом деле имеет нечто подобное. Представляем @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; }
 */
6
Roberrrt

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

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

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

Смотрите демо здесь:

http://rounin.co.uk/projects/axe/axe2.html

(сравните два списка слева в стиле стандартных селекторов и два списка справа в стиле топоров)

5
Rounin

Вот хак, использующий 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>
5
Jan Kyu Peblik

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

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

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

3
Gaurav Aggarwal

Это возможно с помощью амперсанда в SASS:

h3
  font-size: 20px
  margin-bottom: 10px
  .some-parent-selector &
    font-size: 24px
    margin-bottom: 20px

CSS-вывод:

h3 {
  font-size: 20px;
  margin-bottom: 10px;
}
.some-parent-selector h3 {
  font-size: 24px;
  margin-bottom: 20px;
}
2

Есть идеи?

CSS 4 будет интересен, если он добавит несколько хуков в ходьбу назад . До тех пор можно (хотя не желательно) использовать checkbox и/или radioinputs для нарушить обычный способ соединения вещей, благодаря чему 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 MS 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 Arow */
.menu__trigger__selection::after {
  content: "\25BC";
  display: inline-block;
  transform: rotate(90deg);
}


/* Customize to look more `select` like if ya 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 ya 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); /* MS!? */
}


/**
 * 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 ya 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 и forradio/checkboxinputs и label триггеры ; Скорее всего, кто-то покажет, как снова прикоснуться к ним.

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


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

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

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

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

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

1
S0AndS0

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

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

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

.parent {
    color: #000;
}

.parent.has-kiddos {
    color: red;
}
0
Damiano