La Forma Más Fácil Para Crear Texto Vertical con CSS
Spanish (Español) translation by Eva Collados Pascual (you can also view the original English article)
Esta mañana, necesitaba crear texto vertical para un proyecto en el que estoy trabajando. Después de probar un par ideas, me dirigí a Twitter para consultar y solicitar a nuestros seguidores opiniones respecto al tema. ¡Obtuvimos un montón de excelentes respuestas e ideas que hoy vamos a revisar!
¡Suscríbete a nuestro canal de YouTube para ver todos los video tutoriales!
¿Prefieres ver este vídeo en Screenr?
Método 1: Etiquetas <br>
En principio, una posible forma (aunque no recomendable) de conseguir un texto vertical consiste en añadir una etiqueta <br> tras cada letra.
1 |
|
2 |
<h1>
|
3 |
N <br />E <br />T <br />T <br />U <br />T <br />S |
4 |
</h1>
|
Ver Muestra
No utilices este método. Es poco fiable y descuidado.
Método 2: Crear un Contenedor Estático
Con este método, envolvemos cada letra entre etiquetas span y luego configuramos su atributo display a block mediante CSS.
1 |
|
2 |
<!DOCTYPE html>
|
3 |
<html>
|
4 |
<head>
|
5 |
<meta charset=utf-8 /> |
6 |
<title>Vertical Text</title> |
7 |
|
8 |
<style>
|
9 |
h1 span { display: block; } |
10 |
</style>
|
11 |
</head>
|
12 |
<body>
|
13 |
|
14 |
<h1>
|
15 |
<span> N </span> |
16 |
<span> E </span> |
17 |
<span> T </span> |
18 |
<span> T </span> |
19 |
<span> U </span> |
20 |
<span> T </span> |
21 |
<span> S </span> |
22 |
</h1>
|
23 |
|
24 |
</body>
|
25 |
</html>
|
Ver Muestra
El problema con esta solución, además del aterrador código de su estructura, es que es un proceso manual. Si el texto se generase dinámicamente desde un CMS, no podrías emplearlo. No uses este método.
Método 3: Utilizar JavaScript
Mi instinto inicial fue añadir dinámicamente las etiquetas span con JavaScript. De esta forma, sorteamos los inconvenientes mencionados en el segundo método.
1 |
|
2 |
<!DOCTYPE html>
|
3 |
<html>
|
4 |
<head>
|
5 |
<meta charset=utf-8 /> |
6 |
<title>JS Bin</title> |
7 |
|
8 |
<style>
|
9 |
h1 span { display: block; } |
10 |
</style>
|
11 |
</head>
|
12 |
<body>
|
13 |
<h1> NETTUTS </h1> |
14 |
|
15 |
<script>
|
16 |
var h1 = document.getElementsByTagName('h1')[0]; |
17 |
h1.innerHTML = '<span>' + h1.innerHTML.split('').join('</span><span>') + '</span>'; |
18 |
</script>
|
19 |
</body>
|
20 |
</html>
|
Ver Muestra
Este método definitivamente incorpora mejoras. Arriba, hemos split (dividido) el texto en una cadena y luego hemos envuelto cada letra dentro de un elemento span. Aunque podríamos usar algo como una declaración for, o $.map para filtrar la cadena, una forma mucho mejor y más rápida que reunir y envolver el texto cada vez manualmente.
Pero aun siendo mejor, esta solución no es recomendable.
- ¿Rompería nuestro diseño si JavaScript estuviese deshabilitado?
- Con preferencia y de ser posible, deberíamos estar usando CSS para lograr esto.
Método 4: Aplicar Width al Elemento Contenedor
Evitemos el empleo de JavaScript siempre que sea posible. ¿Qué pasaría si aplicásemos una anchura determinada al elemento contenedor y forzásemos que el texto estuviese siempre contenido en él? Podría funcionar.
1 |
|
2 |
<!DOCTYPE html>
|
3 |
<html>
|
4 |
<head>
|
5 |
<meta charset=utf-8 /> |
6 |
<title>JS Bin</title> |
7 |
|
8 |
<style>
|
9 |
h1 { |
10 |
width: 50px; |
11 |
font-size: 50px; |
12 |
word-wrap: break-word; |
13 |
}
|
14 |
</style>
|
15 |
</head>
|
16 |
<body>
|
17 |
<h1> NETTUTS </h1> |
18 |
</body>
|
19 |
</html>
|
Ver Muestra
En este escenario, aplicamos una breve anchura a la etiqueta h1, y después hacemos que su font-size sea igual al valor exacto de la anchura. Por último, estableciendo un word-wrap con valor break-word, forzando a cada letra a ocupar su propia línea. El problema es que aun siendo word-wrap: break-word parte de la especificación CSS3, no todos los navegadores la aceptan.
Excluyendo a los navegadores más antiguos, esto aparentemente soluciona nuestro problema... aunque no del todo. La muestra de arriba parece funcionar, pero es demasiado arriesgado jugar con valores expresaos en píxeles. Vamos a intentar algo tan simple como convertir las letras mayúsculas en minúsculas.
¡Uy!; con este método, tenemos que ser muy cuidadosos en lo que respecta a los valores que especifiquemos. No es recomendable.
Método 5: Aplicar letter-spacing
Como medida de precaución y para ampliar el cuarto método, ¿por qué no aplicamos un letter-spacing bastante grande solucionando así este asunto?
1 |
|
2 |
<!DOCTYPE html>
|
3 |
<html>
|
4 |
<head>
|
5 |
<meta charset=utf-8 /> |
6 |
<title>JS Bin</title> |
7 |
|
8 |
<style>
|
9 |
h1 { |
10 |
width: 50px; |
11 |
font-size: 50px; |
12 |
word-wrap: break-word; |
13 |
letter-spacing: 20px; /* Set large letter-spacing as precaution */ |
14 |
}
|
15 |
</style>
|
16 |
</head>
|
17 |
<body>
|
18 |
<h1> Nettuts </h1> |
19 |
</body>
|
20 |
</html>
|
Ver Muestra
Esto parece resolver el problema, sin embargo, de nuevo, también estamos usando aquí un poco de CSS3.
Método 6: Usa medidas en ems
Por otra parte, existe una solución que se resuelve con una línea. ¿Recuerdas cuando nos enteramos de que aplicando un overflow: hidden a un elemento padre, haría que de forma milagrosa su contenido flotase? ¡Este método cosiste en ajustar las cosas de esta manera! La clave está en el uso de ems, y la colocación de un espacio entre cada letra.
1 |
|
2 |
<!DOCTYPE html>
|
3 |
<html>
|
4 |
<head>
|
5 |
<meta charset=utf-8 /> |
6 |
<title>JS Bin</title> |
7 |
|
8 |
<style>
|
9 |
h1 { |
10 |
width: 1em; |
11 |
font-size: 40px; |
12 |
letter-spacing: 40px; /* arbitrarily large letter-spacing for safety */ |
13 |
}
|
14 |
</style>
|
15 |
</head>
|
16 |
<body>
|
17 |
<h1> N e t t u t s </h1> |
18 |
</body>
|
19 |
</html>
|
Ver Muestra
Bastante sencillo, ¿no? Y de esta forma, podrás aplicar cualquier tamaño de fuente que desees. Y esto es así porque estamos usando ems -- que es el equivalente a usar x-height relativo a la fuente elegida en cada caso -- de esta forma obtenemos mucha más flexibilidad.
Pero, una vez más, en ocasiones más de una letra acabará situándose en una misma línea. Tienes que estar seguro; por este motivo hemos aplicado un amplio letter-spacing, para asegurarnos de que nunca habrá más de una letra por línea.
Según mis conocimientos hasta el momento, esta es la mejor solución, la más compatible con la mayoría de los navegadores.
Método 7: Whitespace
Una última forma de conseguir este efecto se basa en sacar provecho de la propiedad white-space.
1 |
|
2 |
<!DOCTYPE HTML>
|
3 |
<html lang="en"> |
4 |
<head>
|
5 |
<meta charset="UTF-8"> |
6 |
<title></title>
|
7 |
<style>
|
8 |
h1 { white-space: pre; } |
9 |
</style>
|
10 |
</head>
|
11 |
<body>
|
12 |
|
13 |
<h1>
|
14 |
J |
15 |
E |
16 |
F |
17 |
F |
18 |
R |
19 |
E |
20 |
Y |
21 |
</h1>
|
22 |
</body>
|
23 |
</html>
|
Ver Muestra
Aplicando el valor pre a la propiedad white-space, estamos indicando que el texto se comporte como si estuviera dentro de una etiqueta pre. Por tanto, respeta cualquier espacio que hayas añadido.
Conclusión
¿No debería existir una regla CSS3 que cumpliese esta función? ¿Y si pudiésemos indicar algo en las líneas font-display: letter-block; que estableciese que los caracteres fuesen renderizados en forma de bloques ordenados?
¿Qué opinas? ¿Conoces alguna otra alternativa que debamos considerar? Mucha gente ha sugerido el empleo de text-rotation como solución, pero es importante recordar que esto también provoca el giro del texto en 90 grados, que no es lo que pretendemos.



