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?

Miral
źródło

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.

VoteyDisciple
źródło
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
25
fyi, IE 9 obsługuje:last-child .
Jari Keinänen
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.

Branden Silva
źródło
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

Tarik
źródło
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;
}
ccpizza
źródło
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]-->
nzifnab
źródło
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.

lexx
źródło
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.

ecollis6
źródło
0

Dlaczego nie zastosować obramowania do spodu UL?

#refundReasonMenu #nav ul
{
    border-bottom: 1px solid #b5b5b5;
}
kotlet schabowy
źródło
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>
Ozzy
źródło
-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;
}
dziennik zmian
źródło