Sep 29, 2024

Align Dates in Tabular Data

Have you ever had the issue when working with tabular data that the dates aren’t aligned across the entire column? This can create visual inconsistency, making it harder to read and compare values quickly.

When Does This Happen?

The misalignment often occurs when the characters in a column have different widths, making the data appear jagged. It is interesting to note that this problem only occurs with non-monospace fonts.

Monospace fonts have uniform character widths, meaning every character, whether it’s a “1” or an “8,” occupies the same amount of space. This uniformity ensures that numbers line up perfectly.

In contrast, many sans-serif or serif fonts, such as Arial or Times New Roman have proportional character widths, where each character has a different width depending on its shape. This can cause numbers to appear misaligned.

Figure 1: Using the Inter font by Google, we can reproduce the visual disharmony in the “Creation Date” column.
Figure 1: Using the Inter font by Google, we can reproduce the visual disharmony in the “Creation Date” column.

Another font that illustrates this issue is Google’s Inter font.

When applied to tabular data, you might notice that the digits in the “Creation Date” column do not align consistently, causing visual disharmony.

Why Is This Important?

In data visualization, readability is key. Misaligned numbers make it harder to scan through the data efficiently, especially in larger datasets, leading to a frustrating user experience.

A clean, well-aligned layout not only enhances readability but also improves the overall aesthetics of your tables.

It helps users quickly interpret and interact with the data, making your tables more effective and user-friendly.

How to Improve Readability: A Two-Step Solution

To ensure that your dates are aligned and readable, there are two main things we need to address:

1. Ensure Consistent Date Characters

First, all dates should have the same number of characters.

By formatting the date in DD.MM.YYYY, HH:MM:SS, you ensure that days and months with single digits (i.e., less than 10) are padded with a leading zero (e.g., "01", "02").

This way, every entry in your date column will maintain a consistent length.

For example:

  • “1/9/2024” becomes “01.09.2024”
  • “9/10/2024” remains “09.10.2024”

By having consistent character lengths, the dates become more predictable, and each entry starts and ends at the same positions, improving readability.

Figure 2: A consistent date format already improves the readability, but it is still not perfect yet.
Figure 2: A consistent date format already improves the readability, but it is still not perfect yet.

2. Align the Spacing of the Digits

The second issue is ensuring that all digits in the dates have uniform spacing. This can be challenging because fonts typically use proportional spacing, but we can address this with a CSS property called font-variant-numeric.

Figure 3: Applying the CSS font-variant-numeric style ensures consistent widths for each of the digits.
Figure 3: Applying the CSS font-variant-numeric style ensures consistent widths for each of the digits.

Implementing the Solution

First, let’s build the basic HTML structure for our table:

html
<table>
  <thead>
      <tr>
          <th>Name</th>
          <th>Role</th>
          <th>Creation Date</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>John Doe</td>
          <td>Administrator</td>
          <td class="date"></td>
      </tr>
      <tr>
          <td>Jane Smith</td>
          <td>Editor</td>
          <td class="date"></td>
      </tr>
      <tr>
          <td>Michael Brown</td>
          <td>Viewer</td>
          <td class="date"></td>
      </tr>
  </tbody>
</table>

Next, we’ll use JavaScript to populate the dates dynamically in a consistent DD.MM.YYYY, HH:MM:SS format.

js
// Use your preferred locale, using German locale
const locale = 'de-DE'

// Get all cells with the 'date' class
const dateCells = document.querySelectorAll('.date');

// Get the current date
const today = new Date();

// Format the date to 'DD.MM.YYYY'
const formattedDate = today.toLocaleDateString(locale, {
  year: 'numeric',
  month: '2-digit',
  day: '2-digit'
});

// Format the time to 'HH:MM:SS'
const formattedTime = today.toLocaleTimeString(locale, {
  hour: '2-digit',
  minute: '2-digit',
  second: '2-digit'
});

// Set the cell text to the formatted date and time
dateCells.forEach(cell => {
  cell.textContent = formattedDate + ',' + formattedTime;
});

By using toLocaleDateString() and toLocaleTimeString() with the de-DE locale (German format), we ensure the date and time strings are formatted correctly with leading zeros.

To ensure that the digits in our dates align perfectly, we’ll use the font-variant-numeric property with the tabular-nums value.

This value ensures that each digit occupies the same amount of space, similar to how a monospace font would behave, and it is widely supported in modern browsers (see MDN Web Docs).

Additionally, we reduce the letter spacing to improve the visual balance.

css
.date {
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.045rem;
}