Selector :has() El "Selector Padre" de CSS
El selector :has() permite aplicar estilos a elementos padre basándose en sus elementos hijos. Es como tener lógica condicional directamente en CSS, sin necesidad de JavaScript para estados dinámicos.
Formulario Inteligente Observa cómo el formulario cambia según su contenido
Escribe en los campos para ver cómo el formulario detecta automáticamente el contenido
Haz click en "Validar" para simular errores y ver la magia del :has()
Observa los cambios automáticos en colores, bordes y mensajes
¿Qué está pasando aquí?
Código del Formulario Inteligente Ejemplos prácticos del selector :has()
1. Detectar Errores en el Formulario
CSS/* Formulario normal */
.smart-form {
border: 2px solid var(--border-color);
background: var(--surface);
}
/* ¡MAGIA! Si el formulario TIENE inputs con errores */
.smart-form:has(.form-input.error) {
border-color: var(--error);
background: color-mix(in srgb, var(--error) 5%, var(--surface));
box-shadow: 0 0 0 4px color-mix(in srgb, var(--error) 10%, transparent);
}
/* Si el formulario TIENE campos válidos */
.smart-form:has(.form-input:valid):not(:has(.error)) {
border-color: var(--success);
background: color-mix(in srgb, var(--success) 3%, var(--surface));
}
2. Labels Inteligentes
CSS/* Label normal */
.form-label {
color: var(--text-primary);
}
/* Si el grupo TIENE un input con error */
.form-group:has(.form-input.error) .form-label {
color: var(--error);
}
/* Si el grupo TIENE un input enfocado */
.form-group:has(.form-input:focus) .form-label {
color: var(--primary-color);
transform: scale(1.02);
}
/* Si el grupo TIENE un input válido */
.form-group:has(.form-input:valid):not(:has(.error)) .form-label {
color: var(--success);
}
3. Botones que Reaccionan
CSS/* Botón submit deshabilitado por defecto */
.form-button--submit {
opacity: 0.5;
cursor: not-allowed;
}
/* Si el form TIENE todos los campos requeridos válidos */
.smart-form:has(#name:valid):has(#email:valid):has(#password:valid):has(#terms:checked) .form-button--submit {
opacity: 1;
cursor: pointer;
background: linear-gradient(45deg, var(--success), var(--primary-color));
}
/* Si el form TIENE errores, botón validar cambia */
.smart-form:has(.error) .form-button--validate {
background: var(--warning);
animation: pulse 2s infinite;
}
4. Combinaciones Avanzadas
CSS/* Si el form TIENE password field Y está enfocado */
.smart-form:has(input[type="password"]:focus) {
--form-accent: var(--warning);
}
/* Si el form TIENE checkboxes marcados */
.smart-form:has(input[type="checkbox"]:checked) .form-status {
background: color-mix(in srgb, var(--success) 10%, transparent);
}
/* Si el form NO TIENE errores Y TIENE campos válidos */
.smart-form:not(:has(.error)):has(:valid) {
background: linear-gradient(135deg,
color-mix(in srgb, var(--success) 3%, var(--surface)),
color-mix(in srgb, var(--primary-color) 2%, var(--surface))
);
}
Casos de Uso del :has() Más allá de los formularios
Formularios Dinámicos
Validación visual instantánea, campos que se adaptan según el contenido, estados de carga sin JavaScript.
form:has(.error) { /* estilos */ }
E-commerce
Carrito que cambia según productos, productos que muestran badges según stock, categorías que se destacan.
.cart:has(.item) { /* mostrar total */ }
Dashboards
Paneles que cambian según datos, gráficos que se adaptan según contenido, alertas automáticas.
.dashboard:has(.alert) { /* modo emergencia */ }
Interfaces Adaptativas
Layouts que se reorganizan según contenido, modales que se ajustan, navegación contextual.
.sidebar:has(.submenu) { /* expandir */ }
Soporte de Navegadores :has() en producción
Graceful degradation:
@supports not selector(:has(*)) {
/* Estilos fallback para navegadores sin :has() */
.smart-form.has-error { /* clase añadida via JS */ }
.form-group.field-error .form-label { color: var(--error); }
}