How to Easily Align Dates and Titles in HTML Lists with CSS
When building a blog index, archive page, or list of articles, you often want to display the publication date alongside the article title. However, by default, inline elements cause the post titles to shift and stagger horizontally depending on the length of the date string or the character widths.
In this guide, we will explore the best modern CSS techniques to align all dates and titles into a clean, professional, two-column layout.
Why Do Dates and Titles Get Misaligned?
By default, elements like <time> and <a> are rendered as inline elements. This means their width is determined strictly by the text inside them. Even if your dates follow the same format (e.g., YYYY-MM-DD), proportional fonts render numbers like '1' narrower than '8', causing subtle horizontal shifts.
Let's fix this using modern CSS layout techniques: Flexbox and CSS Grid.
Method 1: Flexbox with a Fixed-Width Time Element (Most Popular)
Using Flexbox on the list items (<li>) gives you full control over spacing and alignment. By defining a fixed width or flex basis on the <time> element, every post title will start at the exact same horizontal position.
ul.post-list {\n list-style: none;\n padding: 0;\n margin: 0;\n}\n\nul.post-list li {\n display: flex;\n align-items: baseline;\n gap: 1rem; /* Adjust space between date and title */\n margin-bottom: 0.5rem;\n}\n\nul.post-list time {\n flex: 0 0 120px; /* Fixed width: doesn't grow, doesn't shrink, stays 120px */\n color: #666;\n}HTML Structure:
<ul class="post-list">\n <li>\n <time datetime="2024-01-01">Jan 1, 2024</time>\n <a href="/post-a">Getting Started with Modern CSS</a>\n </li>\n <li>\n <time datetime="2024-11-28">Nov 28, 2024</time>\n <a href="/post-b">Building Responsive Layouts</a>\n </li>\n</ul>Method 2: CSS Grid with `display: contents` (Fully Responsive Column Width)
If you don't want to hardcode a width in pixels or rems, you can turn the entire <ul> into a two-column grid. By applying display: contents to the <li> elements, the <time> and <a> tags become direct children of the grid container.
ul.post-grid {\n display: grid;\n grid-template-columns: max-content 1fr;\n gap: 0.5rem 1.5rem;\n list-style: none;\n padding: 0;\n}\n\nul.post-grid li {\n display: contents;\n}\n\nul.post-grid time {\n color: #666;\n white-space: nowrap;\n}Why this works: The max-content column automatically sizes itself to the widest date in your entire list, ensuring that all post titles line up without manual guessing.
Bonus Tip: Use Tabular Numbers
Even if you use dates with equal character counts (like 2024-01-01), proportional fonts make some numbers narrower than others. To ensure numbers share identical widths, enable monospaced numbers using the CSS property font-variant-numeric:
time {\n font-variant-numeric: tabular-nums;\n}Conclusion
For most use cases, Flexbox (Method 1) is the simplest and most predictable solution. If your date formats vary heavily in length (e.g., mixing "May 2" with "September 28"), the CSS Grid (Method 2) approach ensures automatic alignment without needing fixed pixel widths.