A CSS reset is the foundation of any modern web project. This comprehensive guide covers best practices for creating a consistent styling foundation across all browsers while maintaining accessibility and performance.

Table of Contents

What is a CSS Reset?

A CSS reset typically clears out default styling applied by browsers to elements like headings, paragraphs, and lists, ensuring a consistent starting point for styling across all browsers. It usually sets margins, paddings, and other properties to zero or specific values to minimize cross-browser differences.

Benefits of CSS Resets:

  • Consistency: Ensures consistent styling across browsers
  • Control: Gives you full control over element appearance
  • Performance: Reduces unexpected browser default behaviors
  • Accessibility: Includes proper focus states and semantic handling
  • Maintainability: Provides a solid foundation for your styles

Universal Reset Styles

Core Reset Styles

The foundation of the reset - handling margins, padding, box-sizing, and borders for all elements:

css
:where(*, *::before, *::after) {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    border: 0 solid #e2e8f0;
    transition: all 0.18s ease-out;
}

HTML and Body Resets

Set up color scheme preferences and text rendering:

css
:where(html) {
    color-scheme: dark light;
    -webkit-text-size-adjust: none;
}

:where(body) {
    min-height: 100vh;
    min-height: 100dvh;
    line-height: 1.5;
    font-family: system-ui, sans-serif;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeSpeed;
}

Key Points:

  • color-scheme: dark light - Respects system preferences
  • 100dvh - Uses dynamic viewport height for mobile
  • system-ui - Uses native system fonts for better performance

Form Elements Normalization

Ensure form elements inherit styles consistently:

css
:where(input, button, textarea, select) {
    font: inherit;
    color: inherit;
}

:where(textarea) {
    resize: vertical;
}

:where(button) {
    border-style: solid;
}

:where(label:has(> input:disabled), label:has(+ input:disabled)) {
    cursor: not-allowed;
}

Media and Content Resets

Responsive media handling:

css
:where(img, svg, video, canvas, audio, iframe, embed, object) {
    display: block;
    height: auto;
    width: auto;
}

:where(img, picture, svg) {
    max-width: 100%;
    max-height: 100%;
}

Text and Spacing Resets

Proper handling of text overflow and heading line heights:

css
:where(p, h1, h2, h3, h4, h5, h6) {
    overflow-wrap: break-word;
}

:where(h1, h2, h3) {
    line-height: calc(1em + 0.5rem);
}

:where(ul, ol) {
    list-style: none;
}
css
:where([hidden]) {
    display: none !important;
}

:where(a) {
    text-underline-offset: 0.2ex;
}

:where(hr) {
    border-width: 1px 0 0 0;
    color: inherit;
    height: 0;
    overflow: visible;
}

Smooth Scrolling Preference

Respect user motion preferences:

css
@media (prefers-reduced-motion: no-preference) {
    :where(html:focus-within) {
        scroll-behavior: smooth;
    }
}

Accessibility Features

Focus Visible States

Provide clear visual focus indicators for keyboard navigation:

css
:where(:focus-visible) {
    outline: 2px dashed var(--focus-color, Highlight);
    outline-offset: 2px;
}

Visually Hidden Class

Hide elements visually while keeping them accessible to screen readers:

css
:where(.visually-hidden:not(:where(:focus, :active, .not-visually-hidden))) {
    clip-path: inset(50%) !important;
    height: 1px !important;
    width: 1px !important;
    overflow: hidden !important;
    position: absolute !important;
    white-space: nowrap !important;
    border: 0 !important;
}

Usage in HTML:

<span class="visually-hidden">Screen reader only text</span>

Optimize styles for printing and PDF generation:

css
@media print {
    *,
    *::before,
    *::after {
        text-shadow: none !important;
        box-shadow: none !important;
        -webkit-print-color-adjust: exact !important;
        print-color-adjust: exact !important;
        color-adjust: exact !important;
    }

    @page {
        max-height: 100%;
        max-width: 100%;
    }

    body {
        margin: 0 !important;
        padding: 0 !important;
    }

    body,
    p,
    h1,
    h2,
    h3,
    h4,
    h5,
    h6,
    li {
        font-family: "Gotham Book", Arial, Sans-Serif !important;
        font-size: 12pt !important;
        font-weight: normal !important;
    }

    h1,
    h2,
    h3,
    h4,
    h5,
    h6 {
        font-weight: bold !important;
        margin-bottom: 0.5em !important;
    }

    h1 {
        font-size: 24pt !important;
    }

    h2 {
        font-size: 18pt !important;
    }

    h3 {
        font-size: 14pt !important;
    }

    a {
        text-decoration: none !important;
    }

    a:any-link::before,
    a:any-link::after {
        content: none !important;
    }

    img {
        width: 100%;
        height: 100%;
        display: block;
    }

    header,
    footer,
    nav,
    aside,
    form,
    iframe,
    script {
        display: none !important;
    }

    table,
    tr,
    div * {
        page-break-before: avoid !important;
        page-break-after: avoid !important;
    }
}

Print Reset Guidelines:

Element Treatment
Shadows Removed for cleaner print
Colors Preserved with print-color-adjust
Headers/Footers Hidden (often contain navigation)
Images Responsive sizing for print
Links Underlines removed (no :before/:after)
Page Breaks Prevented to avoid fragmentation

Implementation Tips

Method 1: Using @media Print Import

If separating print styles into a different file:

css
/* Import only for print media */
@import url("print-reset.scss") print;

Method 2: Direct @media Print Usage

Include print styles directly in your reset file:

css
/* Import with @media print */
@import url("reset.scss");

@media print {
    /* Print-specific styles */
}

CSS Reset Integration Strategy

  1. Create reset file - reset.css or reset.scss
  2. Import early - Import reset styles before other stylesheets
  3. Use :where() - Reduces specificity conflicts
  4. Test cross-browser - Verify in Chrome, Firefox, Safari
  5. Test print - Use print preview in browser DevTools

Best Practices

  1. Minimize overwrites - Use specific selectors to override resets when needed
  2. Document custom resets - Explain why you’ve deviated from standard resets
  3. Performance - Keep reset styles lean and focused
  4. Accessibility - Always preserve focus indicators
  5. Print testing - Test print styles with Ctrl+P or Print Preview

Additional Resources

Popular and well-maintained CSS reset libraries:

Related Topics: