Auditoría de crecimientoAuditamos sus vínculos de retroceso, analizamos a la competencia y creamos una hoja de ruta de 90 días en vivo durante la llamada.Reservar llamada
Únase a más de 1000 SEO en nuestra comunidad privada de SlackInscribirse
Botones de radio HTML que convierten: la guía definitiva
Cree grupos de radio HTML accesibles y de alta conversión: semántica, diseños de estilo de tarjeta, UX de teclado, validación suave, diseños móviles e integración con Formspree.
Los botones de radio parecen simples. Un clic, una elección. Sin embargo, también son una de las formas más fáciles de comprometer la UX y la accesibilidad. Oculte la entrada nativa, omita elconjunto de camposyleyenda, o valide de manera demasiado agresiva y enviará un formulario que confunde a los usuarios del teclado, frustra a los lectores de pantalla y altera las conversiones.
Esta guía le muestra cómo hacer radios correctamente en 2025: rápida de elegir, fácil de escanear, totalmente accesible y mensurable. Comenzaremos con una línea de base semántica limpia, luego aplicaremos capas de CSS moderno para que las radios puedan verse como tarjetas o controles segmentados sin alterar el comportamiento del teclado o del lector de pantalla.
Verá patrones de validación prácticos que no molestan, diseños responsivos que mantienen los objetivos grandes en dispositivos móviles y fragmentos de producción que puede pegar en cualquier pila. También cubriremos análisis, ideas A/B y una configuración de Formspree para que puedas capturar resultados de inmediato.
Para quién es: diseñadores, desarrolladores front-end y especialistas en marketing que se preocupan por ambosaccesibilidadyconversión. No se requieren marcos pesados, solo HTML sólido, CSS enfocado y una pequeña mejora progresiva.
Al final, sabrás:
Cuando las radios pulsan selecciona, marca o alterna
Cómo crear un grupo de radio accesible (conjunto de campos,leyenda, etiquetado, enfoque)
Cómo diseñar radios de “tarjeta” personalizadas sin ocultar la entrada
Cómo validar con la API de restricción HTML (y enviar mensajes)
Cómo conectar radios a Formspree y medir selecciones
TL;DR
Usoradiosexactamenteunoelección dentro de un conjunto bien definido (idealmente2–6 opciones) que debería servisible de inmediato.
Siempre envuelva las radios en+, dales ello mismonombrey haga de cada opción unse puede hacer clic.
No ocultes entradas convisualización: ninguna; guárdalosenfocable(por ejemplo,opacidad:0; posición:absoluta; recuadro:0) entoncesTabulador/Flechas/Espaciotrabajar.
Haga que los objetivos sean grandes: al menos44×44px, con unanillo de enfoqueeso es claramente visible.
Validar con elAPI de restricción HTML(requerido,reportValidity()), luego mejore los mensajes, no al revés.
Si tiene muchas opciones o no le resultan familiares, agreguetexto de ayudadebajo de cada etiqueta y considerebuscar o agruparen cambio.
En dispositivos móviles, apilaruna columna; en pantallas anchas,2–3 columnasa través de cuadrícula CSS.
Medida: víaimpresiones, selección y envíoy prueba A/Borden de opcionesycopiar.
Para Formspree, mantengaPUBLICACIÓN nativacomo alternativa; añadirbuscarsólo como mejora progresiva.
Cuándo utilizar radios (árbol de decisión)
P1. ¿El usuario elige exactamente una opción?
No →Usocasillas de verificación(0–muchos) o unalternar(binario) o repensar la tarea.
Sí →Vaya a la Q2.
P2. ¿Es necesario que las opciones sean visibles de un vistazo?
Sí →Usoradios(lo mejor para escanear y elegir rápidamente).
No (hay poco espacio/hay muchas opciones)→ Considere unseleccione(menú desplegable). Si las opciones son críticas y se benefician de la comparación, prefiera las radios y rediseñe el diseño.
P3. ¿Cuantas opciones?
2–6→ Las radios son ideales.
7–10→ Es posible que las radios aún funcionen con agrupación o undos columnasred; de lo contrario, utilice una lista de selección o de búsqueda.
>10→ Utilice unseleccionar con búsquedao unpasoeso reduce el conjunto primero.
P4. ¿Las opciones son estados mutuamente excluyentes?
Sí →Radios.
Ninguna combinación / tiene sentido →Casillas de verificación.
P5. ¿La elección generará diferentes preguntas de seguimiento?
Sí →Las radios siguen bien. Mostrar seguimientoscondicionalmente, pero mantén los campos ocultosfuera del orden de tabulacióny SR fluye hasta que se revela.
No →Grupo de radio sencillo.
P6. ¿Familiar versus descriptivo?
Etiquetas familiares(p. ej., “Pequeño/Mediano/Grande”) → las etiquetas cortas son suficientes.
Desconocido o de alto riesgo(por ejemplo, “SEO técnico versus SEO de contenido”) → agregarmicrocopia(descripción de una línea) debajo de cada etiqueta.
P7. ¿El móvil primero?
Sí (siempre)→ Usopila de una columnacon espacios generosos y texto de 16 a 18 píxeles. Promocionar elmás elegidoopción hacia la cima.
Ejemplos prácticos
Tu formulario: "¿Qué servicio?" → Las radios ganan a una selección porque los usuarios deben comparar las opciones una al lado de la otra. Mantenga 3 tarjetas (Construcción de enlaces, SEO, Desarrollo web) con un subtexto breve.
Velocidad de envío: 3–4 velocidades mutuamente excluyentes → Radios (con deltas de precios en el subtexto).
Frecuencia del boletín: Diario/Semanal/Mensual → Radios.
Intereses (puede elegir varios)→ No radios; utilizar casillas de verificación.
Anatomía de un grupo de radio adecuado
Copiar y pegar línea de base semántica (aún no hay CSS sofisticado)
Por qué es importante cada parte
+le da al grupo un nombre para los lectores de pantalla y establece un contexto para todos.
Lo mismonombrehace que las entradas sean mutuamente excluyentes.
Se puede hacer clicalrededor de cada entradale brinda un área enorme de toque/clic (44px+).
requeridoen la primera radiopermite que el navegador valide el grupo de forma nativa.
Texto de ayuda(sugerencia de servicio) ytexto de error(service-error) están separados para que pueda mostrar/ocultar errores sin mover cosas.
No se necesitan roles ARIA.Las radios nativas ya exponen la semántica correcta.
CSS mínimo para usabilidad (apariencia nativa, objetivos grandes, enfoque claro)
/* Diseño y espaciado */ .etiqueta de campo { pantalla: flexible; alinear elementos: centro; brecha: .6rem; relleno: .65rem .8rem; /* objetivo de gran toque */ radio de borde: .6rem; cursor: puntero; }
/* Enfoque del teclado: resalta toda la etiqueta cuando la entrada está enfocada */ .etiqueta de campo: tiene (entrada: foco-visible) { contorno: 3px sólido #3b82f6; desplazamiento de contorno: 2px; }
/* Estado seleccionado (opcional, el punto nativo aún se muestra) */ .etiqueta de campo: tiene (entrada: marcada) { antecedentes: #f1f5ff; }
/* Texto de error */ .error {color: #b91c1c; margen superior: .5rem; tamaño de fuente: .9rem; }
Consejo::tiene()le brinda ese "anillo de enfoque en toda la tarjeta" sin ocultar la entrada real. Si un navegador antiguo no lo admite, los usuarios aún obtienen el anillo de enfoque nativo en la propia radio.
Validación suave y accesible (primero usa el navegador)
Deje que el navegador maneje la parte "debe elegir uno" y luego muestre su error en línea si es necesario.
formulario const = document.getElementById('formulario de cotización'); grupo const = document.getElementById('grupo-servicio'); error constante = document.getEementById('error-servicio');
form.addEventListener('submit', (e) => { // Activa la interfaz de usuario de validación nativa (funciona porque la primera radio tiene `required`) if (!form.reportValidity()) { // Opcional: muestra un error en línea amigable también error.hidden = false; group.setAttribute('aria-invalid', 'true'); e.preventDefault(); else { error.hidden = true group.removeAttribute('aria-inválido' } } Comportamiento que debe esperar (y probar):
Teclado:
Presione una vez para ingresar al grupo; utilizarTeclas de flechamoverse;Espacioselecciona.Lectores de pantalla:
La leyenda se lee como la etiqueta del grupo; cada opción se anuncia con el estado "seleccionado/no seleccionado".Toque:
Al tocar la etiqueta se alterna la radio (gracias al ajuste de etiquetas).Radios de “tarjeta” con estilo personalizado (sin interrumpir la accesibilidad)
Copiar y pegar HTML
Copy-paste HTML
Elija una opción. Puedes cambiar en cualquier momento.
/* Etiqueta de tarjeta */ .tarjeta{ posición: relativa; pantalla:cuadrícula; colocar elementos:centro; alineación de texto:centro; espacio: 6px; relleno: 18px; borde: 1px var sólido (--borde); radio-borde:var(--radio); fondo:var(--bg); cursor:puntero; selección de usuario: ninguna; transición: sombra de cuadro .15s, color de borde .15s, transformación .02s; } .card:hover{ box-shadow:0 8px 20px rgba(0,0,0,.06); }
/* Mantenga la entrada nativa enfocable: no display:none */ .entrada de tarjeta{ posición:absoluta; recuadro: 0; opacidad: 0; }
/* Anillo de enfoque del teclado en toda la tarjeta */ .card:has(entrada:focus-visible){ sombra de cuadro: 0 0 0 3px var (--anillo); color del borde: var(--marca); }
/* Estado seleccionado */ .card:ha(entrada:marcado){ color del borde: var(--marca); sombra de cuadro: 0 0 0 3px var (--anillo); }
/* Contenido */ .título de la tarjeta{ peso de fuente:700; color:#111; } .card-sub{ tamaño de fuente:14px; color:var(--silenciado); }
/* Texto de error */ .error{color:#b91c1c; margen superior: .5rem; tamaño de fuente: .9rem; }
Notas de comportamiento (por qué funciona este patrón)
Novisualización: ningunaen la entrada → los usuarios del teclado pueden presionar Tab;Teclas de flechaselección de movimiento;Espacioselecciona.
Se puede hacer clic en toda la tarjeta porque la entrada está dentro deletiqueta.
:tiene()déjanos peinarcentrarseycomprobadoestados en la tarjeta principal sin hacks ARIA.
La cuadrícula responsiva proporciona1–3 columnasautomáticamente; Los objetivos táctiles se mantienen grandes.
form.addEventListener('submit', (e) => { if (!form.reportValidity()) { // usa el `requerido` en la primera radio err.hidden = false; e.preventDefault(); } else { err.hidden = true; } });
Estrategias de validación que no molestan
Una gran validación es invisible hasta que se necesita. A continuación se presenta un enfoque específico para la radio que es rápido, accesible y tranquilizador para los usuarios.
Principios
Nativo primero.Deje que HTML maneje "se debe seleccionar uno".
Aplazar errores.No grites a los usuarios antes de que intenten continuar.
Señale el problema.Anuncie errores, cambie el enfoque de manera inteligente y mantenga el texto breve.
Claro sobre el cambio.Tan pronto como se haga una elección válida, elimine el error.
Línea de base (solo nativo)
Solo HTML puede hacer cumplir la regla conrequeridoen una radio del grupo.
Esto ya le brinda: flechas del teclado, espacio para seleccionar y validación a nivel del navegador.
Errores en línea amigables (mejora progresiva)
Desactive la ventana emergente del navegador y administre los mensajes en línea para que coincidan con su diseño.
HTML (agregar una región de error)
Elija una opción.
CSS (estilo simple)
.error {color:#b91c1c; margen superior: .5rem; tamaño de fuente: .9rem; }
JS (aplazar errores, anunciar correctamente)
forma constante = document.getElementById('cita'); grupo constante = document.getElementById('svc'); const err = document.getElementById('svc-err'); radios const = form.querySelectorAll('input[nombre="servicio"]');
dejar intentado = falso; // muestra errores sólo después de que el usuario intenta continuar
function showError(msg='Elija una opción.') { err.textContent = mensaje; error.oculto = falso; group.setAttribute('aria-invalid', 'true'); // Agrega el error a describe por para que los SR lo anuncien a continuación group.setAttribute('aria-describedby', 'svc-hint svc-err'); }
form.addEventListener('submit', (e) => { intenté = true; if (!hasSelection()) { e.preventDefault(); showError(); // Muestre el grupo a la vista y coloque el foco en la primera radio radios[0].focus(); group.scrollIntoView({ conductual: 'smooth', block: 'center' }); más { borrarError(); } // No regañes temprano; claro una vez que eligen algo
radios.forEach(r => { r.addEventListener('cambiar', () => { if (intento) clearError(); }); }); Por qué funciona esto
No hay burbujas de información sobre herramientas del navegador; los usuarios ven errores
en líneaal lado del grupo.Los lectores de pantalla escuchan el
leyenda, entonces elerror, gracias aaria-descrita por.Sólo aparecen errores
despuésun intento de envío (o al regresar para corregirlo).Validación suave por paso (formularios de varios pasos)
Si ingresa con el botón “Siguiente”, valide solo ese paso.
if (!hasSelection()) { showError(); } else { clearError(); // avanza al siguiente paso... } }); Mensajes personalizados con la API de restricción (opcional)
Si prefiere mantener el modelo de validez del navegador, configure un mensaje personalizado en el
primeroradio en el grupo.const primeraRadio = radios[0];
form.addEventListener('submit', (e) => { if (!hasSelection()) { firstRadio.setCustomValidity('Por favor, elija una opción.'); // Activa la interfaz de usuario nativa; o llama a form.reportValidity() e.preventDefault(); form.reportValidity(); } else { primeraRadio.setCustomValidity(''); } } Úselo cuando desee la "burbuja" nativa más su propio texto; de lo contrario, siga el método en línea anterior para una interfaz de usuario consistente.
Resumen de errores (para formularios largos)
Si su formulario es largo, agregue un
resumen superiorque se vincula con el área del problema.
suma const = document.getElementById('resumen de errores'); suma.oculta = falso; suma.querySelector('a').focus(); // Los SR anuncian la alerta } Reservas del lado del servidor y de la red
La validación del lado del cliente mejora la UX, pero
siemprevalide también en el servidor (o mediante su servicio de envío). Si el envío falla, devuelva la página con: validate on the server (or by your submission service) too. If submission fails, return the page with:
El anteriorla selección persistió, y
Elmismo error en líneaal lado del grupo.
Integración de Formspree (mejora progresiva)
Haga que las radios funcionen incluso si JavaScript falla y luego mejore para obtener un agradecimiento más fluido y mejores análisis.
// en el controlador de envío antes de enviar: const iniciado = Número(fd.get('started_at')); if (Date.now() - iniciado < 2000) retorno; // parece un robot
Líneas de asunto que reflejan la elección de radio (bandeja de entrada limpia)
Puedes personalizar_sujetode la radio seleccionada:
servicio constante = fd.get('servicio'); // por ejemplo, "seo" fd.set('_subject', `Nuevo cliente potencial ${servicio} desde el formulario de contacto`);
Errores comunes que se deben evitar
Ocultar radios convisualización: ninguna.Usoopacidad: 0; posición:absoluta; recuadro:0dentro de la etiqueta para que los teclados sigan funcionando.
Olvidandoconjunto de campos/leyenda.Los lectores de pantalla dependen de ellos para obtener contexto.
Sobrevalidación temprana.Mostrar errores después de enviar/Siguiente, luego borrarlos tan pronto como el usuario corrija el grupo.
No capturar el contexto.AñadirURL de página,referentey campos UTM, lo agradecerás más tarde.
Internacionalización e Inclusividad
Idioma, etiquetas y tono
Utilice la páginaidioma(y cambiar páginas por configuración regional): …
Mantenga las etiquetas breves ydescriptivo, evite la jerga específica de una cultura.
Prefieroneutrofrases ("Elija un plan") en lugar de suposiciones ("¿Cuál es su presupuesto?").
Localizarerroresytexto de ayudacon un diccionario simple codificado pordocumento.documentElement.lang.
constante i18n = { es: { elegir: 'Elija una opción'. }, es: { elegir: 'Elige una opción, por favor.' }, ar: { elija: 'يُرجى اختيار خيار واحد.' } }; const t = (k) => (i18n[document.documentElement.lang] || i18n.en)[k]; errorEl.textContent = t('elegir');
Etiquetas largas y opciones de varias líneas
Dejar etiquetasenvolver; nunca trunca palabras cruciales.
Mantenga grande el área de impacto incluso cuando el texto se ajuste: use relleno enetiqueta, no solo la entrada.
.card { tamaño en línea: 100%; relleno: 16px; } .card .card-title { peso de fuente: 700; altura de línea: 1,25; } .card .card-sub { tamaño de fuente: 14px; altura de línea: 1,4; }
Soporte de derecha a izquierda (RTL)
Usar CSSpropiedades lógicasy:dir()por lo que no necesitas estilos separados.
/* Espaciado que cambia automáticamente a RTL */ .card { padding-inline: 16px; bloque de relleno: 16px; }
/* Anillo de enfoque que respeta la dirección */ .card:has(entrada:focus-visible) { esquema: 3px solid var(--ring); desplazamiento de contorno: 2px; }
Copia de CTA(“Obtener mi propuesta gratuita” frente a “Obtener mi cotización”)
Texto de ayudapresencia
Antipatrones (no hagas esto)
Ocultar entradas convisualización: ninguna(rompe el teclado y los SR).
Desaparecidoconjunto de campos/leyenda.
Pequeñas áreas de impacto (solo se puede hacer clic en el pequeño punto).
Estado de selección de solo color; enfoque invisible.
Validandoantesel usuario intenta continuar.
Empacar de 10 a 20 opciones en radios; utilice una selección de búsqueda en su lugar.
Lista de verificación final
conjunto de campos+leyendapresente
Lo mismonombre, únicovalors
Las etiquetas envuelven las entradas; Se puede hacer clic en toda la tarjeta
Anillo de enfoque claramente visible
requeridoen primera radio; errores leves en línea
Cuadrícula de 1 a 3 columnas, objetivos táctiles grandes y receptivos
Cadenas localizadas; RTL seguro mediante propiedades lógicas
Análisis al ver/seleccionar/enviar
La validación del lado del servidor refleja las reglas del cliente
Recursos
Especificaciones y patrones de creación
Estándar HTML –: semántica nativa, agrupación pornombre, formar comportamiento.
Prácticas de autoría WAI-ARIA 1.2 – Grupo de radio: comportamiento esperado del teclado (Tab en grupo,Flechapara mover,Espaciopara seleccionar), patrones de etiquetado.
WCAG 2.2elementos esenciales para radios:
2.1.1Teclado(todo operable mediante teclado)
2.4.7Enfoque visible(enfoque claramente visible)
2.5.5Tamaño objetivo(se recomienda ≥44×44px)
1.4.3Contraste (mínimo)
Guías de referencia
MDN: Entrada de radio,etiqueta,conjunto de campos/leyenda, validación de formulario (API de validación de restricciones).
Sistema de diseño GOV.UK – Radios: guía excelente y probada en batalla sobre redacción y errores.
Componentes inclusivos (Heydon Pickering): patrones prácticos y críticas.
1) ¿Cuántas opciones son demasiadas para las radios?
Apunta a2–6. Si tiene entre 7 y 10, agrúpelos o utilice una cuadrícula de dos columnas. Más de ~10, cambie aseleccionar (con búsqueda)o rediseñar para limitar las opciones primero.
2) ¿Debo preseleccionar una opción?
Sólo si hay unclara mayoría en defaulty no sesgará los datos. La preselección acelera la finalización pero puede reducir la elección deliberada. Si no está seguro,no preseleccionar.
3) Radios vs seleccionar vs casillas de verificación, ¿qué elijo?
Radios: elección única, las opciones deben servisiblelado a lado. Seleccionar: opción única cuando el espacio es reducido o las opciones son muchas. Casillas de verificación:0–muchosopciones (no mutuamente excluyentes).
4) ¿Puedo diseñar radios como “tarjetas” sin alterar la accesibilidad?
Sí. Mantenga elentrada nativa enfocable(no usedisplay:none). Pon la entradadentro del, configúrelo enopacidad: 0; posición:absoluta; recuadro: 0;y aplicar estilo a la etiqueta. Uso:tiene(entrada:enfoque-visible)y:tiene(entrada:marcado)para impulsar el enfoque/estados seleccionados.
5) ¿Cuál es la mejor manera de validar un grupo de radio?
Utilice HTML primero: pongarequeridoen la primera radioy llamaformulario.reportValidity()(o dejar que el navegador maneje el envío). Para una mejor interfaz de usuario, muestra un breveerror en líneacerca del grupodespuésel primer intento, yclaro sobre el cambio.
6) ¿Necesito roles ARIA comorol="grupo de radio"?
No para radios nativas. Un adecuadoconjunto de campos+leyendaya ofrece a los lectores de pantalla el contexto adecuado. Agregue ARIA solo si está creando untotalmente personalizadowidget (evitar si es posible).
7) ¿Cómo manejo los campos de seguimiento condicional (muestro diferentes entradas según la selección)?
Mostrar/ocultar los seguimientosdespuésuna selección. Cuando está oculto, tambiéndesactivaresos controles para que estén fuera del orden de tabulación y no se envíen. Cuando se revelen, mueva el foco con sensatez y asegúrese de que las etiquetas permanezcan claras.
8) ¿Qué debo probar antes del envío?
Flujo del teclado, enfoque visible, anuncios del lector de pantalla (leyenda leída, estado seleccionado expresado), áreas de visita móviles, tiempo de validación (sin molestias tempranas) y valores seleccionadospersistiren el error del lado del servidor.
Shahid Shahmiri is a digital marketer who helps online businesses grow with smart marketing tactics that improve sales and leads. He is passionate and driven to grow businesses online and is responsible for analyzing marketing, SEO, growth and managing promotional and media channels.