Un selector de CSS para obtener el último div visible

161

Una pregunta difícil sobre el selector de CSS, no sé si es posible.

Digamos que este es el diseño HTML:

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

Quiero seleccionar el último div, que se muestra (es decir, no display:none), que sería el tercero diven el ejemplo dado. Eso sí, el número de divs en la página real puede diferir (incluso display:nonelos).

Vishal Shah
fuente

Respuestas:

62

Puede seleccionar y diseñar esto con JavaScript o jQuery, pero CSS solo no puede hacer esto.

Por ejemplo, si tiene jQuery implementado en el sitio, puede hacer lo siguiente:

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

Aunque es de esperar que tenga una clase / ID envuelta alrededor de los divs que está seleccionando, en cuyo caso su código se vería así:

var last_visible_element = $('#some-wrapper div:visible:last');
Sueños surrealistas
fuente
22
la pregunta dice claramente que no "un Selector CSS JQuery", dice "UN SELECTOR CSS", esta debería ser la RESPUESTA aceptada = P
AgelessEssence
2
Esta es, de hecho, la respuesta a la pregunta original. El interlocutor nunca mencionó javascript o jquery y esas etiquetas fueron agregadas por otro respondedor. 1 infectado: ¿realmente quieres jQuery? Si es así, por favor ponga eso en su pregunta. De lo contrario, debe aceptar esta respuesta en su lugar.
jep
Creo que jQuery es aceptable para el OP. Esa era la solución aceptada, después de todo.
Surreal Dreams
77
¿Por qué es la primera respuesta allllwaaayyysss jquery? Esta es una respuesta de JavaScript a una pregunta de CSS . CSS! == javascript
dudewad
2
@dudewad: Vea la última parte de la primera oración: "pero CSS solo no puede hacer esto". La respuesta podría dejarlo así, sin otra alternativa a la vista ... o proporcionar una alternativa. Pero esta respuesta al menos ha hecho su debida diligencia al afirmar que CSS no puede hacer lo que se le pide (aunque no explica por qué ). Por otra parte, una respuesta que simplemente se apaga en una solución de JavaScript sin reconocer la naturaleza CSS de la cuestión es la pena criticar.
BoltClock
23

La verdadera respuesta a esta pregunta es que no puedes hacerlo. Las alternativas a las respuestas solo de CSS no son respuestas correctas a esta pregunta, pero si las soluciones JS son aceptables para usted, entonces debe elegir una de las respuestas JS o jQuery aquí. Sin embargo, como dije anteriormente, la respuesta correcta y verdadera es que no puede hacer esto en CSS de manera confiable a menos que esté dispuesto a aceptar el :notoperador con [style*=display:none]y otros selectores negados, que solo funciona en estilos en línea, y es un pobre en general solución.

amigo
fuente
En primer lugar, estoy de acuerdo con usted, pero creo que usar el :notoperador como usted dijo puede funcionar en ciertas circunstancias. Por ejemplo, esto funciona perfectamente para mi situación en la que tengo JS ocultando elementos condicionalmente que luego agrega estilos en línea y, por lo tanto, su solución realmente funciona perfectamente :)
doz87
1
Bueno, entonces supongo que lo que funciona :) Soy un poco idealista y me gusta enfatizar que las cosas no son las mejores, es importante poder distinguir lo que es 'hacky' y lo que no es porque nos hace a todos mejores programadores.
dudewad
Sí, te escucho, estoy de acuerdo en que esta solución no debe usarse como una solución de CSS para la consulta OP, creo que esto funciona muy bien cuando se usa junto con JS.
doz87
También puede usar una clase CSS para ocultar elementos (en lugar de un estilo en línea). Si ese es el caso, también puede negar el selector para esa clase oculta. Esto siempre selecciona lo mismo que está oculto porque ambos están establecidos por la misma clase CSS. Entonces su respuesta va en la dirección correcta pero no lo suficientemente lejos. :-)
ygoe
8

Si puede usar estilos en línea, puede hacerlo únicamente con CSS.

Estoy usando esto para hacer CSS en el siguiente elemento cuando el anterior es visible:

div [style = 'display: block;'] + table {
  filtro: desenfoque (3px);
}
Alex Grande
fuente
1
Lo cambiaría a [style*='display: block']como podría tener display: block !important;o simplemente <div style="display: block">:-)
OZZIE
Funciona para mí en un archivo CSS como este .btn-group > .btn.d-none + .btn(utilizado para los grupos de entrada de bootstrap "
Jean-Charbel VANNIER
7

Creo que no es posible seleccionar por un valor CSS (pantalla)

editar:

en mi opinión, tendría sentido usar un poco de jquery aquí:

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

Solución JS pura (por ejemplo, cuando no utiliza jQuery u otro marco para otras cosas y no desea descargarlo solo para esta tarea):

<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
fuente
¡Gracias por el fragmento, la única respuesta que no es jQuery! Sin embargo, esto no funciona cuando se tienen que aplicar varios elementos primarios a: jsfiddle.net/uEeaA/100 . ¿Puede ayudarme a crear una solución para otros que funcione? Lo necesito, otros lo necesitan, así que por favor ayuda :)
mnsth
Me doy cuenta de que este es un hilo viejo, pero para cualquier visitante futuro, podría hacer algo como jsfiddle.net/uEeaA/103
xec
Quería votar este solo b / c que dejaste caer jQuery, bien por ti. Mi única queja es que un div se puede ocultar de la vista de muchas maneras, no solo en función del parámetro de estilo. Muy rápido: [1] el ancho y la altura se pueden establecer en 0, [2] la escala de transformación puede ser 0, [3] y podemos colocarla fuera del área visible.
Markus
4

Tratar

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

Tyler Wayne
fuente
2

de otra manera, puedes hacerlo con javascript, en Jquery puedes usar algo como:

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

*re-editado

eveevans
fuente
2

No es posible con CSS, sin embargo, podría hacerlo con jQuery.

DEMO JSFIDDLE

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 (solución anterior):

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

$items.each(function() {

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

});
martynas
fuente
3
Eso es mucho jQuery para $('li:visible:last').addClass('red').
alex
¿Eh? $('li').not(':hidden').last().addClass("red");
martynas
0

Si ya no necesita los elementos ocultos, simplemente use en element.remove()lugar de element.style.display = 'none';.

Masoud Shariati
fuente
-6

Esto funcionó para mí.

.alert:not(:first-child){
    margin: 30px;
}
kmukku
fuente
3
no estás respondiendo la pregunta
Serginho