Selector CSS para la etiqueta de un botón de radio marcado

221

¿Es posible aplicar un estilo css (3) a la etiqueta de un botón de radio marcado?

Tengo el siguiente marcado:

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

Lo que esperaba es que

label:checked { font-weight: bold; }

haría algo, pero lamentablemente no lo hace (como esperaba).

¿Hay un selector que pueda lograr este tipo de funcionalidad? Puede rodear con divs, etc. si eso ayuda, pero la mejor solución sería una que use la etiqueta '' para '' atributo.

Cabe señalar que puedo especificar navegadores para mi aplicación, por lo tanto, lo mejor de su clase css3, etc.

Stephen
fuente

Respuestas:

361

pruebe el +símbolo: es el combinador de hermanos adyacentes. Combina dos secuencias de selectores simples que tienen el mismo padre y el segundo debe venir INMEDIATAMENTE después del primero.

Como tal:

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

funciona muy bien para el siguiente marcado:

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

... y funcionará para cualquier estructura, con o sin divs, etc., siempre que la etiqueta siga a la entrada de radio.

Ejemplo:

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
fuente
11
¿Hay alguna forma de hacer esto, pero con la etiqueta de ser el elemento antes EG:<label for="rad1">Radio 1</label><input id="rad1" type="radio" name="rad">
Nathan Koop
17
Puede usar una tilda ~para seleccionar elementos hermanos que no sean necesariamente adyacentes. css-tricks.com/child-and-sibling-selectors
Martin
1
Gracias, esto me ayudó a crear "botones de radio de imagen" sin JS.
KillerX
99
Vale la pena señalar que esto no funcionará en IE 8, ya que el :checkedselector no es compatible .
Mark Amery
2
@ Martin Solo en caso de que te lo estés preguntando, esto en realidad no funcionará en tu caso, ya que la etiqueta aún debe seguir la entrada. La diferencia entre '+' y '~' es si la etiqueta es directamente adyacente, o si es generalmente adyacente: si la etiqueta es el siguiente elemento o solo uno de los siguientes .
Njord
127

Sé que esta es una vieja pregunta, pero si desea que <input>sea ​​un hijo en <label>lugar de separarlos, aquí hay una forma pura de CSS que podría lograr:

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

Luego simplemente envuelva el texto con un <span>:

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

Véalo en JSFiddle .

Miguel
fuente
Excelente. Esto es muy útil cuando se trata de la situación de la maquinilla de afeitar <label>@Html.RadioButtonFor(..) someText<label>, arrojé <span>"someText" y funcionó de maravilla. ¡Gracias!
S1r-Lanzelot
¡Agradable! No había pensado en esto.
Matthew Dean el
¡Justo lo que necesitaba! Gracias.
Ryan
¿Qué sucede si desea diseñar: etiqueta activa con: marcado? Esto no es realmente una solución.
Maciej Krawczyk
2
@MaciejKrawczyk No es una solución para usted porque su caso de uso es completamente diferente. Si desea diseñar una etiqueta: activa, simplemente puede hacerlo label:active { font-weight: bold; }. Ver: jsfiddle.net/Gbq8Z/608 (wow, no puedo creer que el violín haya sido bifurcado 608 veces).
Mike
22

Olvidé dónde lo vi por primera vez, pero en realidad puedes incrustar tus etiquetas en un contenedor en otro lugar siempre que tengas el for=atributo establecido. Entonces, veamos una muestra en 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>

Uf. Eso fue mucho para una "muestra", pero creo que realmente lleva a casa el efecto y el punto: ciertamente podemos seleccionar una etiqueta para un control de entrada verificado sin que sea un hermano. El secreto radica en mantener las inputetiquetas de un niño solo para lo que necesitan ser (en este caso, solo el bodyelemento) .

Como el labelelemento en realidad no utiliza el :checkedpseudo selector, no importa que las etiquetas estén almacenadas en el header. Tiene el beneficio adicional de que, dado que headeres un elemento hermano, podemos usar el ~selector de hermanos genérico para pasar del input[type=radio]:checkedelemento DOM al headercontenedor y luego usar los selectores descendientes / hijos para acceder a los labelmismos, lo que permite la posibilidad de diseñarlos cuando Se seleccionan las respectivas casillas de radio / casillas de verificación .

No solo podemos diseñar las etiquetas, sino también diseñar otro contenido que pueda ser descendiente de un contenedor hermano en relación con todos los inputs. Y ahora, por el momento que todos han estado esperando, ¡el JSFIDDLE ! Ve allí, juega con él, haz que funcione para ti, descubre por qué funciona, rómpelo, ¡haz lo que haces!

Esperemos que todo tenga sentido y responda completamente la pregunta y posiblemente cualquier seguimiento que pueda surgir.

Nathan Blair
fuente
2
Esta es la respuesta a esta pregunta. Otros mientras correctos son esencialmente super básicos. Si bien esto resuelve algo más complicado e interesante, uno estaría tentado a tomar js.
transforma el
La respuesta aceptada a esta pregunta tiene> 30 veces más votos a favor a pesar de imponer una limitación que esta respuesta obvia totalmente. A diferencia de muchas publicaciones promocionadas de manera similar que pretenden información alucinante, esto realmente cumple con el reclamo. Increíble trabajo, muchas gracias.
naughtilus
1
@naughtilus: esta respuesta obvia totalmente la limitación de la respuesta simple, porque define explícitamente los estilos para cada opción. es decir, Mine te obliga a tener una convención de estructura; este te obliga a escribir css para cada botón de radio y resultado.
Stephen
@morphles simple! = "super basic": esta solución es más complicada, interesante y poderosa, para este código exacto; el mío funcionará en todas las páginas después de 1 convención
Stephen
1

Si su entrada es un elemento secundario de labely tiene más de una etiqueta, puede combinar el truco de @ Mike con Flexbox+ order.

ingrese la descripción de la imagen aquí

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 }

Véalo en JSFiddle .

nota: el selector de hermanos solo funciona dentro del mismo padre. Para evitar esto, puede hacer que la entrada se oculte en el nivel superior utilizando el truco @Nathan Blair .

QWERTY
fuente
-1

Podrías usar un poco de jQuery:

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

Debería asegurarse de que sus botones de radio marcados también tengan la clase correcta en la carga de la página.

Dan Herd
fuente
3
Sí ... por supuesto, es posible hacerlo a través de javascript (frameworks), pero no es tan simple como parece. ¿Qué sucede si algo más ya ha marcado la casilla? ¿Qué script eliminará esta clase si se selecciona otra radio en el mismo grupo? Se vuelve demasiado complicado realmente rápido. Quiero usar la funcionalidad integrada form + css del navegador porque funcionará todo el tiempo.
Stephen
44
Tu selector debería ser$('label[for="' + $(this).attr('id') + '"]').toggleClass();
Wesley Murch,
-3

ACTUALIZAR:

Esto solo funcionó para mí porque nuestro html generado existente era extraño, generaba labels junto con radios y les daba a ambos checkedatributos.

¡No importa, y grandes beneficios para Brilliand por mencionarlo!

Si su etiqueta es un hermano de una casilla de verificación (que suele ser el caso), puede usar el ~selector de hermanos y un label[for=your_checkbox_id]para abordarlo ... o asignarle una identificación a la etiqueta si tiene varias etiquetas (como en este ejemplo donde yo usar etiquetas para botones)


Vine aquí buscando lo mismo, pero terminé encontrando mi respuesta en los documentos .

Un labelelemento con checkedatributo puede seleccionarse así:

label[checked] {
  ...
}

Sé que es una vieja pregunta, pero tal vez ayude a alguien por ahí :)

aprendizDev
fuente
55
¿Y cómo se supone que se verificará la etiqueta?
Brilliand
2
Hola, buena captura. No lo hace. Aparentemente tenemos un código bastante extraño que genera etiquetas junto con botones de radio, y agrega un atributo "marcado" a ambos cuando se genera el html. Pero no es realmente válido ... Así que esto es totalmente inutilizable. Editaré la respuesta, no tengo idea de por qué obtuve los votos a favor. ¡Gracias!
aprendizDev