Selettore CSS per l'etichetta di un pulsante di opzione controllato


221

È possibile applicare uno stile css (3) a un'etichetta di un pulsante di opzione selezionato?

Ho il seguente markup:

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

Quello che speravo fosse quello

label:checked { font-weight: bold; }

farebbe qualcosa, ma purtroppo non (come mi aspettavo).

Esiste un selettore in grado di ottenere questo tipo di funzionalità? Potresti circondarti di div ecc se questo aiuta, ma la soluzione migliore sarebbe quella che usa l'etichetta '' per '' l'attributo.

Va notato che sono in grado di specificare i browser per la mia applicazione, quindi per favore il migliore della classe css3 ecc.

Risposte:


361

prova il +simbolo: è un combinatore di fratelli adiacenti. Combina due sequenze di selettori semplici che hanno lo stesso genitore e il secondo deve arrivare IMMEDIATAMENTE dopo il primo.

Come tale:

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

funziona molto bene per il seguente markup:

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

... e funzionerà per qualsiasi struttura, con o senza div ecc, purché l'etichetta segua l'ingresso radio.

Esempio:

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>


11
Esiste un modo per farlo, ma con l'etichetta come elemento precedente EG:<label for="rad1">Radio 1</label><input id="rad1" type="radio" name="rad">
Nathan Koop,

17
Puoi usare una tilda ~per selezionare elementi fratelli che non sono necessariamente adiacenti. css-tricks.com/child-and-sibling-selectors
Martin

1
Grazie, questo mi ha solo aiutato a creare "pulsanti di opzione immagine" senza JS.
KillerX,

9
Vale la pena notare che questo non funzionerà in IE 8, poiché il :checkedselettore non è supportato .
Mark Amery,

2
@Martin Nel caso ti stia chiedendo, questo in realtà non funzionerà nel tuo caso, poiché l'etichetta deve ancora seguire l'input. La differenza tra '+' e '~' è se l'etichetta è direttamente adiacente, o è generalmente adiacente: se l'etichetta è l' elemento successivo o solo uno degli elementi successivi .
Njord,

127

So che questa è una vecchia domanda, ma se ti piacerebbe avere <input>un figlio <label>invece di averli separati, ecco un puro modo CSS che potresti realizzare:

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

Quindi avvolgi il testo con un <span>:

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

Guardalo su JSFiddle .


Eccellente. Questo è molto utile quando <label>@Html.RadioButtonFor(..) someText<label>ho a che fare con la situazione del rasoio , ho lanciato <span>"someText" e ha funzionato come un incantesimo. Grazie!
S1r-Lanzelot,

Bello! Non ci avevo pensato.
Matthew Dean,

Proprio quello di cui avevo bisogno! Grazie.
Ryan,

Cosa succede se si desidera lo stile: etichetta attiva con: selezionato? Questa non è davvero una soluzione.
Maciej Krawczyk,

2
@MaciejKrawczyk Non è una soluzione per te perché il tuo caso d'uso è completamente diverso. Se vuoi dare uno stile a un'etichetta attiva che puoi fare label:active { font-weight: bold; }. Vedi: jsfiddle.net/Gbq8Z/608 (wow, non posso credere che il violino sia stato biforcato 608 volte).
Mike,

22

Ho dimenticato dove l'ho visto menzionato per la prima volta, ma puoi effettivamente incorporare le etichette in un contenitore altrove purché tu abbia for=impostato l' attributo. Quindi, diamo un'occhiata a un esempio su 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>

Accidenti. Questo è stato molto per un "campione" ma credo che porti davvero a casa l'effetto e il punto: possiamo certamente selezionare un'etichetta per un controllo di input verificato senza che sia un fratello. Il segreto sta nel mantenere i inputtag come un bambino solo per ciò che devono essere (in questo caso - solo l' bodyelemento) .

Poiché l' labelelemento non utilizza effettivamente lo :checkedpseudo-selettore, non importa che le etichette siano memorizzate in header. Ha il vantaggio aggiuntivo che, poiché si headertratta di un elemento di pari livello, è possibile utilizzare il ~selettore di pari livello generico per spostarsi dall'elemento input[type=radio]:checkedDOM al headercontenitore e quindi utilizzare i selettori discendente / figlio per accedere agli labelstessi, consentendo la possibilità di modellarli quando le rispettive caselle radio / caselle di controllo sono selezionate .

Non solo possiamo modellare le etichette, ma anche altri contenuti che potrebbero essere discendenti di un contenitore di pari livello rispetto a tutti inputi messaggi. E ora per il momento che stavate tutti aspettando, il JSFIDDLE ! Andateci, giocateci, fatelo funzionare per voi, scoprite perché funziona, spezzatelo, fate quello che fate!

Spero che tutto abbia un senso e risponda pienamente alla domanda e, eventualmente, a eventuali follow-up che potrebbero sorgere.


2
Questa è la risposta a questa domanda. Altri, sebbene corretti, sono essenzialmente di base. Mentre questo risolve qualcosa di più complicato e interessante, si sarebbe tentati di afferrare js per.
trasforma

La risposta accettata a questa domanda ha> 30 volte più voti nonostante imponga una limitazione che questa risposta ovvia totalmente. A differenza di molti post analizzati in modo simile che pretendono informazioni strabilianti, questo in realtà recita sul reclamo. Ottimo lavoro, grazie mille.
naughtilus,

1
@naughtilus - questa risposta ovvia totalmente alla limitazione della risposta semplice, perché definisce esplicitamente gli stili per ciascuna opzione. cioè il mio ti costringe ad avere una convenzione di struttura; questo ti obbliga a scrivere CSS per ogni pulsante di opzione e risultato.
Stephen,

@morphles simple! = "super basic": questa soluzione è più complicata, interessante e potente - per questo codice esatto; il mio funzionerà su tutte le pagine che seguono 1 convention
Stephen

1

Se il tuo input è un elemento figlio di labele hai più di una etichetta, puoi combinare il trucco di @ Mike con Flexbox+ order.

inserisci qui la descrizione dell'immagine

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 }

Guardalo su JSFiddle .

nota: il selettore di pari livello funziona solo all'interno dello stesso genitore. Per ovviare a questo, puoi rendere nascosto l'input al livello più alto usando l' hack di @Nathan Blair .


-1

Puoi usare un po 'di jQuery:

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

Dovresti assicurarti che anche i pulsanti di opzione selezionati abbiano la classe corretta al caricamento della pagina.


3
Sì ... è ovviamente possibile farlo tramite javascript (framework), ma non è così semplice come sembra. Cosa succede se qualcos'altro ha già spuntato la casella? Quale script rimuoverà questa classe se viene selezionata un'altra radio nello stesso gruppo? Diventa troppo complicato molto velocemente. Voglio usare la funzionalità form + css incorporata nel browser perché funzionerà ogni volta.
Stephen,

4
Il tuo selettore dovrebbe essere$('label[for="' + $(this).attr('id') + '"]').toggleClass();
Wesley Murch il

-3

AGGIORNARE:

Questo ha funzionato solo per me perché il nostro html generato esistente era stravagante, generando labels insieme a se radiodando loro entrambi gli checkedattributi.

Non importa, e big up per Brilliand per averlo allevato!

Se l'etichetta è un fratello di una casella di controllo (che di solito è il caso), è possibile utilizzare il ~selettore di pari livello, e una label[for=your_checkbox_id]per affrontarlo ... o dare l'etichetta di un id, se si dispone di più etichette (come in questo esempio, dove ho usa le etichette per i pulsanti)


Sono venuto qui alla ricerca dello stesso, ma alla fine ho trovato la mia risposta nei documenti .

un labelelemento con checkedattributo può essere selezionato in questo modo:

label[checked] {
  ...
}

So che è una vecchia domanda, ma forse aiuta qualcuno là fuori :)


5
E come dovrebbe essere controllata l'etichetta?
Brilliand,

2
Ehi, buona cattura. Non Apparentemente abbiamo un codice piuttosto stravagante che genera etichette insieme ai pulsanti di opzione e aggiunge un attributo "controllato" a entrambi quando si genera l'html. Ma non è davvero valido ... Quindi è totalmente inutilizzabile. Modificherò la risposta, non ho idea del perché ho ottenuto i voti per questo. Grazie!
apprendista
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.