Advertisement
HTML & CSS

The Easiest Way to Create Vertical Text with CSS

by

Earlier this morning, I needed to create vertical text for a project I'm working on. After trying out a couple ideas, I took to Twitter to find what sorts of thoughts our followers had on the subject. There were plenty of great responses and ideas that we'll go over today!

*Note - please refer to "Method 6" below for more details about proper usage.

Subscribe to our YouTube page to watch all of the video tutorials!
Prefer to watch this video on Screenr?


Method 1: <br> Tags

So, one possible (though not recommended) way to achieve vertical text is to add <br> tags after each letter.

<h1>
   N <br />E <br />T <br />T <br />U <br />T <br />S
</h1>
View a Demo

Don't use this method. It's lame and sloppy.


Method 2: Static Wrapping

With this method, we wrap each letter in a span, and then set its display to block within our CSS.

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Vertical Text</title>

<style>
  h1 span { display: block; }
</style>
</head>
<body>
 
  <h1>
   <span> N </span>
   <span> E </span>
   <span> T </span>
   <span> T </span>
   <span> U </span>
   <span> T </span>
   <span> S </span>
  </h1>
  
</body>
</html>
View Demo

The problem with this solution -- other than the frightening mark-up -- is that it's a manual process. If the text is generated dynamically from a CMS, you're out of luck. Don't use this method.


Method 3: Use JavaScript

My initial instinct was to dynamically add the span tags with JavaScript. That way, we get around the issues mentioned in method two.

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>

<style>
  h1 span { display: block; }
</style>
</head>
<body>
  <h1> NETTUTS </h1>
  
  <script>
    var h1 = document.getElementsByTagName('h1')[0];
    h1.innerHTML = '<span>' + h1.innerHTML.split('').join('</span><span>') + '</span>';
  </script>
</body>
</html>
View Demo

This method is definitely an improvement. Above, we split the text into an array, and then wrap each letter in a span. While we could use something like a for statement, or $.map to filter through the array, a far better and quicker solution is to manually join and wrap the text at the same time.

Though better, this solution isn't recommended.

  • Will this break your layout if JavaScript is disabled?
  • Ideally, we should be using CSS for this task, if possible.

Method 4: Apply a Width to the Container

Let's get away from JavaScript if we can. What if we applied a width to the container element, and forced the text to wrap? That could work.

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>

<style>
  h1 {
    width: 50px;
    font-size: 50px;
    word-wrap: break-word;
  }
</style>
</head>
<body>
  <h1> NETTUTS </h1>
</body>
</html>
View Demo

In this scenario, we apply a very narrow width to the h1 tag, and then make its font-size equal to that exact value. Finally, by setting word-wrap equal to break-word, we can force each letter onto its own line. However, word-wrap: break-word is part of the CSS3 specification, and is not compliant across all browsers.

Excluding older browsers, this seemingly solves our problem...but not entirely. The demo above does appear to work, but it's too risky to play with pixel values. Let's try something as simple as turning the uppercase letters into lowercase.

Broken Again

Yikes; with this method, we have to be very careful when it comes to the specific values we set. Not recommended.


Method 5: Apply letter-spacing

As a precaution, and to extend method four, why don't we apply fairly large letter-spacing to get around this issue?

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>

<style>
  h1 {
    width: 50px;
    font-size: 50px;
    word-wrap: break-word;
    letter-spacing: 20px; /* Set large letter-spacing as precaution */
  }
</style>
</head>
<body>
  <h1> Nettuts </h1>
</body>
</html>
View Demo

That seems to fix the issue, though, again, we're using a bit of CSS3 here.


Method 6: Use ems

Alternatively, there's a one-liner solution. Remember when we learned that applying overflow: hidden to a parent element would miraculously make it contain its floats? This method is sort of like that! The key is to use ems, and place a space between each letter.

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>

<style>
  h1 {
    width: 1em;
    font-size: 40px;
    letter-spacing: 40px; /* arbitrarily large letter-spacing for safety */
  }
</style>
</head>
<body>
  <h1> N e t t u t s </h1>
</body>
</html>
View Demo

Pretty neat, right? And, this way, you can apply any font size that you wish. Because we're using ems -- which is equal to the x-height of the chosen font -- we're then provided with a lot more flexibility.

But, once again, sometimes more than one letter will end up on a line. You have to be safe; that's why I've applied arbitrarily large letter-spacing to ensure that there's never more than one letter on a line.

To my knowledge at this time, this is the best, most cross-browser compliant solution.


Method 7 : Whitespace

One last way to achieve this effect is to take advantage of the white-space property.

<!DOCTYPE HTML>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title></title>
      <style>
         h1 { white-space: pre; }
      </style>
   </head>
   <body>

      <h1>
         J 
         E 
         F 
         F 
         R 
         E 
         Y
      </h1>
   </body>
</html>
View Demo

By setting white-space to pre, that instructs the text to behave as if it was within a pre tag. As such, it honors any spacing that you've added.


Conclusion

Shouldn't there be a CSS3 rule to accomplish this task? What if I could set something along the lines of: font-display: letter-block; which would instruct each letter to be rendered as a block of sorts?

What do you think? Do you have any other alternatives that we should consider? Many people suggested using text-rotation to accomplish the task, but it's important to remember that this also rotates the text ninety degrees as well, which is not what we're trying to achieve.

Related Posts
  • Code
    HTML5
    HTML5: Vibration APIPdl54 preview image@2x
    HTML5 has been a breath of fresh air for the web, which hasn't only affected the web as we know it. HTML5 provides a number of APIs that enable developers to create interactive websites and improve the user experience on mobile devices. In this article, we'll take a closer look at the Vibration API.Read More…
  • Web Design
    Complete Websites
    Building the Responsive Timeline Portfolio PagePortfolio thumb
    During this tutorial we will be building the fantastic Timeline Portfolio as seen in an earlier tutorial by Tomas Laurinavicius. We will be using some responsive techniques as well as CSS3 animations, Sass and a little bit of jQuery.Read More…
  • Code
    HTML5
    HTML5: Battery Status APIPdl54 preview image@2x
    The number of people browsing the web using mobile devices grows every day. It's therefore important to optimize websites and web applications to accommodate mobile visitors. The W3C (World Wide Web Consortium) is well aware of this trend and has introduced a number of APIs that help with this challenge. In this article, I will introduce you to one of these APIs, the Battery Status API.Read More…
  • Code
    PHP
    Validation and Exception Handling: From the UI to the BackendProcedural to oop php retina preview
    Sooner or later in your programming career you will be faced with the dilemma of validation and exception handling. This was the case with me and my team also. A couple or so years ago we reached a point when we had to take architectural actions to accommodate all the exceptional cases our quite large software project needed to handle. Below is a list of practices we came to value and apply when it comes to validation and exception handling.Read More…
  • Web Design
    UX
    Walk Users Through Your Website With Bootstrap TourTour retina
    When you have a web application which requires some getting used to from your users, a walkthrough of the interface is in order. Creating a walkthrough directly on top of the interface makes things very clear, so that's what we're going to build, using Bootstrap Tour.Read More…
  • Web Design
    HTML/CSS
    Building the Merry Christmas Web App InterfaceXmas build 2 retina
    Today we're going to build the Merry Christmas Web App Interface; a Photoshop layout from an earlier tutorial by Tomas Laurinavicius.Read More…