WRITING
Mastering Modern CSS Typography and Layout
A deep dive into building beautiful, accessible, and responsive typography using modern CSS techniques, custom properties, and semantic HTML.
Building a great website starts with great typography. While it is tempting to jump straight into complex layouts and animations, the foundation of any good user experience is how readable and accessible your text is. In this post, we will explore how to leverage modern CSS to create a beautiful, resilient typographic system.
For more resources on this topic, check out the MDN Web Docs on CSS Text.
The Foundation of Semantic HTML
Before we write a single line of CSS, we need to ensure our HTML is semantic. Screen readers and search engines rely on proper heading hierarchies to understand the structure of your content.
The Power of Headings
Headings should not just be styled differently; they should represent the actual outline of your document. When you use
an <h2>, it signifies a major section. An <h3> signifies a subsection.
Accessibility and Scroll Margins
One of the most overlooked aspects of heading design is how they interact with fixed navigation bars. If a user
clicks a link that jumps to an <h2>, a fixed header might cover it up. By using scroll-margin-top, we can
ensure headings always land perfectly in the viewport. Try hovering over the headings in this post to see
the subtle underline effect!
Structuring Content with Lists
Lists are essential for breaking down complex information into digestible pieces. Let us look at how we can style them effectively.
Unordered Lists
When the order of items does not matter, we use unordered lists. Here are some key principles of good typography:
- Line Height: Ensure there is enough vertical space between lines of text.
- Measure: Keep line lengths between 45 and 75 characters for optimal readability.
- Contrast: Make sure your text color has sufficient contrast against the background.
- This is a nested list item.
- It helps to break down complex points further.
- And we can go even deeper if needed.
Ordered Lists
When the sequence is important, ordered lists guide the reader step-by-step.
- Define your design tokens (colors, spacing, typography).
- Set up your base HTML reset and global styles.
- Build your component library using scoped CSS.
- Test across multiple devices and screen readers.
Highlighting Key Concepts
Sometimes you need to draw attention to a specific thought or quote from an expert. Blockquotes are perfect for this.
“Design is not just what it looks like and feels like. Design is how it works.”
— Steve Jobs
Blockquotes should be visually distinct from the main body text, usually achieved through a border, background color, or indentation, without sacrificing readability.
Showcasing Code
For technical blogs, code blocks need to be pristine. Inline code should be subtle but noticeable, like the
font-family property, while block code needs to be highly readable and scrollable on mobile.
Here is an example of how we define our base typography tokens in CSS:
:root {
--font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
--font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
--text-base: 1rem;
--text-lg: 1.125rem;
--text-xl: 1.25rem;
--leading-relaxed: 1.6;
}
body {
font-family: var(--font-sans);
line-height: var(--leading-relaxed);
}
Notice how the code block has a subtle border and rounded corners, making it feel like a distinct component on the page.
Comparing Data with Tables
Tables are often neglected in modern web design, but they are crucial for displaying structured data. Let us compare some common CSS length units:
| Unit | Name | Relative To | Best Used For |
|---|---|---|---|
px |
Pixels | Absolute | Borders, shadows, fine details |
rem |
Root EM | Root font size | Typography, global spacing |
em |
EM | Parent font size | Component-level spacing, padding |
vw |
Viewport Width | Viewport width | Hero sections, fluid typography |
% |
Percentage | Parent element | Layout widths, fluid grids |
Integrating Rich Media
Text is great, but breaking it up with images, videos, and embeds keeps the reader engaged.
Standard Images
Here is a standard image. Notice how it takes up the full width of the reading column and has a subtle border to frame it.
Figures and Captions
When an image needs context, wrapping it in a figure with a figcaption is the semantic approach.
Figure 1: Clean code is a reflection of a clear mind. Notice the spacing and alignment.
Embedded Media
Videos and iframes should behave just like images—fluid and responsive.
Handling Edge Cases
Finally, a robust typographic system must handle edge cases gracefully. What happens when a user pastes a massively long URL or a string of text without spaces?
Instead of breaking the layout or causing horizontal scrollbars, we use overflow-wrap: anywhere to ensure
the text breaks cleanly to the next line. Let us test it with this ridiculously long, unbroken string of
characters:
SupercalifragilisticexpialidociousIsAVeryLongWordButSometimesURLsAreEvenLongerLikeHttps://www.example.com/some/very/long/path/that/keeps/going/and/going/without/any/spaces/whatsoever/and/just/keeps/on/going/forever.
Conclusion
Building a great typographic system takes time, but it pays off immensely. By focusing on semantic HTML,
leveraging modern CSS features like custom properties and scroll-margin, and handling edge cases, you
create a reading experience that is accessible, beautiful, and resilient.
Happy coding, and keep writing!