Tag Archives: navegadores

Bug Webkit contenteditable

Foto de Justin Raycraft en Flickr

Errores de formato en elementos contenteditable con Webkit (Chrome, Safari)

contenteditable es un atributo que nos llegó con HTML5 y que permite que ciertos elementos HTML sean editables o modificables en el navegador del usuario. Esta propiedad la usan muchos editores de texto para páginas web, algunos tan populares como TinyMCE.

Webkit (el motor de renderizado de navegadores como Safari, Opera y los que utilizan Blink como Chrome) tiene un problema en la manera en que gestiona los objetos contenteditable: cuando se han aplicado estilos específicos (por ejemplo en el body de un editor TinyMCE), en ciertas ocasiones algunos de estos estilos añadidos (como line-height o font-size en ems) generan regiones span indeseadas dentro del código, cosa que puede comportar cambios imprevistos en el formato obtenido, como diferentes tamaños de letra o interlineados inesperados.

El problema existe desde hace algunos años y ha sido reportado, aunque nunca ha sido corregido. Por lo visto se considera parte de una funcionalidad que compara los estilos al modificar bloques e intenta mantenerlos insertando elementos span en línea. Con todo, en Firefox, Internet Explorer y Microsoft Edge no se da este caso.

Algunas soluciones

Los editores WYSIWYG más populares han ido añadiendo conectores o plugins o bien cambios para compensar este error, por lo que en muchos casos solo será necesario actualizar el software o las bibliotecas correspondientes.

Sin embargo, en determinados escenarios no siempre nos es posible actualizar los editores, bien por razones de compatibilidad o porque hay involucradas aplicaciones críticas que no podemos manipular con facilidad o con la frecuencia que quisiéramos. En estos casos podemos optar por otras soluciones más simples, como utilizar estilos uniformes o parches con JavaScript.

Una de las soluciones propuestas en Stack Overflow es observar el DOM para controlar este comportamiento. Fijémonos en el siguiente ejemplo: en la tercera caja utilizamos mutation observers en vez de mutation events, y restringimos la acción a  la plataforma Webkit:

(Explora éste código en JSFiddle)