Introducción
Este tutorial explica paso a paso cómo mostrar automáticamente un icono al lado de los enlaces externos en un sitio WordPress usando CSS mask. La técnica aprovecha pseudo-elementos y máscaras SVG para dibujar un icono coloreable por CSS (usando currentColor) sin añadir imágenes adicionales al DOM ni depender de fuentes de iconos. Incluyo varias opciones: selector CSS puro, mejora con PHP en functions.php para añadir clases y etiquetas accesibles, y un pequeño fallback/ajuste para navegadores.
Por qué usar CSS mask
- Coloreable: con background-color: currentColor el icono toma el color del texto o del enlace.
- Ligero: una máscara SVG (embed o externo) evita cargar fuentes de iconos o sprites adicionales.
- Flexible: se puede colocar con ::after sin modificar el HTML visible.
Resumen de enfoques
- Solo CSS: reconocer enlaces externos por selector y añadir ::after con mask.
- WordPress (recomendado): añadir clase external a enlaces externos desde functions.php y, opcional, insertar una etiqueta con texto para lectores de pantalla.
- Fallback JS: en caso de que queramos soportar selecciones más complejas o navegadores muy antiguos.
Nota importante sobre dominio
En los ejemplos CSS con selectores que excluyen tu dominio, sustituye tudominio.com por el dominio real de tu sitio (sin protocolo).
1) Icono SVG: dos opciones (archivo o data URI)
Puedes usar un archivo SVG en tu theme (por ejemplo: /wp-content/themes/tu-tema/images/external.svg) o incrustarlo como data URI en la propiedad mask. Aquí un SVG simple (símbolo de flecha externa) para usar/convertir:
ltsvg xmlns=http://www.w3.org/2000/svg viewBox=0 0 24 24 fill=none stroke=currentColor stroke-width=2 stroke-linecap=round stroke-linejoin=roundgt ltpath d=M18 13v6a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6 /gt ltpolyline points=15 3 21 3 21 9 /gt ltline x1=10 y1=14 x2=21 y2=3 /gt lt/svggt
Si prefieres el data URI, tendrás que escapar/URL-encodar el SVG para insertarlo en CSS. Para simplificar el tutorial usaré un data URI abreviado en los ejemplos, pero puedes señalar al archivo SVG externo para un caché más eficiente.
2) CSS: selector puro (sin PHP)
Este CSS añade un icono a los enlaces que empiezan por http/https y que no contienen tu dominio. Sustituye tudominio.com por tu dominio real.
/ Selector que detecta enlaces externos (reemplaza tudominio.com) /
a[href^=http]:not([href=tudominio.com]) {
/ opcional: estilos del enlace /
}
/ Añade el icono usando un pseudo-elemento y máscara SVG /
a[href^=http]:not([href=tudominio.com])::after {
content:
display: inline-block
width: 0.9em
height: 0.9em
margin-left: 0.3em
vertical-align: text-bottom
background-color: currentColor / color del icono igual que el texto /
background-repeat: no-repeat
background-position: center
background-size: contain
/ Máscara (para navegadores modernos) - ejemplo usando data URI SVG /
-webkit-mask: url(data:image/svg xmlutf8,) no-repeat center / contain
mask: url(data:image/svg xmlutf8,) no-repeat center / contain
/ No interacciones en el icono /
pointer-events: none
}
/ Pequeño ajuste para enlaces dentro de texto pequeño /
a[href^=http]:not([href=tudominio.com])::after {
transform: translateY(0.06em)
}
Explicación rápida
- background-color: currentColor permite que el icono tome el color del enlace.
- -webkit-mask y mask usan la misma imagen SVG. Mantén ambos para compatibilidad con Safari y Chrome.
- pointer-events: none evita que el pseudo-elemento interfiera en el clic del enlace.
3) Mejor método para WordPress: añadir clase y etiqueta accesible desde functions.php
Es recomendable que la lógica de detectar enlaces externos se haga en el servidor (functions.php) y que se inserte una clase external en esos enlaces. Así el CSS queda limpio y el selector no necesita comprobar el dominio en cliente. Además añadiremos una etiqueta (enlace externo) dentro del enlace para lectores de pantalla.
/
Añade clase .external, target=_blank, rel=noopener noreferrer y un texto accesible
a los enlaces externos dentro del contenido.
Colocar en functions.php del tema hijo.
/
function mi_tema_marcar_enlaces_externos( content ) {
site_host = parse_url( home_url(), PHP_URL_HOST )
libxml_use_internal_errors(true)
dom = new DOMDocument()
// envuelve el contenido para que DOMDocument lo trate bien
dom->loadHTML( . content . )
xpath = new DOMXPath( dom )
foreach ( xpath->query(//a[@href]) as a ) {
href = a->getAttribute(href)
// considerar solo http/https
if ( preg_match(#^https?://#i, href) ) {
href_host = parse_url( href, PHP_URL_HOST )
if ( href_host stripos( href_host, site_host ) === false ) {
// añadir clase external
existing_class = a->getAttribute(class)
a->setAttribute(class, trim(existing_class . external))
// asegurarse de target y rel
if ( ! a->hasAttribute(target) ) {
a->setAttribute(target, _blank)
}
a->setAttribute(rel, noopener noreferrer)
// añadir texto accesible dentro del enlace (visualmente oculto pero disponible a lectores)
sr = dom->createElement(i, (enlace externo)) // la etiqueta está permitida
sr->setAttribute(class, sr-only)
a->appendChild( sr )
}
}
}
// extraer contenido interior del wrapper div
div = dom->getElementsByTagName(div)->item(0)
new_content =
foreach ( div->childNodes as child ) {
new_content .= dom->saveHTML( child )
}
return new_content
}
add_filter( the_content, mi_tema_marcar_enlaces_externos, 20 )
Notas sobre el snippet PHP
- Funciona con el contenido procesado por the_content. Si necesita aplicarse también a widgets/textos en otras áreas, añada filtros adicionales.
- Libxml errores se suprimen para evitar ruidos en el log usar con cuidado si tu HTML es muy irregular.
4) CSS final asociado a la clase .external y estilos para .sr-only
Con el PHP anterior, los enlaces externos tendrán la clase external. Así el CSS queda más claro y fácil de mantener.
/ Icono para enlaces marcados por PHP /
a.external::after {
content:
display: inline-block
width: 0.9em
height: 0.9em
margin-left: 0.3em
vertical-align: text-bottom
background-color: currentColor
-webkit-mask: url(/wp-content/themes/tu-tema/images/external.svg) no-repeat center / contain
mask: url(/wp-content/themes/tu-tema/images/external.svg) no-repeat center / contain
pointer-events: none
}
/ Estilos para el texto accesible añadido () /
.sr-only {
position: absolute !important
width: 1px
height: 1px
padding: 0
margin: -1px
overflow: hidden
clip: rect(0 0 0 0)
clip-path: inset(50%)
border: 0
white-space: nowrap
}
5) Fallback y compatibilidad
- Si usas archivo SVG externo, el navegador lo cacheará — recomendado para producción.
- Para navegadores que no soportan mask, puedes ofrecer un fallback sencillo usando background-image con la misma SVG (aunque no será fácilmente coloreable). Por ejemplo:
/ Fallback simple: fondo con SVG (no recolorable) / a.external.no-mask::after { background-image: url(/wp-content/themes/tu-tema/images/external.svg) background-size: contain background-repeat: no-repeat } - Safari y Chrome requieren -webkit-mask en muchos casos, por eso se añaden ambos prefijos.
6) Variante con JavaScript (opcional)
Si prefieres añadir la clase en cliente (por ejemplo, si no puedes editar functions.php), puedes usar un pequeño script que añada la clase external para todos los enlaces externos al cargar la página.
// Ejecutar en footer o en un archivo JS cargado al final
(function(){
var siteHost = location.host
var links = document.querySelectorAll(a[href^=http])
for (var i = 0 i < links.length i ) {
var a = links[i]
try {
var hrefHost = new URL(a.href).host
if (hrefHost hrefHost.indexOf(siteHost) === -1) {
a.classList.add(external)
if (!a.hasAttribute(target)) a.setAttribute(target,_blank)
a.setAttribute(rel,noopener noreferrer)
// añadir texto accesible si lo necesitas:
var iEl = document.createElement(i)
iEl.className = sr-only
iEl.textContent = (enlace externo)
a.appendChild(iEl)
}
} catch(e) { / ignore invalid URLs / }
}
})()
7) Consideraciones de accesibilidad y SEO
- Para usuarios de lectores de pantalla añadimos un texto accesible (enlace externo) dentro del enlace, oculto visualmente con .sr-only.
- Añadir target=_blank debe acompañarse de rel=noopener noreferrer por seguridad y rendimiento.
- Evita usar solo CSS generated content para texto informativo, ya que los lectores de pantalla pueden no leer contenido generado por CSS por eso el enfoque PHP/JS inserta texto real dentro del enlace.
8) Recomendaciones finales
- En entorno de producción usa la variante PHP (functions.php) o un plugin para modificar el contenido del servidor. Es más fiable y evita depender de JS.
- Usa SVG externo para cache y rendimiento. Usa data URI solo para pruebas o en casos concretos.
- Prueba en distintos navegadores (Safari, Chrome, Firefox) porque el soporte de mask puede variar incluye -webkit-mask para compatibilidad con WebKit.
- Ten cuidado con el parseo HTML en PHP: la función con DOMDocument funciona bien en contenido típico pero revisa en páginas con HTML muy fragmentado.
Recursos útiles
Conclusión
Con una combinación de un pequeño ajuste en functions.php (para marcar enlaces externos y añadir texto accesible) y la potencia de CSS mask, puedes mostrar un icono automático y coloreable junto a los enlaces externos sin añadir elementos extra visibles ni sobrecargar recursos. El resultado es ligero, accesible y fácil de mantener.
Leave a Reply