Korzystanie z selektora ostatniego dziecka


106

Moim celem jest zastosowanie CSS na końcu li, ale tak się nie dzieje.

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

Jak mogę wybrać tylko ostatnie dziecko?

Odpowiedzi:


171

:last-childPseudoclass nadal nie można wiarygodnie wykorzystane w różnych przeglądarkach. W szczególności wersje Internet Explorer <9 i Safari <3,2 pewno nie wspierają go , choć Internet Explorer 7 i Safari 3.2 zrobić wsparcia :first-child, z zaciekawieniem.

Najlepszym rozwiązaniem jest jawne dodanie last-child(lub podobnej) klasy do tego przedmiotu i zastosowanie li.last-childzamiast tego.


46
IE8 też nie obsługuje :last-child. I to nie jest takie ciekawe. :first-childjest pseudoklasą CSS2, pseudoklasą :last-childCSS3.
mercator

92
last-child działa we wszystkich nowoczesnych przeglądarkach, co oznacza, że ​​oczywiście nie działa w żadnej wersji IE.
Rob


6
@mercator Ciekawe, że: first-child zostało zaimplementowane w CSS2, ale: last-child zostało pozostawione do CSS3 ... wydaje się dość oczywiste dodanie ich w tym samym czasie.
Cobby

21
IE7 odmawia uznania innych bękartów
Dewayne

76

Innym rozwiązaniem, które może Ci się przydać, jest odwrócenie relacji. Więc ustawiasz obramowanie dla wszystkich elementów listy. Następnie użyłbyś first-child, aby usunąć obramowanie dla pierwszego przedmiotu. Pierwsze dziecko jest obsługiwane statycznie we wszystkich przeglądarkach (co oznacza, że ​​nie może być dodawane dynamicznie przez inny kod, ale pierwsze dziecko jest selektorem CSS2, podczas gdy ostatnie dziecko zostało dodane w specyfikacji CSS3)

Uwaga: Działa to tak, jak zamierzałeś, tylko wtedy, gdy masz na liście tylko 2 elementy, takie jak przykład. Każda trzecia i następna pozycja będzie miała zastosowane obramowanie.


2
+1 do nieszablonowego myślenia :-) Właśnie przekonwertowałem moje elementy ostatniego dziecka na pierwsze dziecko i zmieniłem przez border-right na border-left dla separatorów menu. Teraz IE8 lubi mój css.
Scott B

43

Jeśli myślisz, że możesz używać Javascript, to od czasu obsługi jQuery last-childmożesz użyć metody css jQuery i dobrze, że będzie ona obsługiwać prawie wszystkie przeglądarki

Przykładowy kod:

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

Więcej informacji na ten temat można znaleźć tutaj: http://api.jquery.com/css/#css2


8
Porozmawiaj o brudnych.
md1337

95
Lepiej zrobić coś takiego $("#nav li:last-child").addClass('last-child'), żebyś mógł zachować swój styl w swoich arkuszach stylów.
jason

Jest to czystsze niż pierwsze rozwiązanie, ponieważ jest obsługiwane automatycznie. Ale zgadzam się też z Jasonem.
Josh M.

1
W rzeczywistości IE7 nie ładuje klasy, która ma zarówno div:last-childi div.last-child. Wygląda na to, że uważa :last-childskładnię za niepoprawną i żadna klasa z tym pseudo-selektorem nie zostanie zastosowana.
Josh M.

@Josh M .: To prawidłowe i oczekiwane zachowanie. Powinienem powiedzieć, że to dość niefortunne. Musiałbyś powielić regułę.
BoltClock

19

Jeśli liczba elementów listy jest stała, możesz użyć sąsiedniego selektora, np. Jeśli masz tylko trzy <li>elementy, możesz wybrać ostatni za <li>pomocą:

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

3
Twój selektor jest zły. li + #nav liwybiera liwnętrze, #navktóre nastąpi później li. Twój selektor powinien po prostu być #nav li + li + li.
BoltClock

1
To fajne. Działa dobrze w IE8, ale nie w IE7.
Mateng

13

Jeśli często potrzebujesz selektorów CSS3, zawsze możesz skorzystać z biblioteki selectivizr w swojej witrynie:

http://selectivizr.com/

Jest to skrypt JS, który dodaje obsługę prawie wszystkich selektorów CSS3 do przeglądarek, które inaczej by ich nie obsługiwały.

Wrzuć to do swojego <head>tagu za pomocą warunku IE:

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


0

Alternatywnie do używania klasy możesz użyć szczegółowej listy, ustawiając elementy potomne dt tak, aby miały jeden styl, a elementy potomne dd, aby miały inny. Twój przykład wyglądałby następująco:

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

Żadna metoda nie jest lepsza od drugiej i zależy to tylko od osobistych preferencji.


0

Innym sposobem jest użycie selektora ostatniego potomka w jQuery, a następnie użycie metody .css (). Bądź jednak zmęczony, ponieważ niektórzy ludzie wciąż są w epoce kamienia łupanego i używają przeglądarek z wyłączoną obsługą JavaScript.


0

Dlaczego nie zastosować obramowania do spodu UL?

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

1
Jeśli masz padding-bottomna <ul>elemencie lub margin-bottomna ostatnim <li>elemencie, nie będzie to miało pożądanego umieszczenia tuż pod ostatnim <li>elementem. W przeciwnym razie jest to dobre rozwiązanie.
Wex

0

Jeśli pływasz elementami, możesz odwrócić kolejność

to znaczy float: right; zamiastfloat: left;

Następnie użyj tej metody, aby wybrać pierwsze dziecko klasy.

/* 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;
}

W rzeczywistości jest to stosowanie tej klasy tylko do OSTATNIEJ instancji, ponieważ jest teraz w odwrotnej kolejności.

Oto działający przykład:

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

Trudno powiedzieć, nie widząc reszty CSS, ale spróbuj dodać !importantkolor przed obramowaniem, aby wyglądało tak:

#refundReasonMenu #nav li:last-child
{
  border-bottom: 1px solid #b5b5b5 !important;
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.