Czy istnieje selektor nadrzędny CSS?

3175

Jak wybrać <li>element, który jest bezpośrednim rodzicem elementu kotwiczącego?

Na przykład mój CSS byłby mniej więcej taki:

li < a.active {
    property: value;
}

Oczywiście istnieją sposoby na zrobienie tego za pomocą JavaScript, ale mam nadzieję, że istnieje jakieś obejście, które istnieje natywnie dla CSS poziomu 2.

Menu, które próbuję stylizować, jest wyrzucane przez CMS, więc nie mogę przenieść aktywnego elementu do <li>elementu ... (chyba, że ​​motywuję moduł tworzenia menu, którego wolałbym nie robić).

Jakieś pomysły?

jcuenod
źródło

Odpowiedzi:

2531

Obecnie nie ma możliwości wyboru elementu nadrzędnego elementu w CSS.

Jeśli byłby na to sposób, byłoby to w jednej z aktualnych specyfikacji selektorów CSS:

To powiedziawszy, Robocza selekcja poziomu 4 zawiera :has()pseudoklasę, która zapewni taką możliwość. Będzie podobny do implementacji jQuery .

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

Jednak od maja 2020 r. Nadal nie jest obsługiwana przez żadną przeglądarkę .

W międzyczasie będziesz musiał skorzystać z JavaScript, jeśli chcesz wybrać element nadrzędny.

Dan Herbert
źródło
68
Wydaje się, że zostało już zasugerowane i odrzucone: stackoverflow.com/questions/45004/…
RobM
14
Wygląda na to, selektor przedmiotu została przekształcona, z wyjątkiem przy użyciu !obecnie:The subject of the selector can be explicitly identified by appending an exclamation mark (!) to one of the compound selectors in a selector.
animuson
13
To, co gotowe, $wyglądało dla mnie lepiej ... !można łatwiej przeoczyć dołączone .
Christoph
51
Główny zwrot akcji! Selectors 4 WD został właśnie zaktualizowany dzisiaj, aby wykluczyć wskaźnik tematu z szybkiego profilu, który ma być wykorzystywany przez implementacje CSS. Jeśli ta zmiana pozostanie, oznacza to, że nie będziesz już mógł używać wskaźnika tematu w arkuszach stylów (chyba że dodasz rodzaj wypełnienia, taki jak opisany w innej odpowiedzi ) - możesz go używać tylko z interfejsem API Selectors i gdziekolwiek w przeciwnym razie można zaimplementować pełny profil.
BoltClock
55
Kolejna ważna aktualizacja: wygląda na to, że rozważają całkowite wyeliminowanie składni selektora tematów i zastąpienie go :has()pseudo, które wszyscy znają i kochają z jQuery. Najnowsza wersja językowa usunęła wszystkie odniesienia do wskaźnika podmiotu i zastąpiła go :has()pseudo. Nie znam dokładnych powodów, ale CSSWG przeprowadziła ankietę jakiś czas temu i wyniki musiały wpłynąć na tę decyzję. Najprawdopodobniej jest to zgodne z jQuery (dzięki czemu może wykorzystywać qSA bez modyfikacji), a ponieważ składnia wskaźnika podmiotu okazała się zbyt myląca.
BoltClock
152

Nie sądzę, że możesz wybrać rodzica tylko w CSS.

Ale ponieważ wydaje się, że masz już .activeklasę, łatwiej byłoby przenieść tę klasę do li(zamiast a). W ten sposób możesz uzyskać dostęp zarówno do, jak lii apoprzez CSS.

jeroen
źródło
4
Nie można przesunąć pseudo selektora na element listy, ponieważ nie jest to element, na którym można ustawić fokus. Używa selektora: active, więc gdy kotwica jest aktywna, chce, aby wpłynęła ona na element listy. Elementy listy nigdy nie będą w stanie aktywnym. Nawiasem mówiąc, szkoda, że ​​taki selektor nie istnieje. Uzyskiwanie czystego menu CSS w pełni dostępnego z klawiatury wydaje się niemożliwe bez niego (za pomocą selektorów rodzeństwa można tworzyć podmenu tworzone przy użyciu zagnieżdżonych list, ale gdy lista się skupi, zostanie ponownie ukryta). Jeśli są jakieś rozwiązania CSS tylko dla tego konkretnego konunu
12
@Dominic Aquilina Spójrz na pytanie, OP używa klasy, a nie pseudo selektora.
jeroen
125

Możesz użyć tego skryptu :

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

Spowoduje to wybranie dowolnego rodzica wprowadzania tekstu. Ale czekaj, jest jeszcze wiele więcej. Jeśli chcesz, możesz wybrać określonego rodzica:

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

Lub wybierz go, gdy jest aktywny:

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

Sprawdź ten HTML:

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

Możesz wybrać, span.helpgdy inputjest aktywny i pokazać go:

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

Istnieje wiele innych możliwości; po prostu sprawdź dokumentację wtyczki.

BTW, działa w Internet Explorerze.

Ider
źródło
5
załóżmy, że użycie jquery patent()byłoby szybsze. Trzeba to jednak przetestować
Dan
2
@Ised Nie powiedzie się, gdy masz deklarację CSS podmiotu Selectora bez selektora potomnego ( #a!sam zgłasza błąd, #a! pdziała), więc inne nie będą działać z powodu Uncaught TypeError: Cannot call method 'split' of undefined: patrz jsfiddle.net/HerrSerker/VkVPs
yunzen
3
@HerrSerker Myślę, że #a! jest nieprawidłowym selektorem, co powinien wybrać?
Iders
2
@Ised Nie wiem. Specyfikacja nie mówi, że jest to nielegalne. #za! powinien sam się wybrać. Przynajmniej ich nie powinno być błędu w JavaScript
Yunzen 17.04.13
5
Zgodnie z moim komentarzem do zaakceptowanej odpowiedzi wygląda na to, że wypełnianie może być wymagane nawet w niedalekiej przyszłości, ponieważ wskaźnik tematu może nigdy nie zostać zaimplementowany przez przeglądarki w CSS.
BoltClock
108

Jak wspomniało kilka innych, nie ma sposobu na stylizację elementów nadrzędnych elementu przy użyciu tylko CSS, ale następujące funkcje działają z jQuery :

$("a.active").parents('li').css("property", "value");
zcrar70
źródło
21
<Selektora nie istnieje (zweryfikowane jQuery 1.7.1).
Rob W
6
Być może ten <-syntax zadziałał w 2009 roku, ale zaktualizowałem go (dla 2013 roku).
Alastair
5
Jeszcze lepiej, korzystać z wbudowanego w jQuery jest :has()selektor : $("li:has(a.active)").css("property", "value");. Odczytuje podobnie do proponowanego !selektora CSS 4 . Zobacz także: :parentselektor , .parents()metoda , .parent()metoda .
Rory O'Kane
7
I zamiast używać .css("property", "value")do stylizowania wybranych elementów, powinieneś zwykle .addClass("someClass")i mieć w swoim CSS .someClass { property: value }( via ). W ten sposób możesz zanotować styl z pełną mocą CSS i dowolnych używanych przez ciebie preprocesorów.
Rory O'Kane
69

Nie ma selektora rodzica; dokładnie tak, jak nie ma poprzedniego selektora rodzeństwa. Jednym z dobrych powodów braku tych selektorów jest to, że przeglądarka musi przeglądać wszystkie elementy potomne elementu, aby ustalić, czy należy zastosować klasę. Na przykład, jeśli napisałeś:

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

Następnie przeglądarka będzie musiała poczekać, aż załaduje się i przeanalizuje wszystko, aż </body>do ustalenia, czy strona powinna być czerwona, czy nie.

Artykuł Dlaczego nie mamy selektora rodzica wyjaśnia go szczegółowo.

Salman A.
źródło
11
więc przyspiesz przeglądarkę. sam internet szybciej. ten selektor jest zdecydowanie potrzebny, a powodem jego nie jest, niestety, ponieważ żyjemy w powolnym, prymitywnym świecie.
vsync
11
w rzeczywistości selektor sprawiłby, że bardzo szybka przeglądarka wyglądałaby wolno.
Salman A
5
Ufam, że twórcy przeglądarek opracowaliby implementację, która jest (przynajmniej) tak szybka jak wersja javascript, z której ludzie i tak korzystają.
Marc.2377,
„żyjemy w powolnym, prymitywnym świecie” kaszel kaszel nowe jabłko zegarek kaszel kaszel
Marvin
@ Marc.2377 Jeśli spróbujesz powyższego przykładu w JS na swojej stronie, nigdy go nie odwiedzę. Z drugiej strony, powiedziałbym, że przez większość czasu dbasz tylko o bezpośrednie dzieci, więc jeśli ograniczałoby się to tylko do bezpośrednich dzieci, byłby to dobry dodatek bez zbytniego wpływu.
xryl669,
54

W CSS 2 nie ma na to sposobu. Możesz dodać klasę do lii odwołać się do a:

li.active > a {
    property: value;
}
Josh
źródło
3
ustawiając element na wyświetlanie: blok, możesz stylizować go tak, aby pasował do całego obszaru li. jeśli potrafisz wyjaśnić, jakiego stylu szukasz, być może mógłbym pomóc z rozwiązaniem.
Josh
jest to w rzeczywistości proste i eleganckie rozwiązanie, aw wielu przypadkach sensowne jest ustawienie klasy na rodzicu.
Ricardo
35

Spróbuj przełączyć ana blockwyświetlanie, a następnie użyj dowolnego stylu. aElementem wypełni lielementu, a będziesz w stanie zmienić swój wygląd, jak chcesz. Nie zapomnij ustawić lipadding na 0.

li {
  padding: 0;
  overflow: hidden;
}
a {
  display: block;
  width: 100%;
  color: ..., background: ..., border-radius: ..., etc...
}
a.active {
  color: ..., background: ...
}
Raseko
źródło
31

Selektor CSS „ General Sibling Combinator ” może być użyty do tego, co chcesz:

E ~ F {
    property: value;
}

To pasuje do każdego Felementu poprzedzonego przez Eelement.

Cobaasta
źródło
24
To jest tylko selektor rodzeństwa, to nie dziecko, rodzic ... tak naprawdę nie odpowiada na pytanie kolega
Alireza
26

O ile mi wiadomo, nie w CSS 2. CSS 3 ma bardziej niezawodne selektory, ale nie jest konsekwentnie wdrażany we wszystkich przeglądarkach. Nawet przy ulepszonych selektorach nie wierzę, że osiągnie dokładnie to, co podałeś w swoim przykładzie.

Mark Hurd
źródło
24

Wiem, że OP szukał rozwiązania CSS, ale można to łatwo osiągnąć za pomocą jQuery. W moim przypadku musiałem znaleźć <ul>tag nadrzędny dla <span>tagu zawartego w dziecku <li>. jQuery ma :hasselektor, dzięki czemu możliwe jest zidentyfikowanie rodzica przez zawarte w nim dzieci:

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

wybierze ulelement, który ma element potomny o identyfikatorze someId . Lub, aby odpowiedzieć na pierwotne pytanie, coś podobnego powinno załatwić sprawę (niesprawdzone):

$("li:has(.active)")
David Clarke
źródło
3
Lub użyj, $yourSpan.closest("ul")a dostaniesz nadrzędną UL swojego elementu rozpiętości. Niemniej jednak twoja odpowiedź jest całkowicie nie na temat, imho. Możemy odpowiedzieć na wszystkie pytania oparte na CSS za pomocą rozwiązania jQuery.
Robin van Baalen
1
Jak wskazano w innych odpowiedziach, nie ma sposobu, aby to zrobić za pomocą CSS 2. Biorąc pod uwagę to ograniczenie, udzieloną przeze mnie odpowiedź jest taka, o której wiem, że jest skuteczna i jest najprostszym sposobem odpowiedzi na pytanie za pomocą javascript imho.
David Clarke,
Biorąc pod uwagę twoje opinie, niektórzy się z tobą zgadzają. Ale jedyną odpowiedzią pozostaje ta zaakceptowana; jasne i proste „nie można tego zrobić tak, jak chcesz”. Jeśli pytanie brzmi: jak osiągnąć prędkość 60 km / h na rowerze, a ty odpowiesz „prostym: wsiądź do samochodu i uderz w benzynę”, to wciąż nie jest odpowiedzią. Stąd mój komentarz.
Robin van Baalen,
1
Takie podejście uczyniłoby SO prawie całkowicie bezużytecznym. Szukam SO, jak rozwiązać problemy, a znalezienie „jedynej odpowiedzi” nie rozwiązuje problemu. Właśnie dlatego SO jest tak niesamowity, ponieważ zawsze istnieje więcej niż jeden sposób na skórowanie kota.
David Clarke,
23

Pseudoelement :focus-withinpozwala na wybranie rodzica, jeśli fokus jest aktywny.

Element może być skoncentrowany, jeśli ma tabindexatrybut.

Obsługa przeglądarki dla fokusu

Tabindex

Przykład

.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>

sol
źródło
2
W moim przypadku to działa dobrze, dzięki! Po prostu nie, przykładem może być bardziej ilustrative jeśli zmieni kolor na rodzica, a nie do rodzeństwa, to wymienić .color:focus-within .changez .color:focus-within. W moim przypadku używam paska nawigacyjnego bootstrap, który dodaje klasę do dzieci, gdy są aktywne, i chcę dodać klasę do nadrzędnego paska .nav. Myślę, że jest to dość powszechny scenariusz, w którym jestem właścicielem znaczników, ale komponent css + js to bootstrap (lub inny), więc nie mogę zmienić zachowania. Chociaż mogę dodać tabindex i użyć tego css. Dzięki!
cancerbero
22

Jest to najczęściej dyskutowany aspekt specyfikacji Selektor Poziom 4 . Dzięki temu selektor będzie mógł stylizować element zgodnie z jego dzieckiem, używając wykrzyknika po danym selektorze (!).

Na przykład:

body! a:hover{
   background: red;
}

ustawi czerwony kolor tła, jeśli użytkownik najedzie kursorem na dowolną kotwicę.

Ale musimy poczekać na implementację przeglądarki :(

Marco Allori
źródło
21

Możesz spróbować użyć hiperłącza jako elementu nadrzędnego, a następnie zmienić elementy wewnętrzne po najechaniu myszą. Lubię to:

a.active h1 {color:red;}

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

a.active h2 {color:blue;}

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

W ten sposób możesz zmienić styl w wielu znacznikach wewnętrznych, w oparciu o najazd elementu nadrzędnego.

burza rzeczna
źródło
1
Jest to poprawne, ale ogranicza kod znacznika w aznaczniku tylko do niektórych elementów, jeśli chcesz zachować zgodność ze standardami XHTML. Na przykład nie można użyć elementu divwewnętrznego abez ostrzeżenia o naruszeniu schematu.
Ivaylo Slavov
2
Całkowicie w prawo Ivaylo! „a” jest elementem nieblokowym, więc nie można w nim używać elementów blokowych.
burza rzeczna
1
W HTML5 doskonale jest umieszczać elementy blokowe w linkach.
Matthew James Taylor
2
... gdyby było semantycznie złe, nie pozwoliliby na to w HTML5, gdzie nie było wcześniej.
BoltClock
14

Obecnie nie ma selektora rodziców i nie jest nawet omawiany w żadnym z rozmów W3C. Musisz zrozumieć, jak CSS jest oceniany przez przeglądarkę, aby zrozumieć, czy jest to potrzebne, czy nie.

Jest tu wiele technicznych wyjaśnień.

Jonathan Snook wyjaśnia, jak ocenia się CSS .

Chris Coyier o rozmowach selektora rodziców .

Harry Roberts ponownie o pisaniu wydajnych selektorów CSS .

Ale Nicole Sullivan ma kilka interesujących faktów na temat pozytywnych trendów .

Ci ludzie są najwyższej klasy w dziedzinie rozwoju front-endu.

Suraj Naik
źródło
12
needJest określona przez wymagania developerzy, czy mieć go w spec decydują inne czynniki.
nicodemus13
14

Pomysł na poziome menu ...

Część HTML

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

Część 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%; }

Zaktualizowano wersję demonstracyjną i resztę kodu

Kolejny przykład, jak używać go do wprowadzania tekstu - wybierz nadrzędny zestaw pól

Ilya B.
źródło
3
Nie jest dla mnie wcale jasne, w jaki sposób chcesz uogólnić to na niektóre / wiele / większość przypadków użycia selektora nadrzędnego, a nawet dokładnie, które części tego CSS robią. Czy możesz dodać dokładne wyjaśnienie?
Nathan Tuggy
2
Nie próbowałem zastosować tego do scenariuszy w świecie rzeczywistym, dlatego mówię „Nie do produkcji”. Ale myślę, że można go zastosować do menu 2-poziomowego tylko ze stałą szerokością elementu. „które części tego CSS robią, co” - tutaj rodzeństwo testujące jest w rzeczywistości tłem elementu nadrzędnego (ostatnia linia CSS).
Ilya B.,
2
Dodano wyjaśnienie (sekcja css jsfiddle, zaczynając od „GŁÓWNEJ CZĘŚCI”) ... I się myliłem - może istnieć dowolna liczba podpoziomów.
Ilya B.
13

Oto hack za pointer-eventspomocą 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>

Jan Kyu Peblik
źródło
12

Istnieje wtyczka, która rozszerza CSS o niektóre niestandardowe funkcje, które mogą naprawdę pomóc w projektowaniu stron internetowych. To się nazywa EQCSS .

Jedną z rzeczy, które dodaje EQCSS, jest selektor nadrzędny. Działa we wszystkich przeglądarkach, Internet Explorer 8 i nowszych. Oto format:

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

Więc tutaj otworzyliśmy kwerendę elementu dla każdego elementu a.active, a dla stylów w tym zapytaniu rzeczy takie $parentmają sens, ponieważ istnieje punkt odniesienia. Przeglądarka może znaleźć element nadrzędny, ponieważ jest bardzo podobny do parentNodeJavaScript.

Oto demo$parent i kolejne $parentdemo, które działa w Internet Explorerze 8 , a także zrzut ekranu na wypadek, gdybyś nie miał programu Internet Explorer 8 do przetestowania .

EQCSS obejmuje również meta-selektory : $prevdla elementu przed wybranym elementem i $thistylko dla tych elementów, które pasują do zapytania o element, i więcej.

innovati
źródło
11

Jest teraz 2019, a najnowsza wersja CSS Nesting Module faktycznie ma coś takiego. Przedstawiamy @nestzasady.

3.2 Reguła zagnieżdżania: @nest

Chociaż bezpośrednie zagnieżdżanie wygląda ładnie, jest nieco kruche. Niektóre prawidłowe selektory zagnieżdżania, takie jak .foo &, są niedozwolone, a edytowanie selektora w określony sposób może spowodować nieoczekiwane unieważnienie reguły. Również niektórym osobom trudno jest wizualnie odróżnić gniazda od otaczających deklaracji.

Aby pomóc we wszystkich tych kwestiach, w niniejszej specyfikacji zdefiniowano regułę @nest, która nakłada mniej ograniczeń dotyczących prawidłowego zagnieżdżania reguł stylu. Jego składnia to:

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

Reguła @nest działa identycznie jak reguła stylu: zaczyna się od selektora i zawiera deklaracje, które dotyczą elementów pasujących do selektora. Jedyna różnica polega na tym, że selektor użyty w regule @nest musi zawierać gniazdo, co oznacza, że ​​zawiera w sobie selektor zagnieżdżenia. Lista selektorów zawiera gniazdo, jeśli wszystkie jego poszczególne złożone selektory zawierają gniazdo.

(Skopiuj i wklej z powyższego adresu URL).

Przykład prawidłowych selektorów w ramach tej specyfikacji:

.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; }
 */
roberrrt-s
źródło
10

Technicznie nie ma na to bezpośredniego sposobu. Możesz to jednak rozwiązać za pomocą jQuery lub JavaScript.

Możesz jednak zrobić coś takiego.

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

jQuery

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

Jeśli chcesz to osiągnąć za pomocą jQuery, tutaj znajduje się odwołanie do selektora nadrzędnego jQuery .

Prabhakar Undurthi
źródło
9

W3C wykluczył taki selektor ze względu na ogromny wpływ na wydajność, jaki miałby na przeglądarkę.

rgb
źródło
27
fałszywe. ponieważ DOM jest drzewem, muszą dotrzeć do rodzica, zanim dotrą do dziecka, więc po prostu cofnij się o jeden węzeł. z oo
NullVoxPopuli
9
Selektory CSS są kolejką, dlatego kolejność wyboru jest oceniana, a nie hierarchia dokumentu XPath lub DOM.
Paul Sweatte,
3
@rgb Przynajmniej tak nam powiedzieli.
Junzen
9

Krótka odpowiedź brzmi NIE ; nie mamy parent selectorna tym etapie CSS, ale jeśli i tak nie musisz zamieniać elementów ani klas, drugą opcją jest JavaScript. Coś takiego:

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

Lub krócej, jeśli używasz jQuery w swojej aplikacji:

$('a.active').parents('li').css('color', 'red'); // Your property: value;
Alireza
źródło
5

Chociaż obecnie nie ma selektora rodzica w standardowym CSS, pracuję nad (osobistym) projektem o nazwie ax (tj. Augmented CSS Selector Syntax / ACSSSS ), który wśród 7 nowych selektorów obejmuje zarówno:

  1. bezpośredniego rodzica selektor <(który umożliwia wybór przeciwny do >)
  2. każdy wybierak przodka ^ (który umożliwia wybór przeciwny do [SPACE])

topór jest obecnie na stosunkowo wczesnym etapie rozwoju BETA.

Zobacz demo tutaj:

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

(porównaj dwie listy po lewej ze stylowymi selektorami i dwie listy po prawej ze stylowymi selektorami)

Rounin
źródło
3
Projekt jest obecnie na wczesnym etapie beta. Możesz (przynajmniej obecnie) aktywować selektory toporów w swoich stylach CSS, umieszczając je <script src="https://rouninmedia.github.io/axe/axe.js"></script>na samym końcu dokumentu HTML, tuż przed </body>.
Rounin
4

Przynajmniej do CSS 3 włącznie, nie można tak wybrać. Ale w JavaScript można to teraz zrobić dość łatwo, wystarczy dodać trochę waniliowego JavaScript, zauważ, że kod jest dość krótki.

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>

Eduard Florinescu
źródło
4

Jakieś pomysły?

CSS 4 będzie fantazyjny, jeśli doda trochę haków do chodzenia wstecz . Do tego czasu możliwe (choć nie wskazane) jest użycie checkboxi / lub radio inputs, aby przerwać zwykły sposób łączenia rzeczy, a dzięki temu CSS może działać poza swoim normalnym zakresem ...

/* 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>

... dość brutto , ale tylko z CSS i HTML można dotknąć i re-touch coś, ale bodyi :rootz niemal dowolnego miejsca przez przyłączenie idi forwłaściwości z radio/ checkbox inputs i label wyzwala ; prawdopodobnie ktoś kiedyś pokaże, jak je ponownie dotknąć.

Jednym dodatkowym zastrzeżeniem jest to, że może być użyty tylko jeden input ze specyficznych id, najpierw checkbox/ radio wygrywa stan przełączania innymi słowy ... Ale wiele etykiet może wskazywać na to samo input, chociaż to sprawiłoby, że zarówno HTML, jak i CSS wyglądałyby jeszcze grubiej.


... Mam nadzieję, że istnieje jakieś obejście, które istnieje natywnie dla CSS poziomu 2 ...

Nie jestem pewien co do innych :selektorów, ale ja :checkeddla wersji wcześniejszej niż CSS 3. Jeśli dobrze pamiętam, to było coś takiego i [checked]dlatego możesz znaleźć to w powyższym kodzie, na przykład:

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

... ale dla rzeczy takich jak ::afteri :hover, nie jestem wcale pewien, w której wersji CSS pojawiły się te pierwsze.

To wszystko powiedziane, proszę, nigdy nie używaj tego w produkcji, nawet w gniewie. Na pewno żart, innymi słowy tylko dlatego, że coś można zrobić, nie zawsze oznacza, że powinno .

S0AndS0
źródło
3

Nie, nie możesz wybrać rodzica tylko w CSS.

Ale ponieważ wydaje się, że masz już .activeklasę, łatwiej byłoby przenieść tę klasę do li(zamiast a). W ten sposób możesz uzyskać dostęp zarówno do, jak lii apoprzez CSS.

Gaurav Aggarwal
źródło
1

Zmiana elementu nadrzędnego na podstawie elementu podrzędnego może obecnie nastąpić tylko wtedy, gdy mamy <input>element wewnątrz elementu nadrzędnego. Gdy wejście zostanie zogniskowane, odpowiedni element nadrzędny może zostać zmieniony za pomocą CSS.

Poniższy przykład pomoże ci zrozumieć korzystanie :focus-withinz 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>

Sethuraman
źródło
1

Jest to możliwe z ampersand w Sass :

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

Dane wyjściowe CSS:

h3 {
  font-size: 20px;
  margin-bottom: 10px;
}
.some-parent-selector h3 {
  font-size: 24px;
  margin-bottom: 20px;
}
Rodolfo Jorge Nemer Nogueira
źródło
2
to prawda, ale tylko wtedy, gdy znasz selektor z góry.
Shahar,
11
To nie wybiera h3rodzica, który był celem. To wybrałoby h3s potomków .some-parent-selector.
Jacob Ford
1

W tym celu wynająłbym kod JavaScript. Na przykład w React podczas iteracji po tablicy dodaj kolejną klasę do komponentu nadrzędnego, co oznacza, że ​​zawiera on twoje dzieci:

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

A potem po prostu:

.parent {
    color: #000;
}

.parent.has-kiddos {
    color: red;
}
Damiano
źródło
0

Nie ma selektora nadrzędnego css (a zatem w preprocesorach css) z powodu „Główne powody, dla których grupa robocza CSS wcześniej odrzucała propozycje selektorów nadrzędnych są związane z wydajnością przeglądarki i problemami z renderowaniem przyrostowym”.

Dmitrij Sokołow
źródło