Un selettore CSS per ottenere l'ultimo div visibile


162

Una domanda complicata per i selettori CSS, non so se sia possibile.

Diciamo che questo è il layout HTML:

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

Voglio selezionare l'ultimo div, che viene visualizzato (cioè no display:none) che sarebbe il terzo divnell'esempio dato. Intendiamoci, il numero di divs sulla pagina reale può differire (anche display:nonequelli).

Risposte:


63

Puoi selezionarlo e modellarlo con JavaScript o jQuery, ma i CSS da soli non possono farlo.

Ad esempio, se hai implementato jQuery sul sito, potresti semplicemente fare:

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

Anche se si spera che tu abbia una classe / ID racchiusa tra i div che stai selezionando, nel qual caso il tuo codice sarebbe simile a:

var last_visible_element = $('#some-wrapper div:visible:last');

22
la domanda dice chiaramente di no "un selettore CSS JQuery", dice "UN SELETTORE CSS", questa dovrebbe essere la RISPOSTA accettata = P
AgelessEssence,

2
Questa è, in effetti, la risposta alla domanda originale. L'interrogante non ha mai menzionato javascript o jquery e quei tag sono stati aggiunti da un altro risponditore. 1nfected - vuoi davvero jQuery? In tal caso, inseriscilo nella tua domanda. Altrimenti, dovresti invece accettare questa risposta.
jep

Penso che jQuery sia accettabile per l'OP. Questa era la soluzione accettata, dopo tutto.
Surreal Dreams,

7
Perché la prima risposta è allllwaaayyysss jquery? Questa è una risposta javascript a una domanda CSS . CSS! == javascript
dudewad

2
@dudewad: vedi l'ultima parte della prima frase: "ma i CSS da soli non possono farlo." La risposta potrebbe lasciarlo a quello, senza alternative in vista ... o fornire un'alternativa. Ma questa risposta ha almeno fatto la dovuta diligenza nel dichiarare che i CSS non possono fare ciò che viene chiesto (anche se non spiega il perché ). D'altra parte, una risposta che va appena fuori su una soluzione JavaScript senza riconoscere la natura CSS della questione è la pena di criticare.
BoltClock

23

La vera risposta a questa domanda è che non puoi farlo. Le alternative alle risposte solo CSS non sono risposte corrette a questa domanda, ma se le soluzioni JS sono accettabili per te, allora dovresti scegliere una delle risposte JS o jQuery qui. Tuttavia, come ho detto sopra, la risposta vera e corretta è che non puoi farlo in modo affidabile nei CSS a meno che tu non sia disposto ad accettare l' :notoperatore con [style*=display:none]e altri selettori così negati, che funzionano solo su stili in linea ed è complessivamente scarso soluzione.


In primo luogo, sono d'accordo con te, ma penso che l'uso :notdell'operatore come hai affermato possa funzionare in determinate circostanze. Ad esempio, questo funziona perfettamente per la mia situazione in cui ho JS che nasconde in modo condizionale elementi che quindi aggiungono stili in linea e quindi la tua soluzione funziona davvero perfettamente :)
doz87

1
Bene, allora immagino che cosa funzioni :) Sono solo un po 'un idealista e mi piace sottolineare dove le cose non sono le migliori, è importante essere in grado di distinguere ciò che è "hacky" e cosa non lo è perché ci rende tutti programmatori migliori.
Dudewad,

Sì, ti sento, sono d'accordo che questa soluzione non dovrebbe essere utilizzata come soluzione css solo per la query OP, penso che funzioni molto bene se usata insieme a JS.
doz87,

È inoltre possibile utilizzare una classe CSS per nascondere elementi (anziché uno stile incorporato). In tal caso, puoi anche negare il selettore per quella classe nascosta. Questo seleziona sempre lo stesso cosa è nascosto perché entrambi sono impostati dalla stessa classe CSS. Quindi la tua risposta va nella giusta direzione ma non abbastanza lontano. :-)
giovedì

8

Se è possibile utilizzare gli stili incorporati, è possibile farlo esclusivamente con CSS.

Sto usando questo per fare CSS sull'elemento successivo quando è visibile quello precedente:

div [style = 'display: block;'] + table {
  filtro: sfocatura (3px);
}

1
Lo cambierei [style*='display: block']perché potrebbe display: block !important;o semplicemente <div style="display: block">:-)
OZZIE

Funziona per me in un file CSS come questo .btn-group > .btn.d-none + .btn(usato per i gruppi di input di bootstrap "
Jean-Charbel VANNIER

7

Penso che non sia possibile selezionare un valore css (display)

modificare:

a mio avviso, avrebbe senso usare un po 'di jquery qui:

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

6

Soluzione JS pura (ad es. Quando non si utilizza jQuery o un altro framework per altre cose e non si desidera scaricarla solo per questa attività):

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


Grazie per lo snippet, l'unica risposta non jQuery! Tuttavia, questo non funziona quando si hanno più elementi padre da applicare a: jsfiddle.net/uEeaA/100 - puoi aiutarmi a costruire una soluzione per gli altri che funziona? Ne ho bisogno, altri ne hanno bisogno, quindi per favore aiutate :)
mnsth

Mi rendo conto che si tratta di un vecchio thread, ma per tutti i futuri visitatori, potresti fare qualcosa del genere jsfiddle.net/uEeaA/103
xec,

Volevo votare questo solo perché hai lasciato jQuery - bravo con te. La mia unica lamentela è che un div può essere nascosto alla vista in molti modi, non solo in base al parametro di stile. Molto veloce: [1] larghezza e altezza possono essere impostate su 0, [2] la scala di trasformazione può essere 0, [3] e possiamo posizionarla al di fuori dell'area visibile.
Markus,


2

in altro modo, puoi farlo con javascript, in Jquery puoi usare qualcosa come:

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

* rimontate


2

Non è possibile con CSS, tuttavia è possibile farlo con 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 (soluzione precedente):

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

$items.each(function() {

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

});

3
Questo è un sacco di jQuery per $('li:visible:last').addClass('red').
alex,

Eh? $('li').not(':hidden').last().addClass("red");
martynas,

0

Se non hai più bisogno degli elementi nascosti, usa element.remove()invece di element.style.display = 'none';.


-6

Questo ha funzionato per me.

.alert:not(:first-child){
    margin: 30px;
}

3
non stai rispondendo alla domanda
Serginho,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.