Un sélecteur CSS pour obtenir la dernière div visible

162

Une question de sélection CSS délicate, je ne sais pas si c'est même possible.

Disons que c'est la mise en page HTML:

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

Je veux sélectionner le dernier div, qui est affiché (c'est-à-dire non display:none) qui serait le troisième divdans l'exemple donné. Remarquez que le nombre de divs sur la page réelle peut différer (même display:noneceux).

Vishal Shah
la source

Réponses:

63

Vous pouvez sélectionner et styliser cela avec JavaScript ou jQuery, mais CSS seul ne peut pas le faire.

Par exemple, si vous avez implémenté jQuery sur le site, vous pouvez simplement faire:

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

Bien que j'espère que vous aurez une classe / un ID enroulé autour des divs que vous sélectionnez, auquel cas votre code ressemblerait à:

var last_visible_element = $('#some-wrapper div:visible:last');
Rêves surréalistes
la source
22
la question dit clairement non "un sélecteur CSS JQuery", dit "Un sélecteur CSS", cela devrait être le ANSWER = P accepté
AgelessEssence
2
Telle est, en effet, la réponse à la question initiale. Le questionneur n'a jamais mentionné javascript ou jquery et ces balises ont été ajoutées par un autre répondant. 1nfected - voulez-vous réellement jQuery? Si tel est le cas, veuillez le mettre dans votre question. Sinon, vous devriez accepter cette réponse à la place.
jep
Je pense que jQuery est acceptable pour l'OP. C'était la solution acceptée, après tout.
Surreal Dreams
7
Whhyyyy est la première réponse allllwaaayyysss jquery? Ceci est une réponse javascript à une question CSS . CSS! == javascript
dudewad
2
@dudewad: Voir la dernière partie de la première phrase: "mais CSS seul ne peut pas faire ça." La réponse pourrait en rester là, sans alternative en vue ... ou fournir une alternative. Mais cette réponse a au moins fait sa diligence raisonnable en déclarant en fait que CSS ne peut pas faire ce qui est demandé (bien qu'elle n'explique pas pourquoi ). D'autre part, une réponse qui vient se déclenche sur une solution JavaScript sans reconnaître la nature CSS de la question est une valeur critique.
BoltClock
23

La vraie réponse à cette question est que vous ne pouvez pas le faire. Les alternatives aux réponses CSS uniquement ne sont pas des réponses correctes à cette question, mais si les solutions JS vous conviennent, vous devez choisir l'une des réponses JS ou jQuery ici. Cependant, comme je l'ai dit ci-dessus, la vraie et bonne réponse est que vous ne pouvez pas le faire de manière fiable en CSS à moins que vous ne soyez prêt à accepter l' :notopérateur avec [style*=display:none]et d'autres sélecteurs inversés, qui ne fonctionnent que sur les styles en ligne, et sont globalement médiocres. Solution.

dudewad
la source
Premièrement, je suis d'accord avec vous, mais je pense que l'utilisation de l' :notopérateur comme vous l'avez indiqué peut fonctionner dans certaines circonstances. Par exemple, cela fonctionne parfaitement pour ma situation où j'ai JS cachant conditionnellement des éléments qui ajoutent ensuite des styles en ligne et donc votre solution fonctionne parfaitement :)
doz87
1
Eh bien, alors je suppose que ce qui fonctionne fonctionne :) Je suis juste un peu idéaliste et j'aime souligner là où les choses ne sont pas les meilleures, il est important de pouvoir distinguer ce qui est `` hacky '' et ce qui ne l'est pas parce que cela fait de nous tous de meilleurs programmeurs.
dudewad
Oui, je vous entends, je suis d'accord que cette solution ne doit pas être utilisée comme une solution css uniquement à la requête OP, je pense que cela fonctionne très bien lorsqu'elle est utilisée en conjonction avec JS.
doz87
Vous pouvez également utiliser une classe CSS pour masquer des éléments (au lieu d'un style en ligne). Si tel est le cas, vous pouvez tout aussi bien annuler le sélecteur pour cette classe de masquage. Cela sélectionne toujours le même ce qui est caché car les deux sont définis par la même classe CSS. Votre réponse va donc dans la bonne direction mais pas assez loin. :-)
ygoe
8

Si vous pouvez utiliser des styles en ligne, vous pouvez le faire uniquement avec CSS.

J'utilise ceci pour faire du CSS sur l'élément suivant lorsque le précédent est visible:

div [style = 'display: block;'] + table {
  filtre: flou (3px);
}
Alex Grande
la source
1
Je le changerais [style*='display: block']car il aurait pu display: block !important;ou tout simplement <div style="display: block">:-)
OZZIE
Cela fonctionne pour moi dans un fichier css comme celui-ci .btn-group > .btn.d-none + .btn(utilisé pour les groupes d'entrée de bootstrap "
Jean-Charbel VANNIER
7

Je pense qu'il n'est pas possible de sélectionner par une valeur css (affichage)

Éditer:

à mon avis, il serait logique d'utiliser un peu de jquery ici:

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

Solution Pure JS (par exemple, lorsque vous n'utilisez pas jQuery ou un autre framework pour d'autres choses et que vous ne voulez pas le télécharger uniquement pour cette tâche):

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

panthère
la source
Merci pour l'extrait, la seule réponse non jQuery! Cependant, cela ne fonctionne pas lorsque vous avez plusieurs éléments parents à appliquer à: jsfiddle.net/uEeaA/100 - pouvez-vous m'aider à créer une solution pour d'autres qui fonctionne? J'en ai besoin, d'autres en ont besoin, alors aidez
moi
Je me rends compte que c'est un vieux fil de discussion, mais pour tous les futurs visiteurs, vous pouvez faire quelque chose du genre jsfiddle.net/uEeaA/103
xec
Je voulais voter pour ça juste parce que tu as laissé tomber jQuery - tant mieux. Mon seul reproche est qu'un div peut être caché de la vue de plusieurs façons, pas seulement en fonction du paramètre de style. Vraiment rapide: [1] la largeur et la hauteur peuvent être définies sur 0, [2] l'échelle de transformation peut être 0, [3] et nous pouvons la placer hors de la zone visible.
Markus
4

Essayer

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

Tyler Wayne
la source
2

d'une autre manière, vous pouvez le faire avec javascript, dans Jquery, vous pouvez utiliser quelque chose comme:

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

* réédité

eveevans
la source
2

Ce n'est pas possible avec CSS, mais vous pouvez le faire avec jQuery.

DÉMO 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 (solution précédente):

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

$items.each(function() {

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

});
martynas
la source
3
C'est beaucoup de jQuery pour $('li:visible:last').addClass('red').
alex
Hein? $('li').not(':hidden').last().addClass("red");
martynas
0

Si vous n'avez plus besoin des éléments masqués, utilisez simplement à la element.remove()place de element.style.display = 'none';.

Masoud Shariati
la source
-6

Cela a fonctionné pour moi.

.alert:not(:first-child){
    margin: 30px;
}
kmukku
la source
3
vous ne répondez pas à la question
Serginho