Селектор CSS, чтобы получить последний видимый div

162

Сложный вопрос селектора CSS, не знаю, возможно ли это вообще.

Допустим, это макет HTML:

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

Я хочу выбрать последний div, который отображается (т.е. нет display:none), который будет третьим divв данном примере. Имейте в виду, количество divs на реальной странице может отличаться (даже display:noneте).

Вишал Шах
источник

Ответы:

63

Вы можете выбрать и стилизовать это с помощью JavaScript или jQuery, но только CSS не может этого сделать.

Например, если у вас реализован jQuery на сайте, вы можете просто сделать:

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

Хотя, надеюсь, у вас будет класс / ID, обернутый вокруг выбранных вами div, в этом случае ваш код будет выглядеть так:

var last_visible_element = $('#some-wrapper div:visible:last');
Сюрреалистические мечты
источник
22
в вопросе четко сказано «нет JQuery CSS Selector», говорится «CSS SELECTOR», это должно быть принято ANSWER = P
AgelessEssence
2
Это, действительно, ответ на оригинальный вопрос. Спрашивающий никогда не упоминал javascript или jquery, и эти теги были добавлены другим ответчиком. 1nfected - вы действительно хотите JQuery? Если да, то, пожалуйста, укажите это в своем вопросе. В противном случае вам следует принять этот ответ.
Джип
Я думаю, что JQuery является приемлемым для ОП. В конце концов, это было принятое решение.
Сюрреалистические сны
7
Почему первый ответ allllwaaayyysss JQuery? Это javascript ответ на вопрос CSS . CSS! == javascript
dudewad
2
@dudewad: см. последнюю часть первого предложения: «но только CSS не может этого сделать». Ответ может оставить это в покое, без альтернативы в поле зрения ... или предоставить альтернативу. Но этот ответ, по крайней мере, проявил должную осмотрительность, заявив, что CSS не может делать то, о чем его просят (хотя и не уточняет, почему ). С другой стороны, ответ , который просто уходит на решение JavaScript , не признавая CSS характер вопроса является стоит критиковать.
BoltClock
23

Реальный ответ на этот вопрос, вы не можете сделать это. Альтернативы только для CSS-ответов не являются правильными ответами на этот вопрос, но если JS-решения приемлемы для вас, вам следует выбрать один из ответов JS или jQuery здесь. Однако, как я уже говорил выше, верный и правильный ответ заключается в том, что вы не можете сделать это в CSS надежно, если вы не готовы принять :notоператор с [style*=display:none]и другими подобными отрицательными селекторами, который работает только на встроенных стилях и в целом плохо решение.

dudewad
источник
Во-первых, я согласен с вами, но я думаю, что использование :notоператора, как вы заявили, может работать при определенных обстоятельствах. Например, это отлично работает для моей ситуации, когда у меня есть условно скрывающие элементы JS, которые затем добавляют встроенные стили, и, таким образом, ваше решение действительно работает отлично :)
doz87
1
Ну, тогда, я думаю, что работает, я просто немного идеалист, и мне нравится подчеркивать, где вещи не самые лучшие, важно уметь различать, что «хак», а что нет, потому что это делает нас лучше программистов.
dudewad
Да, я слышу, я согласен, что это решение не должно использоваться в качестве решения только для css для запроса OP, я думаю, что это работает очень хорошо, когда используется вместе с JS.
doz87
Вы также можете использовать класс CSS, чтобы скрыть элементы (вместо встроенного стиля). Если это так, вы можете также отрицать селектор для этого скрытого класса. Это всегда выбирает то же самое, что скрыто, потому что оба установлены одним и тем же классом CSS. Таким образом, ваш ответ идет в правильном направлении, но недостаточно далеко. :-)
ygoe
8

Если вы можете использовать встроенные стили, то вы можете сделать это исключительно с помощью CSS.

Я использую это для выполнения CSS на следующем элементе, когда предыдущий виден:

div [style = 'display: block;'] + table {
  фильтр: размытие (3 пикселя);
}
Алекс Гранде
источник
1
Я бы поменял его на [style*='display: block']так как мог бы display: block !important;или просто <div style="display: block">:-)
OZZIE
Это работает для меня в файле CSS, как это .btn-group > .btn.d-none + .btn(используется для входных групп начальной загрузки "
Жан-Шарбель
7

Я думаю, что невозможно выбрать по значению CSS (дисплей)

редактировать:

на мой взгляд, здесь есть смысл использовать немного jquery:

$('#your_container > div:visible:last').addClass('last-visible-div');
Guillaume86
источник
6

Чистое решение JS (например, когда вы не используете jQuery или другую инфраструктуру для других вещей и не хотите загружать это только для этой задачи):

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

пантера
источник
Спасибо за фрагмент, единственный не-jQuery ответ! Тем не менее, это не работает при наличии нескольких родительских элементов для обращения к: jsfiddle.net/uEeaA/100 - можете ли вы помочь мне создать решение для других, которые работают? Мне это нужно, другие нуждаются, поэтому , пожалуйста , помогите :)
mnsth
Я понимаю, что это старая ветка, но для любых будущих посетителей вы можете сделать что-то вроде jsfiddle.net/uEeaA/103
xec
Я хотел бы проголосовать до этого, потому что вы отказались от jQuery - хорошо для вас. Моя единственная жалоба на то, что div может быть скрыт от просмотра разными способами, а не только на основе параметра style. Очень быстро: ширина и высота [1] могут быть установлены в 0, масштаб преобразования [2] может быть 0, [3], и мы можем разместить его вне видимой области.
Маркус
4

Пытаться

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

Тайлер Уэйн
источник
2

иначе вы можете сделать это с помощью javascript, в Jquery вы можете использовать что-то вроде:

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

* переиздавались

eveevans
источник
2

Это невозможно с помощью CSS, однако вы можете сделать это с помощью 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 (предыдущее решение):

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

$items.each(function() {

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

});
Martynas
источник
3
Это много jQuery для $('li:visible:last').addClass('red').
Алекс
А? $('li').not(':hidden').last().addClass("red");
Мартинас
0

Если вам больше не нужны скрытые элементы, просто используйте element.remove()вместо element.style.display = 'none';.

Масуд Шариати
источник
-6

Это сработало для меня.

.alert:not(:first-child){
    margin: 30px;
}
kmukku
источник
3
Вы не отвечаете на вопрос
Сержиньо,