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.