Existe um seletor pai CSS?

3176

Como seleciono o <li>elemento pai direto do elemento âncora?

Como exemplo, meu CSS seria algo como isto:

li < a.active {
    property: value;
}

Obviamente, existem maneiras de fazer isso com JavaScript, mas espero que exista algum tipo de solução alternativa nativa para o CSS Nível 2.

O menu que estou tentando estilizar está sendo exibido por um CMS, por isso não posso mover o elemento ativo para o <li>elemento ... (a menos que eu tema o módulo de criação de menus que preferiria não fazer).

Alguma ideia?

jcuenod
fonte

Respostas:

2535

Atualmente, não há como selecionar o pai de um elemento no CSS.

Se houvesse uma maneira de fazê-lo, seria uma das especificações atuais dos seletores de CSS:

Dito isto, o Rascunho de Trabalho dos Seletores Nível 4 inclui uma :has()pseudo classe que fornecerá esse recurso. Será semelhante à implementação do jQuery .

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

No entanto, em maio de 2020, isso ainda não é suportado por nenhum navegador .

Enquanto isso, você precisará recorrer ao JavaScript se precisar selecionar um elemento pai.

Dan Herbert
fonte
68
Parece que já foi sugerido e rejeitado: stackoverflow.com/questions/45004/…
RobM
14
Parece que o seletor de assunto foi revisitado, exceto usando um !agora: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
O $anexo parecia melhor para mim ... o anexo !pode ser ignorado mais facilmente.
Christoph
51
Grande reviravolta na trama! O Selectors 4 WD foi atualizado hoje para excluir o indicador de assunto do perfil rápido, que deve ser usado pelas implementações de CSS. Se essa alteração persistir, significa que você não poderá mais usar o indicador de assunto nas folhas de estilo (a menos que você adicione algum tipo de polyfill como o descrito em outra resposta ) - você poderá usá-lo apenas com a API Selectors e em qualquer lugar caso contrário, o perfil completo poderá ser implementado.
BoltClock
55
Outra grande atualização: parece que eles estão pensando em acabar com a sintaxe do seletor de assunto e substituí-la pelo :has()pseudo-todo mundo que conhece e ama o jQuery. O ED mais recente removeu todas as referências ao indicador de assunto e o substituiu pelo :has()pseudo. Não sei as razões exatas, mas o CSSWG realizou uma pesquisa há algum tempo e os resultados devem ter influenciado essa decisão. É mais provável a compatibilidade com o jQuery (para que ele possa alavancar o qSA sem modificações) e porque a sintaxe do indicador de assunto se mostrou muito confusa.
BoltClock
152

Eu não acho que você pode selecionar o pai apenas em CSS.

Mas como você já parece ter uma .activeclasse, seria mais fácil movê-la para o li(em vez de a). Dessa forma, você pode acessar apenas o CSS lie o aCSS via.

jeroen
fonte
4
Você não pode mudar o pseudo-seletor para o item da lista, pois não é um elemento que pode ser focalizado. Ele está usando o seletor: active; portanto, quando a âncora estiver ativa, ele deseja que o item da lista seja afetado. Os itens da lista nunca estarão no estado ativo. Como um aparte, é lamentável que esse seletor não exista. Obter um menu CSS puro para ser totalmente acessível ao teclado parece impossível sem ele (usando seletores irmãos, você pode fazer com que submenus criados usando listas aninhadas apareçam, mas quando a lista ganha foco, ela fica oculta novamente). Se houver quaisquer soluções somente CSS para esta CONUN especial
12
@Dominic Aquilina Dê uma olhada na pergunta, o OP está usando uma classe, não um pseudo-seletor.
jeroen
125

Você pode usar este script :

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

Isso selecionará qualquer pai de uma entrada de texto. Mas espere, ainda há muito mais. Se desejar, você pode selecionar um pai especificado:

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

Ou selecione-o quando estiver ativo:

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

Confira este HTML:

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

Você pode selecionar isso span.helpquando inputestiver ativo e mostrá-lo:

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

Existem muito mais recursos; basta verificar a documentação do plugin.

BTW, ele funciona no Internet Explorer.

Idered
fonte
5
suponha que usar jquery patent()seria mais rápido. Isso precisa ser testado, no entanto
Dan
2
@Idered Falha quando você tem uma declaração CSS de um Assunto do Seletor sem nenhum seletor filho (por #a!si só lança um erro, #a! pfunciona) e, portanto, os outros também não funcionam por causa de Uncaught TypeError: Cannot call method 'split' of undefined: consulte jsfiddle.net/HerrSerker/VkVPs
yunzen
3
@HerrSerker Acho que #a! é um seletor inválido, o que ele deve selecionar?
precisa
2
@Idered eu não sei. As especificações não dizem que é ilegal. #uma! deve selecionar-se. Pelo menos não deve haver erro no JavaScript
yunzen 17/04/2013
5
De acordo com meu comentário sobre a resposta aceita, parece que o polyfill pode ser necessário mesmo em um futuro próximo, afinal, porque o indicador de assunto nunca pode ser implementado pelos navegadores em CSS.
BoltClock
108

Conforme mencionado por alguns outros, não há como estilizar os pais de um elemento usando apenas CSS, mas o seguinte funciona com o jQuery :

$("a.active").parents('li').css("property", "value");
zcrar70
fonte
21
O <seletor não existe (verificado usando o jQuery 1.7.1).
23412 Rob Rob W
6
Talvez essa <sintaxe tenha funcionado em 2009, mas eu a atualizei (para 2013).
Alastair
5
Ainda melhor, use built-in de jQuery :has()seletor : $("li:has(a.active)").css("property", "value");. É semelhante ao !seletor proposto pelo CSS 4 . Veja também: :parentseletor , .parents()método , .parent()método .
Rory O'Kane
7
E, em vez de usar .css("property", "value")para estilizar os elementos selecionados, você deve .addClass("someClass")e deve ter no seu CSS .someClass { property: value }( via ). Dessa forma, você pode anotar o estilo com todo o poder do CSS e de qualquer pré-processador que estiver usando.
Rory O'Kane
69

Não há seletor pai; do jeito que não há seletor de irmãos anterior. Um bom motivo para não ter esses seletores é porque o navegador precisa percorrer todos os filhos de um elemento para determinar se uma classe deve ou não ser aplicada. Por exemplo, se você escreveu:

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

Em seguida, o navegador terá que esperar até carregar e analisar tudo até </body>determinar se a página deve estar vermelha ou não.

O artigo Por que não temos um seletor pai explica isso em detalhes.

Salman A
fonte
11
então torne o navegador mais rápido. a internet em si mais rápida. esse seletor é definitivamente necessário, e a razão para não implementá-lo é, infelizmente, porque vivemos em um mundo lento e primitivo.
vsync
11
na verdade, o seletor faria um navegador muito rápido parecer lento.
Salman Um
5
Confio que os desenvolvedores de navegadores apresentem uma implementação que seja (pelo menos) tão rápida quanto a versão javascript, que é aquela que as pessoas acabam usando de qualquer maneira.
Marc.2377
"em que vivemos, um mundo primitivo lento" tosse tosse novo relógio maçã tosse tosse
Marvin
@ Marc.2377 Se você tentar o exemplo acima em JS no seu site, nunca vou visitá-lo. Por outro lado, eu diria que na maioria das vezes, você se preocupa apenas com filhos imediatos; portanto, se fosse limitado apenas aos filhos imediatos, seria uma boa adição sem muito impacto.
precisa saber é o seguinte
54

Não há uma maneira de fazer isso no CSS 2. Você pode adicionar a classe lie referenciar a:

li.active > a {
    property: value;
}
Josh
fonte
3
exibindo o elemento a: block, você pode estilizá-lo para caber em toda a área de li. se você puder explicar qual estilo você está procurando, talvez eu possa ajudar com uma solução.
Josh
essa é realmente uma solução simples e elegante e, em muitos casos, faz sentido definir a classe no pai.
Ricardo
35

Tente mudar apara blockexibição e, em seguida, use o estilo desejado. O aelemento preencherá o lielemento e você poderá modificar sua aparência conforme desejar. Não se esqueça de definir o lipreenchimento para 0.

li {
  padding: 0;
  overflow: hidden;
}
a {
  display: block;
  width: 100%;
  color: ..., background: ..., border-radius: ..., etc...
}
a.active {
  color: ..., background: ...
}
Raseko
fonte
31

O seletor CSS " General Sibling Combinator " pode ser usado para o que você deseja:

E ~ F {
    property: value;
}

Isso corresponde a qualquer Felemento que é precedido por um Eelemento.

cobaasta
fonte
24
Este seletor é apenas irmão, não é filho, pai ... não realmente responder a pergunta companheiro
Alireza
26

Não no CSS 2, tanto quanto eu sei. O CSS 3 possui seletores mais robustos, mas não é implementado de forma consistente em todos os navegadores. Mesmo com os seletores aprimorados, não acredito que ele cumpra exatamente o que você especificou em seu exemplo.

Mark Hurd
fonte
24

Eu sei que o OP estava procurando uma solução CSS, mas é simples de conseguir usando o jQuery. No meu caso, eu precisava encontrar a <ul>tag pai para uma <span>tag contida no filho <li>. O jQuery possui o :hasseletor, portanto, é possível identificar um pai pelos filhos que ele contém:

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

selecionará o ulelemento que possui um elemento filho com o ID someId . Ou, para responder à pergunta original, algo como o seguinte deve fazer o truque (não testado):

$("li:has(.active)")
David Clarke
fonte
3
Ou use $yourSpan.closest("ul")e você obterá o UL pai do seu elemento de amplitude. No entanto, sua resposta é imho completamente offtopic. Podemos responder a todas as perguntas de CSS com uma solução jQuery.
Robin van Baalen
1
Conforme identificado em outras respostas, não há como fazer isso usando o CSS 2. Dada essa restrição, a resposta que forneci é uma que eu sei que é eficaz e é a maneira mais simples de responder à pergunta usando javascript imho.
David Clarke
Dadas suas votações, algumas pessoas concordam com você. Mas a única resposta continua sendo a aceita; puro e simples "não pode ser feito da maneira que você deseja". Se a pergunta é como arquivar 60 mph em uma bicicleta e você a responde com "simples; entre em um carro e acelere", ainda não é uma resposta. Daí o meu comentário.
Robin van Baalen
1
Essa abordagem tornaria o SO quase completamente inútil. Eu procuro SO para saber como resolver problemas, para não encontrar a "única resposta" não soluciona o problema. É por isso que o SO é tão incrível, porque sempre há mais de uma maneira de esfolar um gato.
David Clarke
23

O pseudo elemento :focus-withinpermite que um pai seja selecionado se um descendente tiver foco.

Um elemento pode ser focado se tiver um tabindexatributo.

Suporte do navegador para foco dentro

Tabindex

Exemplo

.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
fonte
2
Isso funciona bem no meu caso, obrigado! Apenas não, o exemplo seria mais ilustrativo se você mudar a cor para o pai, não para o irmão, isso é substituído .color:focus-within .changepor .color:focus-within. No meu caso, estou usando a barra de navegação de inicialização que adiciona a classe aos filhos quando ativo e quero adicionar uma classe ao pai .nav-bar. Eu acho que esse é um cenário bastante comum, onde eu possuo a marcação, mas o componente css + js é bootstrap (ou outro), portanto não posso alterar o comportamento. Embora eu possa adicionar tabindex e usar este css. Obrigado!
Cancerbero
22

Esse é o aspecto mais discutido da especificação Seletores de nível 4 . Com isso, um seletor poderá estilizar um elemento de acordo com seu filho, usando um ponto de exclamação após o seletor fornecido (!).

Por exemplo:

body! a:hover{
   background: red;
}

definirá uma cor de fundo vermelha se o usuário passar o mouse sobre qualquer âncora.

Mas temos que esperar pela implementação dos navegadores :(

Marco Allori
fonte
21

Você pode tentar usar o hiperlink como pai e alterar os elementos internos ao passar o mouse. Como isso:

a.active h1 {color:red;}

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

a.active h2 {color:blue;}

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

Dessa forma, você pode alterar o estilo em várias tags internas, com base na rolagem do elemento pai.

tempestade de rios
fonte
1
Isso está correto, mas limita o código de marcação na atag a apenas alguns elementos, se você deseja estar em conformidade com os padrões XHTML. Por exemplo, você não pode usar um divinterior a, sem receber um aviso de violação do esquema.
Ivaylo Slavov
2
Totalmente certo Ivaylo! "a" é um elemento que não é de bloco, portanto, não é possível usar elementos de bloco dentro dele.
riverstorm
1
No HTML5, é perfeitamente adequado colocar elementos de bloco dentro de links.
Matthew James Taylor
2
... se estivesse semanticamente errado, eles não o teriam permitido no HTML5 onde não estavam antes.
BoltClock
14

Atualmente, não há seletor de pais e nem está sendo discutido em nenhuma das palestras do W3C. Você precisa entender como o CSS é avaliado pelo navegador para realmente entender se precisamos ou não.

Há muitas explicações técnicas aqui.

Jonathan Snook explica como o CSS é avaliado .

Chris Coyier nas conversações do seletor de pais .

Harry Roberts novamente ao escrever seletores CSS eficientes .

Mas Nicole Sullivan tem alguns fatos interessantes sobre tendências positivas .

Essas pessoas são todas de primeira classe no campo do desenvolvimento de front-end.

Suraj Naik
fonte
12
O needé definido pelos requisitos dos desenvolvedores da web, se a inclusão nas especificações é decidida por outros fatores.
precisa
14

Apenas uma ideia para o menu horizontal ...

Parte do HTML

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

Parte do 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%; }

Demonstração atualizada e o restante do código

Outro exemplo de como usá-lo com entradas de texto - selecione pai fieldset

Ilya B.
fonte
3
Não está claro para mim como você pretende generalizar isso para alguns / muitos / a maioria dos casos de uso do seletor pai, ou mesmo exatamente quais partes deste CSS estão fazendo o que. Você pode adicionar uma explicação completa?
Nathan Tuggy
2
Não tentei aplicar isso a cenários do mundo real, por isso digo "Não para produção". Mas acho que só pode ser aplicado ao menu de dois níveis com largura de item fixa. "quais partes deste CSS estão fazendo o que" - .test-irmão aqui é na verdade o plano de fundo do item pai (a última linha do CSS).
Ilya B.
2
Adicionado explicação (seção css do jsfiddle, a partir de "MAIN PART") ... E eu estava enganado - pode haver qualquer número de subníveis.
Ilya B.
13

Aqui está um hack usando pointer-eventscom 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
fonte
12

Há um plug-in que estende o CSS para incluir alguns recursos não-padrão que podem realmente ajudar no design de sites. Chama-se EQCSS .

Uma das coisas que o EQCSS adiciona é um seletor pai. Funciona em todos os navegadores, Internet Explorer 8 e superior. Aqui está o formato:

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

Então, aqui abrimos uma consulta de elemento em cada elemento a.activee, para os estilos dentro dessa consulta, coisas como $parentfazem sentido, porque há um ponto de referência. O navegador pode encontrar o pai, porque é muito semelhante aoparentNode JavaScript.

Aqui está uma demonstração$parent e outra $parentdemonstração que funciona no Internet Explorer 8 , bem como uma captura de tela, caso você não tenha o Internet Explorer 8 para testar. .

O EQCSS também inclui meta-seletores : $prevpara o elemento antes de um elemento selecionado e $thisapenas para aqueles que correspondem a uma consulta de elemento, entre outros.

innovati
fonte
11

Agora é 2019, e a versão mais recente do CSS Nesting Module tem algo parecido com isto. Introdução @nestàs regras.

3.2 A regra do assentamento: @nest

Enquanto o aninhamento direto parece bom, é um pouco frágil. Alguns seletores de aninhamento válidos, como .foo &, não são permitidos e a edição do seletor de certas maneiras pode invalidar a regra inesperadamente. Além disso, algumas pessoas consideram difícil o ninho para distinguir visualmente das declarações circundantes.

Para ajudar em todos esses problemas, essa especificação define a regra @nest, que impõe menos restrições sobre como aninhar validamente regras de estilo. Sua sintaxe é:

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

A regra @nest funciona de maneira idêntica a uma regra de estilo: começa com um seletor e contém declarações que se aplicam aos elementos correspondentes ao seletor. A única diferença é que o seletor usado em uma regra @nest deve conter um ninho, o que significa que ele contém um seletor de aninhamento em algum lugar. Uma lista de seletores contém ninhos se todos os seus seletores complexos individuais estiverem contendo ninhos.

(Copie e cole a partir do URL acima).

Exemplo de seletores válidos sob esta especificação:

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

Tecnicamente, não há maneira direta de fazer isso. No entanto, você pode resolver isso com jQuery ou JavaScript.

No entanto, você pode fazer algo assim também.

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

jQuery

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

Se você deseja conseguir isso usando o jQuery, aqui está a referência para o seletor pai do jQuery .

Prabhakar Undurthi
fonte
9

O W3C excluiu esse seletor por causa do enorme impacto no desempenho que teria em um navegador.

rgb
fonte
27
falso. como o DOM é uma árvore, eles precisam ir para o pai antes de chegar ao filho, então basta simplesmente retornar um nó. oo
NullVoxPopuli
9
Os seletores CSS são uma fila, portanto , a ordem do seletor é avaliada em vez da hierarquia XPath ou DOM do documento.
Paul Sweatte
3
@rgb Pelo menos foi o que nos disseram.
yunzen
9

A resposta curta é NÃO ; não temos um parent selectorneste estágio no CSS, mas se você não precisar trocar os elementos ou classes de qualquer maneira, a segunda opção será usar JavaScript. Algo assim:

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

Ou uma maneira mais curta se você usar o jQuery em seu aplicativo:

$('a.active').parents('li').css('color', 'red'); // Your property: value;
Alireza
fonte
5

Embora atualmente não exista um seletor pai no CSS padrão, estou trabalhando em um projeto (pessoal) chamado ax (ie. Sintaxe de seletor de CSS aumentada / ACSSSS ) que, entre seus 7 novos seletores, inclui ambos:

  1. um seletor pai imediato< (que permite a seleção oposta a >)
  2. um seletor de qualquer ancestral ^ (que permite a seleção oposta a [SPACE])

ax está atualmente em um estágio BETA relativamente inicial de desenvolvimento.

Veja uma demonstração aqui:

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

(compare as duas listas à esquerda com seletores padrão e as duas listas à direita com seletores de machados)

Rounin
fonte
3
Atualmente, o projeto está no estágio beta inicial. Você pode (pelo menos atualmente) ativar os seletores de machado em seus estilos CSS, incluindo <script src="https://rouninmedia.github.io/axe/axe.js"></script>no final do seu documento html, pouco antes </body>.
21417 Rounin
4

Pelo menos até e incluindo o CSS 3, você não pode selecionar assim. Mas isso pode ser feito com muita facilidade hoje em dia no JavaScript, você só precisa adicionar um pouco de JavaScript vanilla, observe que o código é bastante curto.

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
fonte
4

Alguma ideia?

O CSS 4 será sofisticado se adicionar alguns ganchos para andar para trás . Até então, é possível (embora não aconselhável) usar checkboxe / ou radio inputs para interromper a maneira usual de conectar as coisas, e através disso também permite que o CSS opere fora do seu escopo normal ...

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

... bastante nojento , mas com apenas CSS e HTML, é possível tocar e retocar qualquer coisa, exceto o bodye :rootde qualquer lugar, vinculando as propriedades ide forde radio/ checkbox inputs e label triggers ; provavelmente alguém mostrará como retocar as pessoas em algum momento.

Uma ressalva adicional é que apenas um input de um idtalvez específico seja usado, primeiro checkbox/ radio ganha um estado alternado em outras palavras ... Mas vários rótulos podem apontar para o mesmo input, embora isso tornaria o HTML e o CSS ainda mais grosseiros.


... Espero que exista algum tipo de solução alternativa nativa para o CSS Nível 2 ...

Não tenho certeza dos outros :seletores, mas sim :checkedpara o pré-CSS 3. Se bem me lembro, era algo parecido com o [checked]qual você pode encontrá-lo no código acima, por exemplo,

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

... mas para coisas como ::aftere:hover , eu não tenho certeza de qual versão CSS as apareceu pela primeira vez.

Dito isso, por favor, nunca use isso na produção, nem mesmo com raiva. Como uma piada, com certeza, ou em outras palavras, apenas porque algo pode ser feito nem sempre significa que deveria .

S0AndS0
fonte
3

Não, você não pode selecionar o pai apenas em CSS.

Mas como você já parece ter uma .activeclasse, seria mais fácil movê-la para o li(em vez de a). Dessa forma, você pode acessar apenas o CSS lie o aCSS via.

Gaurav Aggarwal
fonte
1

A alteração do elemento pai com base no elemento filho atualmente só pode acontecer quando temos um <input>elemento dentro do elemento pai. Quando uma entrada obtém o foco, seu elemento pai correspondente pode ser afetado usando CSS.

O exemplo a seguir ajudará você a entender o uso :focus-withinem 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
fonte
1

É possível com e comercial em Sass :

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

Saída CSS:

h3 {
  font-size: 20px;
  margin-bottom: 10px;
}
.some-parent-selector h3 {
  font-size: 24px;
  margin-bottom: 20px;
}
Rodolfo Jorge Nemer Nogueira
fonte
2
é verdade, mas somente se você conhecer o seletor com antecedência.
Shahar
11
Isso não seleciona h3o pai, que era o objetivo. Isso selecionaria h3s dos quais são descendentes .some-parent-selector.
Jacob Ford
1

Eu contrataria algum código JavaScript para fazer isso. Por exemplo, em React ao iterar sobre uma matriz, adicione outra classe ao componente pai, o que indica que ele contém seus filhos:

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

E então simplesmente:

.parent {
    color: #000;
}

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

Não há seletor pai de css (e, portanto, em pré-processadores de css), devido a "Os principais motivos para o CSS Working Group rejeitar anteriormente propostas de seletores pai estão relacionados ao desempenho do navegador e a problemas de renderização incremental".

Dmitry Sokolov
fonte