Internacionalización más fácil (Parte 2 de 3)

2024-07-14

En la primera parte de esta serie hablé sobre cómo muchos elementos HTML entienden que se tienen que renderizar de formas diferentes cuando se usan propiedades de CSS o atributos HTML específicos.

En esta segunda parte, voy a continuar con más propiedades y valores de CSS que podemos usar para que nuestro código reaccione a cambios de dirección, y algunos tips al implementar layouts.

Layout

Cuando tengo que definir el layout de una página o de sus componentes, siempre prefiero usar CSS Grid. Ya vimos cómo CSS Grid funciona diferente dependiendo de la dirección, pero veamos un ejemplo específico para un layout.

Grid Named Areas

CSS Grid es una funcionalidad asombrosa de CSS, es muy versátil y la naturaleza declarativa al definir áreas con nombres es una de mis partes favoritas.

Al definir una Grid, podemos usar la propiedad grid-template-areas para definir el layout y dar un significado claro a cada área.

Luego, la dirección definida para el elemento también afecta el orden de las áreas. Ejemplo en CodePen:

See the Pen Grid LTR vs RTL by Ariel Juod (@arieljuod) on CodePen.

Posición de la barra de Scroll

Algo más a tener en cuenta al cambiar la dirección de escritura es que la posición de la barra de scroll también va a cambiar de lado si se debe mostrar.

See the Pen Scrollbar position by Ariel Juod (@arieljuod) on CodePen.

Nota: los navegadores, en general, no muestran la barra de scroll principal en el lado izquierdo incluso cuando el tag html está en dirección derecha-izquierda si el sistema no está configurado también en ese modo. Al testear distintos lenguajes, es probable que algunas barras de scroll no estén posicionadas donde queremos.

Propiedades y Valores Lógicos de CSS

Entonces, ya tenemos nuestro layout LTR (left-to-right), agregamos la propiedad direction: rtl donde se necesite y todos nuestros elementos ahora se renderizan en el sentido correcto, pero hay un problema... Veamos un ejemplo del problema en Heroic:

Al inicio de la Biblioteca mostramos este título All Games y a la de derecha mostramos una píldora con la cantidad de juegos mostrados:

Cambiamos el lenguaje a uno RTL y podemos ver que el espacio entre la píldora y el título desapareció (en realidad está ahí, pero en el lado incorrecto).

Márgenes y Paddings

Para resolver este problema, en lugar de usar margin-left, podemos usar margin-inline-start. Esto se conoce como una propiedad lógica que va a respetar la dirección del elemento, ya que start tiene un significado diferente según la dirección.

Ahora, con el cambio, el margen cambia de la izquierda a la derecha de la píldora y no nos tenemos que preocupar:

Algunos pueden pensar que, en este caso en particular, en lugar de usar un márgen se podría usar una separación de columnas (column gap) si el elemento padre es un flex box (que lo es en Heroic). Una separación tiene más sentido en ese caso en lugar de pensar en márgenes cuando no es necesario, pero ese es el código actual de Heroic y lo estoy usando sólo como ejemplo. No recomiendo usar un márgen para esto.

Left/Right/Top/Bottom vs Start/End y Inline/Block

En lugar de pensar en izquierda/derecha/arriba/abajo (left/right/up/down), cuando trabajamos usando propiedades lógicas tenemos que empezar a pensar en la dirección en que el contenido de un elemento se renderiza, dónde empieza y dónde termina, vertical u horizontal, etc.

En el modo por defecto de texto horizontal de izquierda a derecha, podemos pensar en estas equivalencias:

Y el mismo concepto aplica a paddings.

Nota: la propiedad corta margin es equivalente a usar top/right/bottom/left en lugar de propiedades lógicas, por lo que hay que tener cuidado. Se pueden usar las propiedades cortas margin-inline y margin-block en su lugar.

Inline vs Block

Las propiedades inline hacen referencia a la dirección en que el texto se escribe, mientras que las propiedades block hacen referencia a la dirección en que aparecen nuevas líneas de texto. O sea que, en un modo de escritura vertical, las propiedades block serían izquierda y derecha en lugar de arriba y abajo.

Posicionamiento Dentro de Grid y Flex

Cuando queremos ubicar elementos dentro de un contenedor Flex o de una celda de Grid, usamos las propiedades align-items/content-self y justify-items/content/self. Similar a los márgenes y paddings, en lugar de usar los valores left y right, podemos usar start y end.

Inline vs Block

Las propiedades align-* alinean los elementos en la dirección block (verticalmente por defecto). Y las propiedades justify-* se usan para alinear en la dirección inline (horizontal por defecto).

Posicionamiento Absoluto

A veces necesitamos usar la propiedad position: absolute y típicamente definimos la posición del elemento dentro de su padre usando las propiedades top/right/bottom/left. Pero también podemos usar propiedades lógicas para esto!.

En lugar de top podemos usar inset-block-start, en lugar de left podemos usar inset-inline-start (ya saben cómo sigue). Ejemplo en CodePen:

See the Pen Logical position absolute by Ariel Juod (@arieljuod) on CodePen.

Conclusión

Este fue sólo una muestra de todas las propiedades y valores lógicos de CSS. Hay muchos más y funcionan de forma similar:

Mi objetivo es mostrar que podemos usar las propiedades lógicas para hacernos la vida más fácil. Incluso si no sabemos si la aplicación va a soportar lenguajes que no sean LTR, si escribimos nuestro CSS usando propiedades lógicas (donde tenga sentido), ya vamos a tener la mayor parte del trabajo listo, y sólo necesitaríamos definir la dirección y el modo de escritura.

Una última cosa (ya se está haciendo muy largo): se puede usar un linter de CSS para detectar cuando una propiedad o valor lógico se podría usar. Este plugin de Stylelint es un buen ejemplo.

Qué sigue?

El próximo artículo de esta serie probablemente sea el último relacionado a i18n por un tiempo, y voy a enfocarlo en mostrar algunos problemas raros que tuvimos que lidiar en Heroic y otros proyectos en los que trabajé en el pasado.