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
widthortopinstead oftransformandopacity. - 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-uiuses 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: noneto "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: swapshows 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
remso text follows user settings.