API de resaltado personalizado de CSS: de un vistazo trucos CSS

Alcance de la estilización del texto en el software es algo muy útil que puede hacer. Afortunadamente, tenemos una API de resaltado personalizado de CSS que esperamos, porque representa el futuro del estilo de rango de texto basado en la web.
Un ejemplo: si alguna vez ha utilizado software de edición de texto como Google Docs, Word o Dropbox Paper, descubrirá que detectan errores ortográficos y gramaticales y muestran pequeñas líneas curvas agradables debajo de ellos para llamar la atención. Los editores de código como VS Code hacen lo mismo con los errores de código.

Otro caso muy común de resaltado de texto es buscar y resaltardonde se le proporciona un campo para ingresar texto e ingresarlo busca resultados relevantes en la página y los marca. Intenta presionar Ctrl
/⌘
+ F
en su navegador web ahora mismo e ingrese el texto de este artículo.

El navegador mismo a menudo maneja estas situaciones de estilo. Áreas editables (como un <textarea>
) obtienen automáticamente garabatos ortográficos. El comando de búsqueda resalta automáticamente el texto encontrado.
Pero, ¿qué pasa cuando queremos hacer este tipo de estilo nosotras mismas? Hacer esto en línea ha sido un problema común durante mucho tiempo. Probablemente le cueste a muchas personas mucho más tiempo de lo que debería.
Este no es un problema fácil de resolver. No solo envolvemos el texto en un <span>
con una clase y la aplicación de algún CSS. De hecho, requiere que seas capaz de enfatizar correctamente múltiple rangos de texto en cualquier árbol DOM complejo y posiblemente cruzar los límites de los elementos DOM.
Hay dos soluciones comunes para esto, que incluyen:
- estilizar pseudo-elementos de rango de texto, y
- crea tu propio sistema de resaltado de texto.
Los revisaremos primero y luego veremos la próxima API CSS Custom Highlight, que puede cambiarlo todo. pero si eres
Posible solución №1: rangos de texto con capacidad de estilo
Probablemente el rango de texto con opción de estilo más famoso es la selección del usuario. Cuando utiliza su dispositivo señalador para seleccionar un fragmento de texto en una página web, Selection
el objeto se crea automáticamente. De hecho, intente seleccionar texto en esta página ahora mismo y luego comience document.getSelection()
en la consola de DevTools. Debería ver información sobre la ubicación del texto seleccionado.

Resulta que también puede crear una selección de texto mediante programación desde JavaScript. Aquí hay un ejemplo:
// First, create a Range object.
const range = new Range();
// And set its start and end positions.
range.setStart(parentNode, startOffset);
range.setEnd(parentNode, endOffset);
// Then, set the current selection to this range.
document.getSelection().removeAllRanges();
document.getSelection().addRange(range);
La última parte del rompecabezas es diseñar esta gama. CSS tiene un pseudo-elemento llamado ::selection
para hacer precisamente eso y mantenerlo en todas partes todos los navegadores.
::selection {
background-color: #f06;
color: white;
}
Aquí hay un ejemplo del uso de esta técnica para subrayar todas las palabras en una página una tras otra:
Encima de ::selection
pseudo-elemento, hay una serie de otros pseudo-elementos:
::target-text
selecciona el texto al que se desplaza en navegadores compatibles desplazarse al texto rasgo. (MDN)::spelling-error
selecciona el texto que el navegador marca como que contiene un error ortográfico. (MDN)::grammar-error
selecciona el texto que está marcado por el navegador como que contiene un error gramatical. (MDN)
Desafortunadamente, el soporte del navegador no es muy bueno aquí, y aunque estos rangos son útiles por derecho propio, no se pueden usar para diseñar piezas de texto personalizadas, solo predefinidas por el navegador.
Por lo tanto, la elección del texto personalizado es buena porque es relativamente fácil de pegar y no cambia el DOM de la página. Range
los objetos son esencialmente coordenadas de segmentos en la página, no elementos HTML que deben crearse para existir.
Sin embargo, un inconveniente importante es que al crear una selección se restablece todo lo que el usuario ya seleccionó manualmente. Intente seleccionar texto en la demostración anterior para probar esto. Verá que desaparece tan pronto como el código mueva la selección a otra parte.
Solución potencial №2: Sistema de resaltado personalizado
Esta segunda solución es casi lo único que puede hacer si usa Selection
el objeto es insuficiente para ti. Esta solución gira en torno a hacer todo usted mismo, utilizando JavaScript para insertar nuevos elementos HTML en el DOM donde desea que aparezca el guión bajo.
Desafortunadamente, esto significa mucho más JavaScript para escritura y soporte, sin mencionar obligar al navegador a recrear el diseño de la página cuando cambia el resaltado. Además, existen casos extremos complejos, por ejemplo, cuando desea resaltar un fragmento de texto que cubre varios elementos DOM.

es interesante, CódigoMirror y Mónaco (la biblioteca del editor de texto de JavaScript que impulsa VS Code) tiene su propia lógica de subrayado. Utilizan un enfoque ligeramente diferente, en el que los aspectos más destacados están contenidos en una parte separada del árbol DOM. Las líneas de texto y los segmentos resaltados se muestran en dos lugares diferentes en el DOM, que luego se colocan uno encima del otro. Si marca el subárbol DOM que contiene el texto, no hay acentos. De esta forma, se pueden retratar los acentos sin afectar las líneas del texto y sin tener que introducir nuevos elementos en ellas.
En general, parece haber una falta de resaltado impulsado por el navegador, algo que ayudaría a resolver todas estas deficiencias (sin interferir con la selección de texto personalizado, soporte de opción múltiple, código simple) y sería más rápido que las decisiones personalizadas.
Afortunadamente, ¡eso es de lo que estamos aquí para hablar!
Ingrese la API de resaltado personalizado de CSS
EN API de resaltado personalizado de CSS es una nueva especificación W3C (actualmente en estado de borrador) que le permite diseñar rangos de texto aleatorios desde JavaScript. El enfoque aquí es muy similar a la técnica de selección de texto personalizado que revisamos anteriormente. Brinda a los desarrolladores una forma de crear rangos aleatorios desde JavaScript y luego diseñarlos usando CSS.
Crear rangos de texto
El primer paso es crear los rangos de texto que desea resaltar, lo que se puede hacer usando un Range
en JavaScript. Entonces, como hicimos al configurar la selección actual:
const range = new Range();
range.setStart(parentNode, startOffset);
range.setEnd(parentNode, endOffset);
Cabe resaltar que setStart
y setEnd
los métodos funcionan de manera diferente si el nodo pasado como primer argumento es un nodo de texto o no. Para los nodos de texto, el desplazamiento corresponde al número de caracteres en el nodo. Para otros nodos, el desplazamiento corresponde al número de nodos secundarios en el nodo principal.
También vale la pena señalar que setStart
y setEnd
estas no son las únicas formas de describir dónde comienza y termina un rango. Echar un vistazo otros metodos disponible en Range
clase para ver otras opciones.
Creando acentos
El segundo paso es crear Highlight
objetos para los rangos creados en este último paso. A Highlight
el objeto puede recibir uno o más Range
s. Entonces, si desea resaltar un montón de piezas de texto exactamente de la misma manera, probablemente necesite crear una sola Highlight
objeto e inicializarlo con todos Range
que corresponden a estas partes del texto.
const highlight = new Highlight(range1, range2, ..., rangeN);
Pero también puedes crear tanto Highlight
objetos que necesites. Por ejemplo, si crea un editor de texto colaborativo en el que cada usuario recibe un color de texto diferente, puede crear uno Highlight
objeto de usuario. Luego, cada objeto se puede estilizar de manera diferente, como veremos a continuación.
registro de acentos
Ahora los objetos Resaltar no hacen nada por sí solos. Primero deben registrarse en el llamado registro de resaltado. Esto se hace con la ayuda de API de aspectos destacados de CSSEl registro funciona como un mapa, donde puede registrar nuevos aspectos destacados nombrándolos, así como eliminar elementos destacados (o incluso borrar todo el registro).
Aquí se explica cómo registrar un solo acento.
CSS.highlights.set('my-custom-highlight', highlight);
Donde my-custom-highlight
es el nombre de su elección y highlight
es Highlight
objeto creado en el último paso.
Acentos con estilo
El último paso es aplicar estilo a los aspectos destacados registrados. Esto se hace con el nuevo CSS. ::highlight()
pseudo-elemento usando el nombre que seleccionó al registrarse Highlight
objeto (que es my-custom-highlight
en nuestro ejemplo anterior).
::highlight(my-custom-highlight) {
background-color: yellow;
color: black;
}
Vale la pena señalar que al igual que ::selection
un subconjunto de propiedades CSS solo se puede usar con ::highlight()
pseudo-elemento:
Actualizar destacados
Hay varias formas de actualizar el texto resaltado en una página.
Por ejemplo, puede borrar completamente el registro para resaltar con CSS.highlights.clear()
y luego empezar de nuevo desde el principio. O también puedes actualizar los rangos principales sin tener que recrear ninguno de los objetos. usar para esto range.setStart
y range.setEnd
métodos de nuevo (o uno de los otros Range
métodos) y los aspectos más destacados serán repintados por el navegador.
Pero, Highlight
el objeto funciona como JavaScript Set
eso significa que estás agregando nuevos Range
objetos de existentes Highlight
s highlight.add(newRange)
o eliminar un Range
s highlight.delete(existingRange)
.
En tercer lugar, también puede agregar o eliminar Highlight
artículos de CSS.highlights
Registrarse. Porque esta API funciona como JavaScript Map
puede set
y delete
para actualizar los registrados actualmente Highlight
s.
Compatibilidad con navegador
La especificación de la API CSS Custom Highlight es relativamente nueva y su implementación en los navegadores aún está incompleta, por lo que, aunque será una adición muy útil a la plataforma web, aún no está lista para la producción.
El equipo de microsoft Edge está implementando actualmente la API CSS Custom Highlight en Chromium. De hecho, la función ahora se puede usar en las versiones actuales de Canary activando el indicador de función en una plataforma web experimental (abajo about:flags
). Actualmente no hay un plan firme sobre cuándo estará disponible la función en Chrome, Edge y otros navegadores basados en Chromium, pero está muy cerca.
La API también es compatible con Safari 99+ pero detrás de la bandera del experimento (Desarrollo → Características experimentales → API destacada), y la interfaz es un poco diferente ya que usa StaticRange
en lugar de objetos.
Firefox aún no es compatible con la API, pero puedes lea la posición de Mozilla al respecto Para más información.
Demostración
Hablando de Microsoft Edge, tienen una demostración personalizada en la que puede obtener la API CSS Custom Highlight para realizar una prueba de manejo. Pero antes de probar la demostración, asegúrese de estar usando Chrome o Edge Canary con el indicador de características de la plataforma web experimental en about:flags
página.
/ botón Mira la demostración
La demostración utiliza la API de resaltado personalizado para resaltar rangos de texto en la página según lo que escriba en el cuadro de búsqueda en la parte superior de la página.
Una vez que se carga la página, el código JavaScript recupera todos los nodos de texto de la página (usando un TreeWalker) y cuando el usuario ingresa en el cuadro de búsqueda, el código repite estos nodos hasta que encuentra coincidencias. Estas coincidencias se utilizan luego para crear Range
objetos, que luego se marcan con la API de resaltado personalizado.
Observaciones finales
Entonces, ¿realmente vale la pena esta API resaltada en el navegador? ¡Absolutamente!
Por un lado, incluso si la API CSS Custom Highlight puede parecer un poco complicada al principio (es decir, tener que crear rangos, luego resaltarlos, luego registrarlos y finalmente diseñarlos), sigue siendo mucho más simple que tener que crear un nuevo DOM. elementos e insértelos en los lugares correctos.
Más importante aún, los navegadores pueden diseñar estos rangos muy, muy rápidamente.
La razón por la que solo se permite usar un subconjunto de propiedades CSS con ::highlight()
el pseudoelemento es que el subconjunto contiene solo propiedades que el navegador puede aplicar de manera muy eficiente sin tener que recrear el diseño de la página. Resaltar rangos de texto mediante la inserción de nuevos elementos DOM en la página que los rodea requiere que el motor haga mucho más trabajo.
Pero no confíes en mi palabra. fernando fioriquien está trabajando en la API creó este bonito demostración de comparación de rendimientoEn mi computadora, la API CSS Custom Highlight se ejecuta en promedio 5✕ más rápido que el resaltado basado en DOM.
Con el soporte experimental para Chromium y Safari ya aquí, nos estamos acercando a algo que se pueda usar en producción. ¡No puedo esperar a que los navegadores admitan constantemente la API de Resaltado personalizado y ver qué características desbloqueará!