Back

Estilización de Texto con la API CSS Custom Highlight

Estilización de Texto con la API CSS Custom Highlight

La API CSS Custom Highlight resuelve un problema fundamental: cómo resaltar rangos de texto programáticamente sin saturar el DOM con elementos contenedores. Ya sea que estés construyendo interfaces de búsqueda, editores de texto o aplicaciones educativas, esta API ofrece un enfoque más limpio y eficiente que los métodos tradicionales basados en <mark> o elementos span.

Puntos Clave

  • La API CSS Custom Highlight permite resaltar texto sin manipular el DOM
  • Los resaltados funcionan a través de objetos Range, objetos Highlight y el registro CSS.highlights
  • El rendimiento mejora significativamente ya que no ocurren recálculos de diseño
  • Múltiples rangos no contiguos pueden ser resaltados simultáneamente

Qué Hace Diferente a la API CSS Custom Highlight

El resaltado de texto tradicional requiere modificar la estructura del DOM. Usar elementos <mark> o spans significa insertar nodos, activar recálculos de diseño y gestionar HTML complejo cuando los resaltados abarcan múltiples elementos. La API CSS Custom Highlight elimina estos problemas al trabajar con rangos de JavaScript y el pseudo-elemento ::highlight, manteniendo tu DOM intacto.

La API consiste en tres componentes principales:

  • Objetos Range que definen los límites del texto
  • Objetos Highlight que agrupan rangos
  • Registro CSS.highlights que conecta los resaltados con los estilos

Creación y Estilización de Rangos de Texto

Construyendo tu Primer Resaltado

Comienza creando un objeto Range para definir qué texto resaltar:

const range = new Range();
const textNode = document.querySelector('p').firstChild;
range.setStart(textNode, 0);
range.setEnd(textNode, 20);

A continuación, crea un objeto Highlight y regístralo:

const highlight = new Highlight(range);
CSS.highlights.set('my-highlight', highlight);

Finalmente, aplícale estilo con el pseudo-elemento ::highlight:

::highlight(my-highlight) {
  background-color: yellow;
  color: black;
}

Implementación de Resaltado de Resultados de Búsqueda

Aquí tienes un ejemplo práctico para resaltar resultados de búsqueda en tu documento:

function highlightSearchResults(searchTerm) {
  // Limpiar resaltados existentes
  CSS.highlights.delete('search-results');
  
  const walker = document.createTreeWalker(
    document.body,
    NodeFilter.SHOW_TEXT
  );
  
  const ranges = [];
  let node;
  
  while (node = walker.nextNode()) {
    const text = node.textContent;
    const regex = new RegExp(searchTerm, 'gi');
    let match;
    
    while (match = regex.exec(text)) {
      const range = new Range();
      range.setStart(node, match.index);
      range.setEnd(node, match.index + searchTerm.length);
      ranges.push(range);
    }
  }
  
  if (ranges.length > 0) {
    const searchHighlight = new Highlight(...ranges);
    CSS.highlights.set('search-results', searchHighlight);
  }
}

Patrones Avanzados: Resaltados Multi-Rango

El verdadero poder emerge al trabajar con múltiples rangos de texto no contiguos. Un solo objeto Highlight puede contener múltiples objetos Range:

// Resaltar múltiples párrafos separados
const range1 = new Range();
range1.selectNodeContents(document.querySelector('#intro'));

const range2 = new Range();
range2.selectNodeContents(document.querySelector('#conclusion'));

const highlight = new Highlight(range1, range2);
CSS.highlights.set('important-sections', highlight);

También puedes gestionar múltiples grupos de resaltado simultáneamente:

// Diferentes tipos de resaltado con estilos distintos
CSS.highlights.set('errors', new Highlight(...errorRanges));
CSS.highlights.set('warnings', new Highlight(...warningRanges));
CSS.highlights.set('info', new Highlight(...infoRanges));
::highlight(errors) {
  background-color: #fee;
  text-decoration: wavy underline red;
}

::highlight(warnings) {
  background-color: #ffa;
}

::highlight(info) {
  background-color: #e6f3ff;
}

Beneficios de Rendimiento y Compatibilidad del Navegador

La API CSS Custom Highlight sobresale en escenarios críticos de rendimiento. A diferencia de la manipulación del DOM, los resaltados no activan recálculos de diseño ni crean sobrecarga de memoria por elementos adicionales. El motor de renderizado del navegador maneja los resaltados en la capa de pintura, haciendo las actualizaciones notablemente rápidas.

A partir de 2025, Chrome, Edge y Safari soportan la API, con el soporte de Firefox en desarrollo. Para navegadores más antiguos, implementa un fallback con detección de características:

if ('CSS' in window && 'highlights' in CSS) {
  // Usar API Custom Highlight
  const highlight = new Highlight(range);
  CSS.highlights.set('fallback-safe', highlight);
} else {
  // Fallback al enfoque tradicional
  const span = document.createElement('span');
  span.className = 'highlight';
  range.surroundContents(span);
}

Consejos de Implementación Práctica

Al implementar resaltado de texto en producción:

  1. Limpia los resaltados no utilizados para prevenir fugas de memoria:

    CSS.highlights.delete('old-highlight');
  2. Maneja contenido dinámico actualizando rangos cuando el DOM cambie:

    highlight.add(newRange);
    highlight.delete(oldRange);
  3. Usa nombres de resaltado significativos que describan su propósito (ej. ‘search-results’, ‘spell-check’, ‘user-annotations’)

Conclusión

La API CSS Custom Highlight transforma cómo abordamos el resaltado de texto en la web. Al separar la lógica de resaltado de la estructura del DOM, ofrece mejor rendimiento, código más limpio y mayor flexibilidad que los métodos tradicionales. Comienza a experimentar con rangos de texto resaltado en tu próximo proyecto: tus usuarios (y tu DOM) te lo agradecerán.

Preguntas Frecuentes

Sí, la API puede resaltar texto que abarca múltiples elementos. Los objetos Range pueden comenzar en un elemento y terminar en otro, lo que la hace perfecta para resaltar frases que cruzan límites de párrafos o elementos span.

Los resaltados permanecen unidos a sus objetos Range originales. Si el DOM cambia, necesitas actualizar o recrear manualmente los rangos. La API no rastrea automáticamente las mutaciones del DOM, así que implementa tu propio patrón observador para contenido dinámico.

Múltiples resaltados pueden superponerse en el mismo rango de texto. El navegador aplica todos los estilos de resaltado coincidentes, con los estilos definidos posteriormente tomando precedencia. Puedes controlar el apilamiento visual a través de propiedades CSS como background-color y opacity.

Truly understand users experience

See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..

OpenReplay