Introducción
Un botón fantasma (outline) es un botón con fondo transparente y una línea perimetral que sigue el color del texto o del tema. En WordPress, crear botones fantasma consistentes exige una aproximación sistemática: variables CSS para mantener la coherencia del diseño, atención a estados (hover, focus, active, disabled), accesibilidad y una integración limpia con el tema o editor (Gutenberg). Este artículo muestra, con todo lujo de detalles, cómo diseñar, codificar e integrar botones fantasma en un sitio WordPress moderno.
Principios de diseño para botones fantasma
- Consistencia tonal: usar variables CSS para color y grosor de contorno y aplicarlas a todo el sistema de botones.
- Sin saltos de diseño: evitar cambios de tamaño entre estados. Usar técnicas que no afecten el flujo del layout.
- Accesibilidad: foco visible claro, contraste suficiente y soporte para preferencia de reducción de movimiento.
- Compatibilidad: que funcione tanto en el frontend como en el editor de bloques (Gutenberg) para que la visual del contenido coincida con la del sitio.
- Componentización: clases modulares (.btn, .btn–outline, .btn–sm, .btn–icon) para reutilización.
Estrategia técnica resumida
- Definir variables CSS globales (colores, radio, grosor de contorno, transición).
- Crear componente base .btn con padding, tipografía y alignment.
- Crear variante .btn–outline que use border-color o box-shadow para el contorno sin cambiar el tamaño.
- Implementar estados hover/active/focus con transformaciones sutiles y respetando prefers-reduced-motion.
- Integrar en WordPress: añadir CSS en el tema, encolar archivos y aplicar estilos también en editor.
CSS central: variables y botón base
A continuación, un bloque CSS completo que sirve como punto de partida. Se usan variables para adaptar fácilmente a un tema y se emplea box-shadow para crear un contorno externo que no cambia el tamaño del botón.
:root{
--btn-font-family: system-ui, -apple-system, Segoe UI, Roboto, Helvetica Neue, Arial
--btn-font-size: 16px
--btn-line-height: 1.2
--btn-radius: 8px
--btn-padding-y: 0.5rem
--btn-padding-x: 1rem
--btn-color: #0b63d4 / color principal (texto y contorno) /
--btn-bg: transparent
--btn-outline-width: 2px / grosor visual del contorno /
--btn-outline-offset: 0.15rem / separación visual entre contorno y botón /
--btn-transition: 180ms cubic-bezier(.2,.9,.2,1)
--btn-hover-fade: rgba(11,99,212,0.06)
--btn-disabled-opacity: 0.5
}
/ Componente base /
.btn{
display: inline-flex
align-items: center
justify-content: center
font-family: var(--btn-font-family)
font-size: var(--btn-font-size)
line-height: var(--btn-line-height)
padding: var(--btn-padding-y) var(--btn-padding-x)
color: var(--btn-color)
background: var(--btn-bg)
border: none / No usamos border para evitar doble trazado /
border-radius: var(--btn-radius)
cursor: pointer
text-decoration: none / para anchors /
-webkit-appearance: none
-moz-appearance: none
appearance: none
transition: box-shadow var(--btn-transition), background var(--btn-transition), color var(--btn-transition), transform var(--btn-transition)
/ Usamos box-shadow para el contorno: permite border-radius y no cambia el flujo /
box-shadow: 0 0 0 calc(var(--btn-outline-width)) currentColor
/ Si prefieres que el contorno esté separado: sumar offset invisible /
/ box-shadow: 0 0 0 calc(var(--btn-outline-width) var(--btn-outline-offset)) currentColor /
}
/ Variante fantasma / outline /
.btn--outline{
background: transparent
color: var(--btn-color) / el color marca el contorno y el texto /
/ el box-shadow ya proporciona el trazo. Si quieres micro-línea interna: combinar con outline /
}
/ Tamaños /
.btn--sm{ font-size: 14px padding: 0.3rem 0.6rem }
.btn--lg{ font-size: 18px padding: 0.7rem 1.25rem }
/ Iconos dentro del botón /
.btn__icon{
display: inline-flex
align-items: center
justify-content: center
margin-right: 0.5ch / separación entre icono y texto /
line-height: 0
}
.btn--icon-only .btn__icon{ margin-right: 0 }
/ Hover y focus /
.btn:hover,
.btn:active{
background: var(--btn-hover-fade)
transform: translateY(-1px)
}
.btn:active{ transform: translateY(0) }
/ Focus-visible accesible y claro /
.btn:focus-visible{
outline: none
/ Añadir un contorno de accesibilidad distinto, usando outline (no afecta layout) /
box-shadow:
0 0 0 calc(var(--btn-outline-width)) currentColor, / contorno base /
0 0 0 4px rgba(11,99,212,0.14) / halo de foco /
border-radius: var(--btn-radius)
}
/ Disabled /
.btn[disabled],
.btn[aria-disabled=true]{
opacity: var(--btn-disabled-opacity)
pointer-events: none
cursor: default
box-shadow: 0 0 0 calc(var(--btn-outline-width)) currentColor
}
/ Preferencia por reducir movimiento /
@media (prefers-reduced-motion: reduce){
.btn{ transition: none transform: none }
}
Explicación de decisiones técnicas
- box-shadow como contorno: al usar box-shadow con tamaño 0 0 0 X currentColor se consigue un trazo externo que respeta el border-radius y no afecta el flujo ni el tamaño del botón, evitando saltos en el layout al cambiar estados.
- currentColor: usar el valor de color actual facilita que el contorno herede el mismo color que el texto o que se adapte a variaciones temáticas.
- focus-visible: distingue el foco por teclado del foco por ratón, mejorando la experiencia accesible.
- prefers-reduced-motion: respetar la preferencia del usuario para eliminar animaciones si procede.
Ejemplo de marcado HTML para usar en contenido o bloques
Leer más Pequeño
Integración en WordPress: cómo añadir este CSS correctamente
Hay dos caminos comunes: añadir el CSS en el archivo style.css del tema (o child theme) o encolar un archivo CSS propio. Para temas modernos y buena práctica, encolar estilos es la opción recomendada.
/ functions.php (ejemplo para encolar un archivo custom-button.css) /
function tema_enqueue_outline_buttons() {
// Asegúrate de reemplazar tu-tema y la ruta por la real
wp_enqueue_style( tu-tema-outline-buttons, get_stylesheet_directory_uri() . /css/custom-button.css, array(), 1.0 )
}
add_action( wp_enqueue_scripts, tema_enqueue_outline_buttons )
/ Para que se vea igual en el editor de bloques (Gutenberg) /
function tema_enqueue_block_editor_styles() {
wp_enqueue_style( tu-tema-outline-buttons-editor, get_stylesheet_directory_uri() . /css/custom-button-editor.css, array( wp-edit-blocks ), 1.0 )
}
add_action( enqueue_block_editor_assets, tema_enqueue_block_editor_styles )
Integración con el editor de bloques (Gutenberg)
- Añade las mismas clases al HTML generado por el bloque Buttons de Gutenberg usando la opción Additional CSS class(es) del bloque o mediante un bloque personalizado que pinche la clase .btn–outline.
- Si creas bloques dinámicos, devuelve
lta class=btn btn--outline...gten el render PHP del bloque para mantener consistencia. - Encola los estilos para el editor como se mostró arriba para que el WYSIWYG refleje el frontend.
Estados avanzados y variantes
- Ghost invertido (para fondos oscuros): cambiar la variable –btn-color según el contexto, por ejemplo con un contenedor que tenga data-theme=dark o usando clases .is-dark.
- Outline con relleno al hover: en hover se puede rellenar con un color semitransparente para enfatizar la acción, sin perder contraste.
- Outline doble o sombra ligera: combinar box-shadow con un pequeño offset para dar relieve si el diseño lo requiere.
/ Ejemplo: contexto oscuro /
[data-theme=dark] .btn{
--btn-color: #e6f0ff / color claro sobre fondo oscuro /
}
/ Hover con relleno más marcado /
.btn--outline:hover{
background: color-mix(in srgb, var(--btn-color) 8%, transparent) / o rgba manual /
}
Accesibilidad: checklist imprescindible
- Contraste del texto frente al fondo en estado normal y en hover (usar herramientas de comprobación WCAG).
- Foco por teclado visible y con halo suficiente.
- Usar role=button y tabindex cuando el elemento no sea un ltbuttongt pero actúe como tal.
- Estados aria: aria-disabled para botones no nativos que simulan deshabilitado.
- Evitar usar únicamente color para indicar estados (añadir icono o cambio de forma si es necesario).
Pruebas y compatibilidad
- Probar en navegadores modernos (Chrome, Edge, Firefox, Safari) y en dispositivos móviles. box-shadow funciona bien en estos entornos.
- Si se requiere soporte muy antiguo, considerar fallback con border: 1px solid currentColor para esos navegadores, pero documentar que puede cambiar dimensiones.
- Verificar que la interacción táctil tenga área clicable mínima (44×44 px recomendado por accesibilidad).
Errores comunes y cómo resolverlos
- El contorno cambia el tamaño del botón: solución: usar box-shadow o outline en lugar de border que modifica el flujo.
- Foco no se ve en algunos navegadores: asegurar :focus-visible y no eliminar outline globalmente sin reemplazo apropiado.
- El color no se hereda correctamente: revisar cascada y variables comprobar que la variable –btn-color está definida en :root o en el ámbito adecuado.
- El editor no refleja el frontend: encolar estilos específicos para el editor o usar editor-style.css.
Ejemplo práctico completo: CSS reducido HTML de uso
/ Resumen mínimo para copiar: /
:root{ --btn-color:#0b63d4 --btn-radius:8px --btn-outline-width:2px }
.btn{ display:inline-flex align-items:center padding:0.5rem 1rem color:var(--btn-color) background:transparent border-radius:var(--btn-radius) box-shadow:0 0 0 calc(var(--btn-outline-width)) currentColor transition:all 160ms ease text-decoration:none }
.btn:focus-visible{ box-shadow:0 0 0 calc(var(--btn-outline-width)) currentColor, 0 0 0 4px rgba(11,99,212,0.12) }
.btn:hover{ background:rgba(11,99,212,0.06) transform:translateY(-1px) }
Botón fantasma
Resumen final
Los botones fantasma bien implementados aportan elegancia y coherencia visual. Usar variables CSS, box-shadow para el contorno, focus-visible para la accesibilidad y encolar correctamente los estilos en WordPress garantiza una solución profesional y mantenible. Sigue la estructura modular de clases, prueba en el editor y en el frontend, y adapta las variables a la paleta de tu tema para obtener resultados consistentes.
Leave a Reply