Selektor CSS dla zaznaczonej etykiety przycisku opcji

221

Czy można zastosować styl css (3) do etykiety zaznaczonego przycisku opcji?

Mam następujące znaczniki:

<input type="radio" id="rad" name="radio"/>
<label for="rad">A Label</label>

Miałem nadzieję, że to

label:checked { font-weight: bold; }

zrobiłbym coś, ale niestety nie (tak jak się spodziewałem).

Czy istnieje selektor, który może osiągnąć taką funkcjonalność? Jeśli to pomoże, możesz otoczyć div, itp., Ale najlepszym rozwiązaniem byłoby użycie atrybutu label „for”.

Należy zauważyć, że jestem w stanie określić przeglądarki dla mojej aplikacji, więc proszę o najlepszą klasę css3 itp.

Stephen
źródło

Odpowiedzi:

361

spróbuj +symbolu: Jest to kombinator łączący rodzeństwo. Łączy dwie sekwencje prostych selektorów mających tego samego rodzica, a druga musi NATYCHMIAST po pierwszej.

Takie jak:

input[type="radio"]:checked+label{ font-weight: bold; } 
 //a label that immediately follows an input of type radio that is checked 

działa bardzo ładnie dla następujących znaczników:

<input id="rad1" type="radio" name="rad"/><label for="rad1">Radio 1</label>
<input id="rad2" type="radio" name="rad"/><label for="rad2">Radio 2</label>

... i będzie działać dla dowolnej struktury, z div lub bez div itp., o ile etykieta podąża za sygnałem radiowym.

Przykład:

input[type="radio"]:checked+label { font-weight: bold; }
<input id="rad1" type="radio" name="rad"/><label for="rad1">Radio 1</label>
<input id="rad2" type="radio" name="rad"/><label for="rad2">Radio 2</label>

Stephen
źródło
11
Czy w ogóle można to zrobić, ale etykieta jest wcześniejszym elementem EG:<label for="rad1">Radio 1</label><input id="rad1" type="radio" name="rad">
Nathan Koop
17
Możesz użyć tyldy, ~aby wybrać elementy rodzeństwa, które niekoniecznie sąsiadują. css-tricks.com/child-and-sibling-selectors
Martin
1
Dzięki, pomogło mi to stworzyć „przyciski opcji obrazu” bez JS.
KillerX
9
Warto zauważyć, że nie będzie to działać w IE 8, ponieważ :checkedselektor nie jest obsługiwany .
Mark Amery
2
@Martin Na wszelki wypadek zastanawiasz się, że tak naprawdę nie zadziała w twoim przypadku, ponieważ etykieta nadal musi podążać za danymi wejściowymi. Różnica między znakami „+” i „~” polega na tym, czy etykieta jest bezpośrednio przylegająca, czy generalnie przylega : czy etykieta jest kolejnym elementem, czy tylko jednym z następnych elementów.
Njord
127

Wiem, że to stare pytanie, ale jeśli chcesz mieć <input>dziecko, <label>zamiast je rozdzielić, oto czysty sposób CSS, w jaki możesz to zrobić:

:checked + span { font-weight: bold; }

Następnie po prostu zawiń tekst <span>:

<label>
   <input type="radio" name="test" />
   <span>Radio number one</span>
</label>

Zobacz na JSFiddle .

Mikrofon
źródło
Doskonały. Jest to bardzo przydatne, gdy mamy do czynienia z sytuacją brzytwy <label>@Html.RadioButtonFor(..) someText<label>, rzuciłem <span>wokół „someText” i działało to jak urok. Dziękuję Ci!
S1r-Lanzelot
Miły! Nie myślałem o tym.
Matthew Dean
Dokładnie to, czego potrzebowałem! Dzięki.
Ryan
Co jeśli chcesz stylizować: aktywna etykieta z: zaznaczone? To nie jest tak naprawdę rozwiązanie.
Maciej Krawczyk
2
@MaciejKrawczyk To nie jest rozwiązanie dla Ciebie, ponieważ Twój przypadek użycia jest zupełnie inny. Jeśli chcesz stylizować etykietę: active, możesz to zrobić label:active { font-weight: bold; }. Zobacz: jsfiddle.net/Gbq8Z/608 (wow, nie wierzę, że skrzypce rozwidlono 608 razy).
Mike
22

Zapomniałem, gdzie pierwszy raz o tym wspomniałem, ale tak naprawdę możesz osadzić swoje etykiety w pojemniku w innym miejscu, o ile masz for=ustawiony atrybut. Sprawdźmy więc przykład SO:

* {
  padding: 0;
  margin: 0;
  background-color: #262626;
  color: white;
}

.radio-button {
  display: none;
}

#filter {
  display: flex;
  justify-content: center;
}

.filter-label {
  display: inline-block;
  border: 4px solid green;
  padding: 10px 20px;
  font-size: 1.4em;
  text-align: center;
  cursor: pointer;
}

main {
  clear: left;
}

.content {
  padding: 3% 10%;
  display: none;
}

h1 {
  font-size: 2em;
}

.date {
  padding: 5px 30px;
  font-style: italic;
}

.filter-label:hover {
  background-color: #505050;
}

#featured-radio:checked~#filter .featured,
#personal-radio:checked~#filter .personal,
#tech-radio:checked~#filter .tech {
  background-color: green;
}

#featured-radio:checked~main .featured {
  display: block;
}

#personal-radio:checked~main .personal {
  display: block;
}

#tech-radio:checked~main .tech {
  display: block;
}
<input type="radio" id="featured-radio" class="radio-button" name="content-filter" checked="checked">
<input type="radio" id="personal-radio" class="radio-button" name="content-filter" value="Personal">
<input type="radio" id="tech-radio" class="radio-button" name="content-filter" value="Tech">

<header id="filter">
  <label for="featured-radio" class="filter-label featured" id="feature-label">Featured</label>
  <label for="personal-radio" class="filter-label personal" id="personal-label">Personal</label>
  <label for="tech-radio" class="filter-label tech" id="tech-label">Tech</label>
</header>

<main>
  <article class="content featured tech">
    <header>
      <h1>Cool Stuff</h1>
      <h3 class="date">Today</h3>
    </header>

    <p>
      I'm showing cool stuff in this article!
    </p>
  </article>

  <article class="content personal">
    <header>
      <h1>Not As Cool</h1>
      <h3 class="date">Tuesday</h3>
    </header>

    <p>
      This stuff isn't nearly as cool for some reason :(;
    </p>
  </article>

  <article class="content tech">
    <header>
      <h1>Cool Tech Article</h1>
      <h3 class="date">Last Monday</h3>
    </header>

    <p>
      This article has awesome stuff all over it!
    </p>
  </article>

  <article class="content featured personal">
    <header>
      <h1>Cool Personal Article</h1>
      <h3 class="date">Two Fridays Ago</h3>
    </header>

    <p>
      This article talks about how I got a job at a cool startup because I rock!
    </p>
  </article>
</main>

Uff To było dużo jak na „próbkę”, ale wydaje mi się, że to naprawdę wpływa na efekt i punkt: możemy z pewnością wybrać etykietę dla sprawdzonej kontroli wejściowej, bez bycia rodzeństwem. Sekret polega na utrzymywaniu inputtagów dziecka tylko do tego, czym muszą być (w tym przypadku - tylko bodyelement) .

Ponieważ labelelement nie używa :checkedpseudo selektora, nie ma znaczenia, że ​​etykiety są przechowywane w header. Ma tę dodatkową zaletę, że ponieważ headerjest rodzeństwem, możemy użyć ~ogólnego selektora rodzeństwa, aby przejść z input[type=radio]:checkedelementu DOM do headerkontenera, a następnie użyć selektora potomka / potomka, aby uzyskać dostęp do labelsamych siebie, umożliwiając ich stylizację, gdy ich odpowiednie pola wyboru / pola wyboru są zaznaczone .

Nie tylko możemy stylizować etykiety, ale także stylizować inne treści, które mogą być potomkami kontenera rodzeństwa w stosunku do wszystkich inputliter. A teraz, na chwilę, na którą wszyscy czekali, JSFIDDLE ! Idź tam, baw się nim, spraw, by działał dla Ciebie, dowiedz się, dlaczego to działa, zepsuć go, rób to, co robisz!

Mam nadzieję, że wszystko to ma sens i w pełni odpowiada na pytanie oraz możliwe dalsze działania, które mogą się pojawić.

Nathan Blair
źródło
2
To jest odpowiedź na to pytanie. Inne, choć poprawne, są w gruncie rzeczy super podstawowe. Podczas gdy rozwiązuje to coś bardziej skomplikowanego i interesującego, można pokusić się o js.
morfuje
Przyjęta odpowiedź na to pytanie ma ponad 30 razy więcej głosów pozytywnych, pomimo narzucenia ograniczenia, które ta odpowiedź całkowicie eliminuje. W przeciwieństwie do wielu postów o podobnych poglądach, które podają oszałamiające informacje, faktycznie spełnia to żądanie. Niesamowita praca, wielkie dzięki.
naughtilus
1
@naughtilus - ta odpowiedź całkowicie eliminuje ograniczenie prostej odpowiedzi, ponieważ wyraźnie określa style dla każdej opcji. tj. Mój ogranicza cię do posiadania konwencji budowy; ten ogranicza cię do pisania css dla każdego przycisku opcji i wyniku.
Stephen
@morphles simple! = "super basic": to rozwiązanie jest bardziej skomplikowane, interesujące i wydajne - dla tego dokładnego kodu; mój będzie działał na wszystkich stronach zgodnie z 1 konwencją
Stephen
1

Jeśli Twój wkład jest elementem potomnym labeli masz więcej niż jedną etykietę, możesz połączyć sztuczkę @ Mike'a z Flexbox+ order.

wprowadź opis zdjęcia tutaj

HTML
<label class="switchLabel">
  <input type="checkbox" class="switch"/>
  <span class="left">Left</span>
  <span class="right">Right</span>
</label>
css
label.switchLabel {
  display: flex;
  justify-content: space-between;
  width: 150px;
}
.switchLabel .left   { order: 1; }
.switchLabel .switch { order: 2; }
.switchLabel .right  { order: 3; }

/* sibling selector ~ */
.switchLabel .switch:not(:checked) ~ span.left { color: lightblue }
.switchLabel .switch:checked ~ span.right { color: lightblue }

Zobacz na JSFiddle .

Uwaga: Selektor rodzeństwa działa tylko w obrębie tego samego rodzica. Aby obejść ten problem, możesz ukryć dane wejściowe na najwyższym poziomie za pomocą hakowania @Nathan Blair .

Qwerty
źródło
-1

Możesz użyć trochę jQuery:

$('input:radio').click(function(){
    $('label#' + $(this).attr('id')).toggleClass('checkedClass'); // checkedClass is defined in your CSS
});

Musisz również upewnić się, że zaznaczone przyciski opcji mają również odpowiednią klasę przy ładowaniu strony.

Dan Herd
źródło
3
Tak ... Oczywiście można to zrobić za pomocą javascript (frameworki), ale nie jest to tak proste, jak się wydaje. Co się stanie, jeśli coś innego już zaznaczyło to pole? Jaki skrypt usunie tę klasę, jeśli zostanie wybrane inne radio z tej samej grupy? Bardzo szybko się komplikuje. Chcę korzystać z wbudowanej funkcji przeglądarki + css, ponieważ będzie działać za każdym razem.
Stephen
4
Twój selektor powinien być$('label[for="' + $(this).attr('id') + '"]').toggleClass();
Wesley Murch
-3

AKTUALIZACJA:

Działa to tylko dla mnie, ponieważ nasz istniejący wygenerowany HTML był zwariowany, generując labels wraz z radiosi nadając im oba checkedatrybuty.

Nieważne, i wielkie plusy dla Brilliand za podniesienie go!

Jeśli twoja etykieta jest rodzeństwem pola wyboru (co zwykle ma miejsce), możesz użyć ~selektora rodzeństwa i a, label[for=your_checkbox_id]aby go rozwiązać ... lub nadać etykiecie identyfikator, jeśli masz wiele etykiet (tak jak w tym przykładzie, w którym I użyj etykiet dla przycisków)


Przybyłem tutaj, szukając tego samego - ale ostatecznie znalazłem moją odpowiedź w dokumentacji .

labelelement o checkedatrybut może być wybrany w taki sposób:

label[checked] {
  ...
}

Wiem, że to stare pytanie, ale może pomaga komuś tam :)

apprenticeDev
źródło
5
A jak etykieta ma zostać sprawdzona?
Brilliand
2
Hej, dobry chwyt. Tak nie jest. Najwyraźniej mamy jakiś dość zwariowany kod, który generuje etykiety wraz z przyciskami opcji i dodaje atrybut „zaznaczony” do obu podczas generowania HTML. Ale to nie jest tak naprawdę ważne ... Więc to jest całkowicie bezużyteczne. Zmienię odpowiedź, nie mam pojęcia, dlaczego otrzymałem za nią głosy poparcia. Dzięki!
apprenticeDev