Cómo desarrollar un editor de texto para la web
Publicado: 2022-03-10Trabajo para Readymag, que fabrica una herramienta de diseño basada en navegador que ayuda a las personas a crear sitios web, portafolios y todo tipo de publicaciones en línea, sin codificación. Hay muchos widgets disponibles en nuestra herramienta, y el widget de texto es uno de los más utilizados.
El widget de texto es un campo de entrada de texto en el que el usuario puede aplicar estilo al texto mediante una variedad de controles en el editor. Cada control aplica una propiedad CSS al texto. Desde el punto de vista del usuario, parece un campo común para ingresar texto, pero una gran cantidad de procesos complejos se esconden detrás de su aparente simplicidad.
En este artículo, explicaré los desafíos que enfrentó mi empresa y las soluciones que usamos para crear un widget de texto en nuestra aplicación. También me sumergiré en cómo lo implementamos y lo que aprendimos en el camino, y cómo funciona escribir en la web en general.
Edición de texto en la Web
Hay varias formas de implementar campos de entrada de texto en la web. Podríamos usar un campo de texto simple, o un elemento de contenteditable
textarea
hacer que una entrada sea editable, o document.designMode = on
. ¿En qué se diferencian?
Los elementos input
y textarea
son ideales para agregar texto a una página, pero no brindan una experiencia rica en formato de texto. Para esto, podemos usar el atributo contenteditable
para hacer editable casi cualquier elemento y habilitar el uso de estilos de texto.
Si necesita editar toda la página a la vez, puede usar document.designMode
. Este modo permite editar cualquier elemento dentro de un documento dado, incluso un iframe
.
Optamos por el atributo contenteditable
, que incluye todas las capacidades de edición de texto necesarias. Con este atributo, cualquier texto de la página se vuelve editable, lo cual es muy importante si queremos que las personas puedan diseñar el texto con CSS . Por ejemplo, los usuarios podrían diseñar secciones seleccionadas o todo el texto directamente.
Estilos de texto y propiedades de fuente
Permitimos a los usuarios diseñar el texto de la forma que deseen al brindarles acceso a todas las opciones que ofrece CSS listas para usar. Además de las propiedades conocidas, como la fuente, el estilo, el color y la decoración, ofrecemos a los usuarios la oportunidad de utilizar funciones de fuente OpenType, como ligaduras, conjuntos estilísticos, fracciones, etc. Estas funciones funcionan a través de la propiedad CSS font-feature-settings
, que permite a los usuarios personalizar los estilos de texto.
Nota : recomiendo leer el excelente artículo de Sparanoid que muestra todas las características de OpenType.
La tipografía moderna ha dado un gran paso adelante, permitiendo el uso de fuentes variables en la web a través de la propiedad font-variation-settings
.
Cada fuente variable tiene propiedades variables cuyos valores puede cambiar. Por ejemplo, en una fuente estándar, puede cambiar el peso de la fuente usando valores estrictamente especificados ( 400
, 500
, 600
, etc.), mientras que en una fuente variable, puede usar cualquier valor en el rango disponible, brindando posibilidades más amplias. para el estilo de texto.
.style-1 { font-weight: 600; } .style-2 { font-variation-settings: "wght" 777; }
A continuación puede ver un ejemplo de cómo se ve trabajar con una fuente variable en un widget de texto.
Además de los valores registrados ( wght
, wdth
, slnt
, etc.), los creadores de fuentes también pueden crear sus propias características de fuente únicas (como en el ejemplo anterior). Para dar a nuestros usuarios la oportunidad de utilizar todas las funciones de fuentes posibles, primero necesitamos esta información.
Todas las características que desea utilizar deben definirse en el archivo de fuente. Veamos sus especificaciones. Cada fuente se puede representar en forma de tablas, proporcionando toda la información diferente utilizada al representar sus caracteres.
Usamos dos tablas para recopilar esta información sobre las fuentes:
- Tabla de sustitución de glifos
La tabla de sustitución de glifos (GSUB) contiene una lista de datos de representación de glifos. El objetoGSUB.featureList
es una enumeración de características de fuentes y sus propiedades. Puede ver un ejemplo de datos en la tabla en GitHub. En esta tabla, el campotag
es el más interesante. Este es el nombre de la función de fuente e indica que esta función está disponible con esta fuente. Podemos usar de forma segura latag
en la propiedadfont-feature-settings
. - Tabla de variaciones de fuente
La tabla de variaciones de fuentes (fvar) es una representación de las propiedades variables asociadas con una fuente. Un ejemplo de la tabla también está disponible en GitHub. Cada objeto es una propiedad de fuente, con una descripción de los valores posibles (min
,max
, default) y un nombre localizado (si lo hay). Usamos estos valores con la propiedadfont-variation-settings
.
Con la ayuda de estas dos tablas, podemos cubrir todos nuestros requisitos: usar propiedades de fuente variables y varias características de fuente. Los datos resultantes se muestran en los controles de widget de texto en el editor, donde los usuarios pueden diseñar el texto sin usar ningún código.
Usando tu teclado
La entrada de texto es uno de los aspectos más importantes de la experiencia del usuario del widget de texto. Además de habilitar atajos para trabajar con texto, tuvimos que enfrentar algunos desafíos inusuales. Navegar por el texto con las teclas de flecha fue definitivamente uno de ellos.
Mientras el usuario está editando, el widget de texto también muestra caracteres ocultos, como espacios sin separación y saltos de línea. Se implementan como iconos SVG insertados en el texto, lo que plantea un problema: si usamos contenteditable
, estos iconos impiden que los usuarios muevan el cursor con las teclas de flecha.
La solución es bastante simple: use un span
y el pseudo-elemento :before
. De esta manera, el navegador percibe el ícono como texto y las teclas de flecha funcionan muy bien.
span:before { content: ""; height: 1em; position: relative; background-repeat: no-repeat; background-image: url("data:image/svg+xml,..."); background-position: center bottom; background-size: 1em; }
Atajos
Hay dos métodos abreviados de teclado para pegar texto en un widget de texto.
Cmd / Ctrl + V pega el texto del portapapeles y conserva los estilos que tenía en el documento original. Si el texto se copió de una aplicación como Pages, Notes, Word o Google Docs, su portapapeles contendrá información HTML, no solo texto sin formato. Este HTML se puede analizar y pegar manteniendo los estilos originales.
Puede obtener los datos HTML de la siguiente manera:
// https://www.w3.org/TR/clipboard-apis/#reading-from-clipboard document.addEventListener('paste', (e) => { const text = e.clipboardData.getData('text/plain'); const html = e.clipboardData.getData('text/html'); handlePaste(); });
Además, tenemos el atajo Cmd + Shift + V. Cuando inserta texto usando esta combinación de teclado, el navegador dejará los datos sin formato en la carga útil, por lo que el destino de pegado controla el estilo. Estos accesos directos existen en el navegador de forma predeterminada, pero debe recordar implementarlos en su proyecto.
Selección de texto y enfoque
La selección de texto ayuda a los usuarios a ver qué fragmento de texto se está editando actualmente. Probemos un ejemplo simple: un campo de entrada con un botón para controlar la negrita del texto.
En este ejemplo, podemos seleccionar un fragmento de texto y presionar el botón Bold
, y la selección en el texto permanecerá después. Pero, ¿y si nuestro ejemplo es más complicado? Digamos que agregamos un campo de entrada al selector de tamaño de texto. En este caso, el foco cambiará a la nueva entrada.
Hay dos opciones para solucionar este problema :
- Después de cada evento de entrada, obligamos al foco a volver al bloque de texto. En este caso, la selección comenzará a parpadear después de una cierta cantidad de eventos de entrada; no queremos eso.
- Podemos agregar el bloque de texto a un
iframe
. Como probablemente sepa, uniframe
tiene su propio objeto dewindow
global. Por lo tanto, siempre que la selección esté dentro deliframe
, persistirá incluso si se mueve el foco fuera.
Terminamos con un widget de texto envuelto en iframe
. Por lo tanto, siempre que la selección esté dentro del iframe
, persistirá incluso si se mueve el foco fuera. Eche un vistazo a la captura de pantalla a continuación. Tenemos dos selecciones en la página: el fragmento seleccionado en el widget de texto y el valor seleccionado del tamaño del texto en el control.
Rendimiento durante la entrada de texto
La capacidad de respuesta de su interfaz de edición de texto es importante. Controle de cerca el valor de fotogramas por segundo (FPS), especialmente cuando se trata de tareas como editar texto a alta velocidad o cambiar el tamaño de fuente.
Readymag tiene dos ventanas gráficas: escritorio y móvil . Los estilos de texto pueden aparecer diferentes en cada uno. Mientras se ingresa el texto, el editor realizará varios cálculos para sincronizar los datos entre las ventanas gráficas. Se logra una alta capacidad de respuesta mediante el uso de la API del navegador: requestAnimationFrame
y requestIdleCallback
:
-
requestAnimationFrame
se llama cada vez que se actualiza la pantalla; -
requestIdleCallback
se llama solo cuando el navegador está inactivo.
Esta es una excelente manera de realizar operaciones tediosas sin bloquear el hilo principal.
Accesibilidad
Habilitar la accesibilidad es una de las prácticas más importantes en el desarrollo web actual. Si su sitio web está diseñado teniendo en cuenta la accesibilidad, permitirá que más personas accedan a su producto . Esto significa acomodar no solo a las personas con discapacidad, sino también a los usuarios en diferentes plataformas: dispositivos de escritorio y táctiles, lectores de pantalla, dispositivos auditivos, etc. Para comprender cuán importante puede ser hacer que los proyectos sean accesibles, recomiendo consultar las estadísticas de accesibilidad recientes.
Para comenzar a incorporar prácticas de accesibilidad web, primero consulte las Pautas de accesibilidad al contenido web (WCAG), el recurso más completo sobre el tema. Y siempre que Readymag sea una herramienta para publicación, además de las WCAG, también debemos seguir las Pautas de accesibilidad de herramientas de autor (ATAG).
Nuestro equipo se encuentra actualmente en la etapa de integración de la accesibilidad en el editor. En artículos posteriores, compartiremos más sobre nuestro viaje hacia la integración total de la accesibilidad en Readymag. También puede consultar cualquier trabajo realizado con Readymag utilizando nuestra lista de verificación de accesibilidad.
Mejores prácticas
Finalmente, aquí hay algunos consejos para ayudarlo a desarrollar un editor de texto en la web:
- Piense cuidadosamente en el diseño.
Identifique de antemano qué capacidades necesita y cómo trabajará con los elementos en el editor de texto. - Configure las pruebas visuales.
Cuando trabaja con texto, no puede confiar completamente en el resultado de la prueba instantánea. Puede obtener el resultado correcto en la prueba, esperando el CSS dado para el bloque, pero a veces el resultado puede no ser el esperado. - Pruebe su trabajo en diferentes navegadores.
Si bien la mayoría de los navegadores admiten razonablemente bien las nuevas funciones en línea, a menudo hay problemas al mostrar los mismos estilos en diferentes navegadores. - Use indicadores de funciones para un desarrollo más seguro de nuevas funciones.
- Mide FPS en el navegador al ingresar texto.
No realice tareas que requieran un uso intensivo de la CPU en un solo subproceso. - No tengas miedo de experimentar .
- Por último, pero no menos importante, pruebe Text Widget en Readymag.
Algunos enlaces útiles
- “La demostración completa de CSS para funciones OpenType”, Sparanoid
- “Introducción a las fuentes variables en la web”, web.dev
- “Impresionante tipografía”, Joel Galeran
- “Fuentes variables”, Nick Sherman
- kit de fuentes
- OpenType.js