Complete CSS Course Module 17: Advanced: Professional CSS: Architecture, Performance and Debugging

CSS Performance and Accessibility Best Practices

  • Beginner
  • Lesson 17.2
  • 5 min read
  • 75 of 77 in the course

In short

CSS performance and accessibility best practices help your pages load fast and work for everyone: critical CSS, font-display, focus styles, contrast and rem units. How to make CSS load faster CSS is render-blocking.

CSS performance and accessibility best practices help your pages load fast and work for everyone: critical CSS, font-display, focus styles, contrast and rem units.

How to make CSS load faster

CSS is render-blocking. The browser waits until it has downloaded your CSS before it shows the page, so users do not see unstyled content. That is good, but it means a large or slow CSS file delays everything.

Critical CSS is the small set of styles needed for the part of the page people see first (the header and hero). The idea is to put that small part directly in a <style> tag in the <head>, and load the rest normally. The first screen can appear right away.

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>CodeCraft Bakery</title>
  <style>
    /* Critical CSS: only what the first screen needs */
    body { margin: 0; font-family: system-ui, sans-serif; }
    .site-header { display: flex; justify-content: space-between; padding: 1rem; }
    .hero { min-height: 60vh; display: grid; place-items: center; }
  </style>
  <link rel="stylesheet" href="css/main.css">
</head>

The header and hero get their styles instantly, even before main.css finishes downloading. For most small sites, one well-sized CSS file is already fast enough, so treat critical CSS as an optimization for bigger projects. Build tools can extract it for you.

Do complex CSS selectors slow down your site?

You may read that selectors like div > ul li a or * are "slow". This is mostly a myth today. Modern browsers match selectors extremely fast, and the difference is tiny for normal websites.

The things that really slow pages down are:

  • Huge CSS files full of unused rules, which take longer to download and parse.
  • Animating layout properties like width or top instead of transform and opacity.
  • Very large pages with thousands of elements.
  • Big web fonts and images loaded without care.

So choose selectors for readability and low specificity, not for speed.

To find unused CSS, open Chrome DevTools, press Ctrl+Shift+P (Cmd+Shift+P on Mac), type "Coverage" and reload the page. Red bars show CSS that was never used. Remove old styles when you delete features, and avoid loading a whole framework when you only use a few parts.

Loading web fonts with font-display: swap

Custom fonts can be slow to download. By default, some browsers hide the text until the font arrives. That means users stare at an empty page. font-display: swap tells the browser to show the text in a fallback font right away, then swap in your font when it is ready.

@font-face {
  font-family: "Inter";
  src: url("../fonts/inter-var.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
}

body {
  font-family: "Inter", system-ui, sans-serif;
}

Visitors can start reading immediately. Use the modern woff2 format, which is the smallest. Google Fonts adds display=swap to its links for the same reason.

Tip: The fastest font is one that does not need to download. system-ui uses the operating system's own font and looks clean on every device.

CSS accessibility: focus styles, contrast and rem units

Accessibility means everyone can use your site, including people who use a keyboard, a screen reader or a zoomed-in screen. CSS plays a big part.

Focus styles. Keyboard users press Tab to move between links and buttons. The focus outline shows where they are, like a cursor. Never remove it without giving a better one.

/* Never do this alone: */
/* button:focus { outline: none; } */

:focus-visible {
  outline: 3px solid #4f46e5;
  outline-offset: 3px;
  border-radius: 4px;
}

:focus-visible shows the ring for keyboard users, but usually not when someone clicks with a mouse. Everyone gets a good experience.

Common mistake: Writing outline: none to "clean up" buttons. For keyboard users, this is like hiding the mouse pointer. If you remove the outline, always add another clear focus style.

Color contrast. Text must stand out from its background. The WCAG guideline asks for a contrast ratio of at least 4.5:1 for normal text and 3:1 for large text. Light gray text on white often fails. DevTools shows the contrast ratio when you click a color in the Styles panel.

Use rem for text. Many people set a bigger default font size in their browser. rem units follow that setting, but px font sizes ignore it. Use rem for font-size, and it is a good idea for spacing too.

/* Leave the html font-size alone, so the user's setting is respected */
body {
  font-size: 1rem;
}

h1 {
  font-size: clamp(2rem, 1.5rem + 2vw, 3rem);
}

.small-print {
  font-size: 0.875rem;
  color: #4b5563; /* still passes contrast on white */
}

Reduced motion. As you learned in the animations module, wrap big motion in a prefers-reduced-motion check, so users who are sensitive to movement are protected.

Practice exercise

Audit one of your own pages. Use the Coverage panel to find unused CSS, add font-display: swap to any custom font, add a clear :focus-visible style, and check the contrast of your gray text. Fix anything below 4.5:1.

Hint: Press Tab through your whole page with no mouse. If you ever lose track of where you are, your focus styles need work.

Key takeaways

  • CSS blocks rendering, so keep it small; critical CSS can speed up the first screen.
  • Selector speed is rarely a real problem; unused CSS and layout animations are.
  • font-display: swap shows text right away while a web font loads.
  • Always keep a visible focus style, ideally with :focus-visible.
  • Aim for 4.5:1 text contrast and use rem so text follows user settings.