Cómo agregar soporte RTL a Flexbox y CSS Grid
() translation by (you can also view the original English article)
Las propiedades lógicas definen un nuevo enfoque que cambia la forma en que trabajamos con diseños en CSS. Entre muchas otras ventajas, nos permiten agregar soporte de lenguaje RTL (de derecha a izquierda) a los diseños basados en propiedades lógicas: flexbox y CSS Grid.
En este tutorial, utilizaremos dos demostraciones de Tuts+ de tutoriales anteriores, convirtiéndolas para ver qué tan fácil es realmente agregar soporte RTL a diseños lógicos:
- CSSCómo construir un diseño de un sitio web de noticias con FlexboxJeremy Thomas
- Diseño de cuadrícula CSSCrea un diseño de cuadrícula rota con CSS GridIan Yates
Pero primero veamos brevemente cómo funcionan las propiedades lógicas en CSS.
1. Diseños lógicos y dirección de contenido
El objetivo principal de las propiedades lógicas de CSS es permitir a los desarrolladores cambiar fácilmente los diseños cuando cambia la propiedad writing-mode
o direction
. Supongamos que tienes un sitio web LTR (de izquierda a derecha) y deseas traducirlo a un script RTL como los que se usan con árabe o hebreo. Si has utilizado las propiedades lógicas en tu CSS de manera consistente, solo necesitas agregar la regla direction: rtl;
a la página y el diseño cambiará automáticamente.
Las propiedades lógicas utilizan direcciones lógicas en lugar de físicas para definir diseños. Por ejemplo, la palabra clave start
equivale a left
en scripts de tipo LTR como el latín, y del mismo modo equivale a right
en RTL. Del mismo modo, end
equivale a right
en LTR y a left
en RTL. Es por eso que es fácil agregar soporte RTL a diseños basados en dimensiones lógicas.
Las propiedades lógicas de CSS tienen tres casos de uso principales:
- flexbox (ejemplo
flex-start
,flex-end
) - CSS Grid (ejemplo
grid-row-start
,grid-row-end
,grid-column-start
,grid-column-end
) - equivalentes lógicos de propiedades de uso frecuente como
margin
,padding
,border
,text-align
, y otros.
Si deseas ver ejemplos de código de los casos de uso anteriores, consulta mi artículo reciente sobre las propiedades lógicas de CSS.
Ahora, veamos cómo podemos aprovechar las propiedades lógicas para agregar soporte RTL a flexbox y CSS grid.
2. Cómo agregar soporte RTL a Flexbox
El siguiente ejemplo usa flexbox para crear un diseño de un sitio web de noticias (aquí está el tutorial completo). Tiene un encabezado centrado e incluye un par de tarjetas de diferentes tamaños. La demo utiliza dos media queries: a 800px
y 1000px
. La disposición de las tarjetas dependerá del tamaño de ventana que veas en la demostración:
Para crear una versión RTL del CSS, tenemos que agregar solo una regla:
1 |
* { |
2 |
direction: rtl; |
3 |
}
|
Y, como puedes ver a continuación, la demostración se ha volteado perfectamente, no solo el texto, sino también el diseño, en cada tamaño de ventana gráfica:
¿Por qué fue tan fácil de hacer?
Cuando se usan direcciones físicas en diseños CSS, a menudo pueden estropear tus esfuerzos de RTL. Pero si miras el CSS a continuación, verás que no se usan instrucciones físicas, por lo que fue tan fácil voltear el diseño (las reglas de decoración de texto como las fuentes y los colores se han eliminado del código para facilitar la lectura) :
1 |
.header { |
2 |
padding: 40px 0 20px; |
3 |
text-align: center; |
4 |
}
|
5 |
|
6 |
.header h2 a { |
7 |
border-bottom: 1px solid rgba(255, 255, 255, 0.5); |
8 |
}
|
9 |
|
10 |
.main { |
11 |
margin: 0 auto; |
12 |
max-width: 1040px; |
13 |
padding: 10px; |
14 |
}
|
15 |
|
16 |
.column { |
17 |
flex: 1; |
18 |
flex-direction: column; |
19 |
}
|
20 |
|
21 |
.article { |
22 |
display: flex; |
23 |
flex: 1; |
24 |
flex-direction: column; |
25 |
flex-basis: auto; |
26 |
margin: 10px; |
27 |
}
|
28 |
|
29 |
.article-image { |
30 |
display: block; |
31 |
padding-top: 75%; |
32 |
position: relative; |
33 |
width: 100%; |
34 |
}
|
35 |
|
36 |
.article-image img { |
37 |
display: block; |
38 |
height: 100%; |
39 |
left: 0; |
40 |
position: absolute; |
41 |
top: 0; |
42 |
width: 100%; |
43 |
}
|
44 |
|
45 |
.article-image.is-3by2 { |
46 |
padding-top: 66.6666%; |
47 |
}
|
48 |
|
49 |
.article-image.is-16by9 { |
50 |
padding-top: 56.25%; |
51 |
}
|
52 |
|
53 |
.article-body { |
54 |
display: flex; |
55 |
flex: 1; |
56 |
flex-direction: column; |
57 |
padding: 20px; |
58 |
}
|
59 |
|
60 |
.article-title { |
61 |
flex-shrink: 0; |
62 |
}
|
63 |
|
64 |
.article-content { |
65 |
flex: 1; |
66 |
margin-top: 5px; |
67 |
}
|
68 |
|
69 |
.article-info { |
70 |
display: flex; |
71 |
justify-content: space-between; |
72 |
margin-top: 10px; |
73 |
}
|
74 |
|
75 |
@media screen and (min-width: 800px) { |
76 |
.columns, |
77 |
.column { |
78 |
display: flex; |
79 |
}
|
80 |
}
|
81 |
|
82 |
@media screen and (min-width: 1000px) { |
83 |
.first-article { |
84 |
flex-direction: row; |
85 |
}
|
86 |
|
87 |
.first-article .article-body { |
88 |
flex: 1; |
89 |
}
|
90 |
|
91 |
.first-article .article-image { |
92 |
height: 300px; |
93 |
order: 2; |
94 |
padding-top: 0; |
95 |
width: 400px; |
96 |
}
|
97 |
|
98 |
.main-column { |
99 |
flex: 3; |
100 |
}
|
101 |
|
102 |
.nested-column { |
103 |
flex: 2; |
104 |
}
|
105 |
}
|
Flexbox se encarga de todo el diseño, y las propiedades de flexbox son propiedades lógicas. Las propiedades de tamaño y alineación, como border
, margin
, padding
, y width
, pueden causar problemas en ciertos casos, ya que dependen de direcciones físicas en lugar de lógicas. Por ejemplo, la demostración utiliza la propiedad antigua de padding-top
en lugar del nuevo padding-block-start
, su equivalente lógico.
Sin embargo, como queremos realizar una conversión de LTR a RTL, solo necesitamos voltear el eje horizontal (izquierda-derecha) pero no el vertical (arriba-abajo). El código anterior solo contiene propiedades que definen direcciones verticales como padding-top
y border-bottom
. Estos permanecen igual en ambos diseños.
Como no hay ninguna propiedad en el código que defina direcciones horizontales (por ejemplo, el relleno a la izquierda mediante padding-left
sería una propiedad de este tipo), no tenemos que ajustarlas para que se ajusten a los scripts RTL.
3. Cómo agregar soporte RTL a CSS Grid
Ahora, veamos la demostración con CSS Grid. Define un diseño asimétrico construido sobre la cuadrícula CSS (aquí está el tutorial completo):
Agreguemos la misma regla direction
al CSS y veamos cómo modifica el diseño original:
1 |
* { |
2 |
direction: rtl; |
3 |
}
|
Así es como se volcó la demostración:
Aunque la mayoría de los elementos se voltearon como se esperaba, falta algo. Si comparas las dos demostraciones cuidadosamente, puedes ver que la insignia de la corona entre las imágenes y el titular de "Gibraltar" ha desaparecido.



Entonces, ¿dónde está la corona?
El CSS nos da la respuesta de por qué falta la corona. Todavía está allí, pero oculto en el fondo. Aquí está el código CSS de la demostración (sin color, fuente y otras reglas de decoración de texto):
1 |
blockquote { |
2 |
margin: 0 0 2em 0; |
3 |
}
|
4 |
|
5 |
.cta { |
6 |
padding: 100px 0 100px 20%; |
7 |
}
|
8 |
|
9 |
.cta h1 { |
10 |
margin: 0 0 20px 0; |
11 |
position: relative; |
12 |
}
|
13 |
|
14 |
.button { |
15 |
display: inline-block; |
16 |
padding: .8em 1.5em; |
17 |
}
|
18 |
|
19 |
.strapline { |
20 |
margin-top: 100px; |
21 |
position: relative; |
22 |
}
|
23 |
|
24 |
.strapline::before { |
25 |
content: ''; |
26 |
display: block; |
27 |
background: url(wavy.svg) repeat-x; |
28 |
background-size: cover; |
29 |
width: 20%; |
30 |
height: .5em; |
31 |
position: absolute; |
32 |
top: -3em; |
33 |
left: 40%; |
34 |
}
|
35 |
|
36 |
.cta h1::before { |
37 |
content: ''; |
38 |
display: block; |
39 |
height: 1em; |
40 |
width: 1em; |
41 |
background: url(badge.svg) no-repeat center center; |
42 |
background-size: 80%; |
43 |
position: absolute; |
44 |
left: -120px; |
45 |
top: 0; |
46 |
}
|
47 |
|
48 |
/* Grid layout */
|
49 |
.grid1 { |
50 |
display: grid; |
51 |
grid-template-columns: 3fr 6fr 1fr 5fr 10fr 2fr; |
52 |
grid-template-rows: 100px auto 15px auto auto; |
53 |
}
|
54 |
|
55 |
.img1 { |
56 |
background: url(wooden.jpg); |
57 |
background-size: cover; |
58 |
|
59 |
grid-column: 1 / span 2; |
60 |
grid-row: 2 / span 3; |
61 |
}
|
62 |
|
63 |
.img2 { |
64 |
background: url(speaker.jpg); |
65 |
background-size: cover; |
66 |
|
67 |
grid-column: 2 / span 2; |
68 |
grid-row: 3 / span 3; |
69 |
}
|
70 |
|
71 |
.img3 { |
72 |
background: url(waves.jpg); |
73 |
background-size: cover; |
74 |
|
75 |
grid-column: 5 / span 2; |
76 |
grid-row: 4 / span 2; |
77 |
}
|
78 |
|
79 |
.strapline { |
80 |
grid-column: 3 / span 3; |
81 |
grid-row: 2 / span 1; |
82 |
|
83 |
padding: 0 16%; |
84 |
text-align: center; |
85 |
margin: 0; |
86 |
}
|
87 |
|
88 |
.cta-wrapper { |
89 |
grid-column: 4 / span 2; |
90 |
grid-row: 4 / span 2; |
91 |
}
|
El código anterior utiliza numerosas propiedades de cuadrícula CSS como grid-row
, grid-column
, grid-template-rows
y grid-template-columns
. Sin embargo, como la cuadrícula CSS se basa en dimensiones lógicas en lugar de físicas, las propiedades relacionadas con la cuadrícula no pueden ser el problema.
El problema surge de otras propiedades que posicionan físicamente los elementos en la dimensión horizontal (izquierda-derecha):
1 |
.cta { |
2 |
padding: 100px 0 100px 20%; |
3 |
}
|
4 |
.strapline::before { |
5 |
left: 40%; |
6 |
}
|
7 |
.cta h1::before { |
8 |
left: -120px; |
9 |
}
|
Para admitir scripts RTL, necesitamos invertir a left
y right
de la siguiente manera:
1 |
.cta { |
2 |
padding: 100px 20% 100px 0; |
3 |
}
|
4 |
.strapline::before { |
5 |
right: 40%; |
6 |
}
|
7 |
.cta h1::before { |
8 |
right: -120px; |
9 |
}
|
Si echas un vistazo a la demostración RTL modificada, puedes ver que la corona ha reaparecido y ahora todo está perfectamente alineado:
Probablemente hayas notado que en el CSS modificado, hemos utilizado la propiedad lógica right
en lugar de la correspondiente. Esto se debe a que las propiedades lógicas aún no están listas para la producción, ya que el soporte del navegador todavía es algo irregular.
Sin embargo, así es como se debería ver el CSS modificado utilizando el equivalente lógico de la propiedad right
:
1 |
.cta { |
2 |
padding: 100px 20% 100px 0; |
3 |
}
|
4 |
.strapline::before { |
5 |
inset-inline-start: 40%; |
6 |
}
|
7 |
.cta h1::before { |
8 |
inset-inline-start: -120px; |
9 |
}
|
El equivalente de right
es inset-inline-start
en los scripts RTL, ya que ese es el comienzo del eje en línea. Sin embargo, en las secuencias de comandos LTR, inset-inline-start
equivale a left
, como en ese caso, las filas comienzan a la izquierda de la pantalla.
Por lo tanto, si la demostración original usara la propiedad lógica inset-inline-start
en lugar de la dirección física left
, podríamos haber convertido el diseño de LTR a RTL sin tener que ajustar ninguna regla.
A continuación, puedes ver la misma demo RTL utilizando propiedades lógicas. También he cambiado top
a inset-block-start
solo por razones de coherencia.
Conclusión
Las propiedades lógicas de CSS nos permiten admitir scripts de derecha a izquierda más fácilmente que nunca. Podemos agregar rápidamente soporte RTL a páginas basadas en cuadrícula flexbox y CSS, ya que son diseños lógicos que no dependen de direcciones físicas como izquierda, derecha, arriba y abajo.
Además de los lenguajes RTL, también podemos usar propiedades lógicas para convertir los modos de escritura de arriba a abajo en scripts de lenguaje vertical como el japonés. ¡Mira mi tutorial anterior para más detalles!
Ponte al día con el diseño CSS
- Diseño de cuadrícula CSSDiseño de cuadrícula CSS: Una guía de inicio rápidoIan Yates
- Diseño de cuadrícula CSSDiseño de cuadrícula CSS: columnas fluidas y mejores canalesIan Yates
- Diseño de cuadrícula CSSFlexbox vs. CSS Grid: ¿Cuál deberías usar y cuándo?Anna Monus
- FlexboxUna guía completa para la alineación de FlexboxAnna Monus