Использование селектора последнего дочернего элемента


106

Моя цель - применить CSS к последнему li, но он этого не делает.

#refundReasonMenu #nav li:last-child {
    border-bottom: 1px solid #b5b5b5;
}
<div id="refundReasonMenu">
    	<ul id="nav">
    		<li><a id="abc" href="#">abcde</a></li>
    		<li><a id="def" href="#">xyz</a></li>
    	</ul>
    </div>

Как выбрать только последнего ребенка?

Ответы:


171

:last-childPseudoclass до сих пор не может быть надежно использоваться во всех браузерах. В частности, Internet Explorer версии <9 и Safari <3,2 определенно не поддерживают его , хотя Internet Explorer 7 и Safari 3.2 сделать поддержку :first-child, как ни странно.

Лучше всего явно добавить last-childк этому элементу (или аналогичный) класс и применить его li.last-childвместо него.


46
IE8 тоже не поддерживает :last-child. И это не что любопытно. :first-childэто псевдокласс CSS2, псевдокласс :last-childCSS3.
mercator

92
last-child работает во всех современных браузерах, что означает, конечно, не работает ни в одной версии IE.
Роб


6
@mercator Любопытно, что: first-child был реализован в CSS2, но: last-child остался до появления CSS3 ... кажется довольно очевидным, чтобы добавить их одновременно.
Cobby

21
IE7 отказывается признавать других внебрачных детей
Дьюэйн

76

Еще одно решение, которое может сработать для вас, - это изменить отношения. Таким образом, вы должны установить границу для всех элементов списка. Затем вы должны использовать first-child, чтобы удалить границу для первого элемента. Первый дочерний элемент статически поддерживается во всех браузерах (это означает, что он не может быть добавлен динамически через другой код, но первый дочерний элемент является селектором CSS2, тогда как последний ребенок был добавлен в спецификации CSS3)

Примечание. Это работает только так, как вы планировали, если у вас есть только 2 элемента в списке, как в вашем примере. К любому третьему элементу и далее будут применены границы.


2
+1 для нестандартного мышления :-) Я только что преобразовал свои элементы last-child в first-child и изменил с помощью border-right на border-left для разделителей меню. Теперь IE8 нравится мой css.
Скотт Би

43

Если вы думаете, что можете использовать Javascript, то, поскольку поддержка jQuery last-child, вы можете использовать метод css jQuery, и, что хорошо, он будет поддерживать почти все браузеры.

Пример кода:

$(function(){
   $("#nav li:last-child").css("border-bottom","1px solid #b5b5b5")
})

Вы можете найти больше информации здесь: http://api.jquery.com/css/#css2


8
Поговорим о грязном.
md1337

95
Уэй, лучше сделать что-нибудь подобное, $("#nav li:last-child").addClass('last-child')чтобы сохранить стиль в таблицах стилей.
Джейсон

Это чище, чем первое решение, так как оно обрабатывается автоматически. Но я тоже согласен с Джейсоном.
Джош М.

1
На самом деле IE7 не загружает класс, в котором есть div:last-childи div.last-child. Похоже, что он считает :last-childсинтаксис недопустимым, и любой класс с этим псевдоселектором не будет применяться.
Джош М.

@Josh M .: Это правильное и ожидаемое поведение. Должен сказать, весьма прискорбно. Вам придется продублировать правило.
BoltClock

19

Если количество элементов списка фиксировано, вы можете использовать соседний селектор, например, если у вас всего три <li>элемента, вы можете выбрать последний <li>с помощью:

#nav li+li+li {
    border-bottom: 1px solid #b5b5b5;
}

3
Ваш селектор неправильный. li + #nav liвыбирает liвнутри, #navчто идет после li. Ваш селектор должен быть просто #nav li + li + li.
BoltClock

1
Это здорово. Прекрасно работает в IE8, но не в IE7.
Mateng

13

Если вам часто нужны селекторы CSS3, вы всегда можете использовать библиотеку selectivizr на своем сайте:

http://selectivizr.com/

Это JS-скрипт, который добавляет поддержку почти всех селекторов CSS3 в браузеры, которые иначе не поддерживали бы их.

Добавьте его в свой <head>тег с условным IE:

<!--[if (gte IE 6)&(lte IE 8)]>
  <script src="/js/selectivizr-min.js" type="text/javascript"></script>
<![endif]-->


0

В качестве альтернативы использованию класса вы можете использовать подробный список, задав для дочерних элементов dt один стиль, а для дочерних элементов dd - другой. Ваш пример станет:

#refundReasonMenu #nav li:dd
{
  border-bottom: 1px solid #b5b5b5;
}

html:

<div id="refundReasonMenu">
  <dl id="nav">
        <dt><a id="abc" href="#">abcde</a></dt>
        <dd><a id="def" href="#">xyz</a></dd>
  </dl>
</div>

Ни один из методов не лучше другого, и это зависит только от личных предпочтений.


0

Другой способ сделать это - использовать селектор last-child в jQuery, а затем использовать метод .css (). Однако будьте утомлены, потому что некоторые люди все еще находятся в каменном веке, используя браузеры с отключенным JavaScript.


0

Почему бы не применить границу к нижней части UL?

#refundReasonMenu #nav ul
{
    border-bottom: 1px solid #b5b5b5;
}

1
Если у вас есть padding-bottomна <ul>элементе или margin-bottomна последнем <li>элементе, это не будет иметь желаемого размещению прямо под последний <li>элемент. В остальном это хорошее решение.
Wex

0

Если вы перемещаете элементы, вы можете изменить их порядок

т.е. float: right;вместоfloat: left;

А затем используйте этот метод, чтобы выбрать первого ребенка класса.

/* 1: Apply style to ALL instances */
#header .some-class {
  padding-right: 0;
}
/* 2: Remove style from ALL instances except FIRST instance */
#header .some-class~.some-class {
  padding-right: 20px;
}

Фактически это применяет класс к ПОСЛЕДНЕМУ экземпляру только потому, что теперь он работает в обратном порядке.

Вот вам рабочий пример:

<!doctype html>
<head><title>CSS Test</title>
<style type="text/css">
.some-class { margin: 0; padding: 0 20px; list-style-type: square; }
.lfloat { float: left; display: block; }
.rfloat { float: right; display: block; }
/* apply style to last instance only */
#header .some-class {
  border: 1px solid red;
  padding-right: 0;
}
#header .some-class~.some-class {
  border: 0;
  padding-right: 20px;
}
</style>
</head>
<body>
<div id="header">
  <img src="some_image" title="Logo" class="lfloat no-border"/>
  <ul class="some-class rfloat">
    <li>List 1-1</li>
    <li>List 1-2</li>
    <li>List 1-3</li>
  </ul>
  <ul class="some-class rfloat">
    <li>List 2-1</li>
    <li>List 2-2</li>
    <li>List 2-3</li>
  </ul>
  <ul class="some-class rfloat">
    <li>List 3-1</li>
    <li>List 3-2</li>
    <li>List 3-3</li>
  </ul>
  <img src="some_other_img" title="Icon" class="rfloat no-border"/>
</div>
</body>
</html>

-2

Трудно сказать, не видя остальной части вашего CSS, но попробуйте добавить !importantперед цветом границы, чтобы получилось так:

#refundReasonMenu #nav li:last-child
{
  border-bottom: 1px solid #b5b5b5 !important;
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.