Sélecteur CSS pour l'étiquette d'un bouton radio coché

221

Est-il possible d'appliquer un style css (3) à une étiquette d'un bouton radio coché?

J'ai le balisage suivant:

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

J'espérais que

label:checked { font-weight: bold; }

ferait quelque chose, mais hélas pas (comme je m'y attendais).

Existe-t-il un sélecteur capable de réaliser ce type de fonctionnalité? Vous pouvez entourer de divs, etc. si cela vous aide, mais la meilleure solution serait celle qui utilise l'attribut '' for ''.

Il convient de noter que je suis en mesure de spécifier des navigateurs pour mon application, donc le meilleur de la classe css3, etc. s'il vous plaît.

Stephen
la source

Réponses:

362

essayez le +symbole: Il s'agit du combinateur frère adjacent. Il combine deux séquences de sélecteurs simples ayant le même parent et la seconde doit venir IMMÉDIATEMENT après la première.

En tant que tel:

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

fonctionne très bien pour le balisage suivant:

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

... et cela fonctionnera pour n'importe quelle structure, avec ou sans div etc., tant que l'étiquette suit l'entrée radio.

Exemple:

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
la source
11
Y a-t-il de toute façon à le faire, mais avec l'étiquette étant l'élément prioritaire EG:<label for="rad1">Radio 1</label><input id="rad1" type="radio" name="rad">
Nathan Koop
17
Vous pouvez utiliser un tilda ~pour sélectionner des éléments de la fratrie qui ne sont pas nécessairement adjacents. css-tricks.com/child-and-sibling-selectors
Martin
1
Merci, cela m'a juste aidé à créer des "boutons radio image" sans JS.
KillerX
9
Il convient de noter que cela ne fonctionnera pas dans IE 8, car le :checkedsélecteur n'est pas pris en charge .
Mark Amery
2
@Martin Juste au cas où vous vous poseriez la question, cela ne fonctionnera pas dans votre cas, car l'étiquette doit toujours suivre l'entrée. La différence entre «+» et «~» est de savoir si l'étiquette est directement adjacente, ou est généralement adjointe: si l'étiquette est l' élément suivant , ou juste l' un des éléments suivants .
Njord
127

Je sais que c'est une vieille question, mais si vous souhaitez <input>être un enfant <label>au lieu de les séparer, voici une manière CSS pure que vous pouvez y parvenir:

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

Ensuite, enveloppez simplement le texte avec un <span>:

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

Voir sur JSFiddle .

Mike
la source
Excellent. Ceci est très utile pour gérer la situation du rasoir <label>@Html.RadioButtonFor(..) someText<label>, j'ai jeté <span>"someText" et cela a fonctionné comme un charme. Je vous remercie!
S1r-Lanzelot
Agréable! Je n'avais pas pensé à ça.
Matthew Dean
Juste ce dont j'avais besoin! Merci.
Ryan
Et si vous voulez styliser: étiquette active avec: cochée? Ce n'est pas vraiment une solution.
Maciej Krawczyk
2
@MaciejKrawczyk Ce n'est pas une solution pour vous car votre cas d'utilisation est complètement différent. Si vous voulez styliser une étiquette: active, vous pouvez simplement le faire label:active { font-weight: bold; }. Voir: jsfiddle.net/Gbq8Z/608 (wow, je ne peux pas croire que le violon a été bifurqué 608 fois).
Mike
22

J'oublie où je l'ai vu mentionné pour la première fois, mais vous pouvez réellement intégrer vos étiquettes dans un conteneur ailleurs tant que vous avez l' for=attribut défini. Voyons donc un exemple sur 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>

Ouf. C'était beaucoup pour un "échantillon" mais je pense que cela fait vraiment ressortir l'effet et le point: nous pouvons certainement sélectionner une étiquette pour un contrôle d'entrée vérifié sans que ce soit un frère. Le secret réside dans le fait de garder les inputbalises d'un enfant uniquement à ce qu'il doit être (dans ce cas - uniquement l' bodyélément) .

Puisque l' labelélément n'utilise pas réellement le :checkedpseudo-sélecteur, peu importe que les étiquettes soient stockées dans le header. Cela a l'avantage supplémentaire que puisque headerc'est un élément frère, nous pouvons utiliser le ~sélecteur frère générique pour passer de l' input[type=radio]:checkedélément DOM au headerconteneur, puis utiliser des sélecteurs descendants / enfants pour accéder aux labels eux-mêmes, ce qui permet de les styliser lorsque leur les cases / cases à cocher radio respectives sont sélectionnées .

Non seulement nous pouvons styliser les étiquettes, mais également styler d'autres contenus qui peuvent être les descendants d'un conteneur frère par rapport à tous les inputs. Et maintenant, pour le moment que vous attendiez tous, le JSFIDDLE ! Allez-y, jouez avec, faites-le fonctionner pour vous, découvrez pourquoi cela fonctionne, cassez-le, faites ce que vous faites!

J'espère que tout cela a du sens et répond pleinement à la question et éventuellement à tout suivi qui pourrait survenir.

Nathan Blair
la source
2
Telle est la réponse à cette question. D'autres, bien que corrects, sont essentiellement super basiques. Bien que cela résout quelque chose de plus compliqué et intéressant, celui-ci serait tenté de saisir js.
morphles
La réponse acceptée à cette question a> 30 fois plus de votes positifs malgré l'imposition d'une limitation que cette réponse évite totalement. Contrairement à de nombreux articles similaires qui prétendent des informations époustouflantes, cela répond en fait à la revendication. Un travail incroyable, merci beaucoup.
naughtilus
1
@naughtilus - cette réponse évite totalement la limitation de la réponse simple, car elle définit explicitement les styles pour chaque option. ie Mine vous contraint à avoir une convention de structure; celui-ci vous oblige à écrire css pour chaque bouton radio et résultat.
Stephen
@morphles simple! = "super basique": cette solution est plus compliquée, intéressante et puissante - pour ce code exact; le mien travaillera sur toutes les pages après 1 convention
Stephen
1

Si votre entrée est un élément enfant de la labelet que vous avez plusieurs étiquettes, vous pouvez combiner l'astuce de @ Mike avec Flexbox+ order.

entrez la description de l'image ici

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 }

Voir sur JSFiddle .

Remarque: le sélecteur de frères et sœurs ne fonctionne que dans le même parent. Pour contourner ce problème , vous pouvez masquer l'entrée au niveau supérieur à l'aide du hack @Nathan Blair .

Qwerty
la source
-1

Vous pouvez utiliser un peu de jQuery:

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

Vous devez également vous assurer que vos boutons radio cochés ont également la bonne classe lors du chargement de la page.

Dan Herd
la source
3
Oui ... il est bien sûr possible de le faire via javascript (frameworks), mais ce n'est pas aussi simple qu'il y paraît. Que se passe-t-il si autre chose a déjà coché la case? Quel script supprimera cette classe si une autre radio du même groupe est sélectionnée? Cela devient trop compliqué très rapidement. Je veux utiliser la fonctionnalité intégrée de formulaire + css du navigateur, car elle fonctionnera à chaque fois.
Stephen
4
Votre sélecteur devrait être$('label[for="' + $(this).attr('id') + '"]').toggleClass();
Wesley Murch
-3

METTRE À JOUR:

Cela ne fonctionnait que pour moi parce que notre code HTML généré était farfelu, générant des labels avec des radios et leur donnant les deux checkedattributs.

Tant pis, et bravo à Brilliand pour l'avoir soulevé!

Si votre étiquette est le frère d'une case à cocher (ce qui est généralement le cas), vous pouvez utiliser le ~ sélecteur de frère et a label[for=your_checkbox_id]pour l'adresser ... ou donner un identifiant à l'étiquette si vous avez plusieurs étiquettes (comme dans cet exemple où je utiliser des étiquettes pour les boutons)


Je suis venu ici à la recherche de la même chose - mais j'ai fini par trouver ma réponse dans les documents .

une label élément avec checkedattribut peut être sélectionné comme suit:

label[checked] {
  ...
}

Je sais que c'est une vieille question, mais peut-être que ça aide quelqu'un là-bas :)

apprenticeDev
la source
5
Et comment l'étiquette doit-elle être vérifiée?
Brilliand
2
Hé, bonne prise. Ce n'est pas le cas. Apparemment, nous avons un code assez farfelu qui génère des étiquettes avec des boutons radio et ajoute un attribut "vérifié" aux deux lors de la génération du code HTML. Mais ce n'est pas vraiment valable ... Donc c'est totalement inutilisable. Je vais modifier la réponse, je ne sais pas pourquoi j'ai obtenu les votes positifs. Merci!
apprenticeDev