Um seletor de CSS para obter a última div visível

161

Uma pergunta complicada de seletor de CSS, não sei se é possível.

Digamos que este é o layout HTML:

<div></div>
<div></div>  
<div></div>  
<div style="display:none"></div>
<div style="display:none"></div>  

Quero selecionar o último div, que é exibido (ou seja, não display:none), que seria o terceiro divno exemplo dado. Lembre-se, o número de divs na página real pode ser diferente (mesmo display:noneos).

Vishal Shah
fonte

Respostas:

62

Você pode selecionar e estilizar isso com JavaScript ou jQuery, mas o CSS sozinho não pode fazer isso.

Por exemplo, se você tiver o jQuery implementado no site, poderá fazer:

var last_visible_element = $('div:visible:last');

Embora, esperançosamente, você tenha uma classe / ID agrupada em torno dos divs que você está selecionando; nesse caso, seu código seria semelhante a:

var last_visible_element = $('#some-wrapper div:visible:last');
Sonhos surreais
fonte
22
a questão diz claramente não "a CSS Selector JQuery", diz que "um seletor CSS", esta deve ser a resposta aceita = P
AgelessEssence
2
Esta é, de fato, a resposta para a pergunta original. O interlocutor nunca mencionou javascript ou jquery e essas tags foram adicionadas por outro respondedor. Infectado - você realmente deseja jQuery? Se sim, por favor, coloque isso na sua pergunta. Caso contrário, você deve aceitar esta resposta.
jep
Eu acho que o jQuery é aceitável para o OP. Essa foi a solução aceita, afinal.
Sonhos surreais
7
Por que é a primeira resposta allllwaaayyysss jquery? Esta é uma resposta javascript para uma pergunta de CSS . CSS! == javascript
dudewad
2
@dudewad: Veja a última parte da primeira frase: "mas o CSS sozinho não pode fazer isso." A resposta poderia ser assim, sem alternativa à vista ... ou fornecer uma alternativa. Mas essa resposta fez pelo menos a devida diligência ao afirmar que o CSS não pode fazer o que está sendo solicitado (embora não explique o porquê ). Por outro lado, uma resposta que só sai em uma solução JavaScript sem reconhecer a natureza CSS da questão é digno de crítica.
BoltClock
23

A resposta real para esta pergunta é: você não pode fazê-lo. Alternativas às respostas somente de CSS não são respostas corretas para esta pergunta, mas se as soluções JS forem aceitáveis ​​para você, você deve escolher uma das respostas JS ou jQuery aqui. No entanto, como eu disse acima, a resposta correta e verdadeira é que você não pode fazer isso no CSS de maneira confiável, a menos que esteja disposto a aceitar o :notoperador com os [style*=display:none]seletores negados e com outros seletores, que funcionam apenas em estilos inline e são geralmente pobres solução.

dudewad
fonte
Em primeiro lugar, concordo com você, mas acredito que o uso do :notoperador conforme você declarou pode funcionar em determinadas circunstâncias. Por exemplo, isso funciona perfeitamente para a minha situação onde eu tenho JS condicionalmente ocultar elementos que então adiciona estilos inline e, assim, a sua solução realmente funciona perfeitamente :)
doz87
1
Bem, acho que o que funciona funciona :) Sou um pouco idealista e gosto de enfatizar que as coisas não são as melhores, é importante poder distinguir o que é 'hacky' e o que não é porque isso nos torna melhores programadores.
Dudewad 01/09
Sim, ouvi dizer, concordo que essa solução não deve ser usada como uma solução apenas de CSS para a consulta OP, mas acho que isso funciona muito bem quando usado em conjunto com o JS.
Doz87 2/17
Você também pode usar uma classe CSS para ocultar elementos (em vez de um estilo embutido). Se for esse o caso, você também pode negar o seletor para essa classe oculta. Isso sempre seleciona o mesmo que está oculto, porque ambos são definidos pela mesma classe CSS. Portanto, sua resposta vai na direção certa, mas não o suficiente. :-)
ygoe 21/11/19
8

Se você pode usar estilos embutidos, pode fazê-lo exclusivamente com CSS.

Estou usando isso para fazer CSS no próximo elemento quando o anterior estiver visível:

div [style = 'display: bloco;'] + tabela {
  filtro: desfoque (3px);
}
Alex Grande
fonte
1
Gostaria de alterá-lo para [style*='display: block']uma vez que poderia ter display: block !important;ou apenas <div style="display: block">:-)
OZZIE
Funciona para mim em um arquivo css como este .btn-group > .btn.d-none + .btn(usado para os grupos de entrada do bootstrap "
Jean-Charbel VANNIER
7

Eu acho que não é possível selecionar por um valor css (display)

editar:

na minha opinião, faria sentido usar um pouco de jquery aqui:

$('#your_container > div:visible:last').addClass('last-visible-div');
Guillaume86
fonte
6

Solução JS pura (por exemplo, quando você não usa o jQuery ou outra estrutura para outras coisas e não deseja fazer o download apenas para esta tarefa):

<div>A</div>
<div>B</div>  
<div>C</div>  
<div style="display:none">D</div>
<div style="display:none">E</div>    

<script>
var divs = document.getElementsByTagName('div');
var last;

if (divs) {
    for (var i = 0; i < divs.length; i++) {
        if (divs[i].style.display != 'none') {
            last = divs[i];           
        }
    }
}

if (last) {
    last.style.background = 'red';
}
</script>

http://jsfiddle.net/uEeaA/90/

pantera
fonte
Obrigado pelo trecho, a única resposta não-jQuery! No entanto, isso não funciona ao ter vários elementos pai para aplicar a: jsfiddle.net/uEeaA/100 - você pode me ajudar a criar uma solução para outras pessoas que funcione? Eu preciso disso, outros precisam, então por favor me ajude :)
mnsth
Sei que esse é um tópico antigo, mas, para futuros visitantes, você pode fazer algo como jsfiddle.net/uEeaA/103
xec 16/02/16
Eu queria votar em cima de apenas b / c que você deixou o jQuery - bom para você. Minha única reclamação é que uma div pode ser ocultada da visualização de várias maneiras, não apenas com base no parâmetro style. Muito rápido: [1] largura e altura podem ser definidas como 0, [2] a escala de transformação pode ser 0, [3] e podemos colocá-lo fora da área visível.
Markus
4

Experimentar

div: not ([style * = "display: none"])

Tyler Wayne
fonte
2

de outra maneira, você pode fazê-lo com javascript, no Jquery, você pode usar algo como:

$('div:visible').last()

* reeditado

eveevans
fonte
2

Não é possível com CSS, no entanto, você pode fazer isso com jQuery.

JSFIDDLE DEMO

jQuery:

$('li').not(':hidden').last().addClass("red");

HTML:

<ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
        <li class="hideme">Item 4</li>    
</ul>

CSS:

.hideme {
    display:none;
}

.red {
    color: red;
}

jQuery (solução anterior):

var $items = $($("li").get().reverse());

$items.each(function() {

    if ($(this).css("display") != "none") {
        $(this).addClass("red");
        return false;
    }

});
mártires
fonte
3
Isso é muito jQuery para $('li:visible:last').addClass('red').
alex
Hã? $('li').not(':hidden').last().addClass("red");
Martynas
0

Se você não precisar mais dos elementos ocultos, use em element.remove()vez de element.style.display = 'none';.

Masoud Shariati
fonte
-6

Isso funcionou para mim.

.alert:not(:first-child){
    margin: 30px;
}
kmukku
fonte
3
você não está respondendo à pergunta
Serginho