CSS Best Practices


CSS Best Practices Interview with follow-up questions

1. What is the difference between CSS reset and normalize?

CSS reset and normalize are both baseline stylesheets applied at the start of a project to address inconsistent default styles across browsers, but they take opposite approaches.

CSS Reset

A reset aggressively removes all browser default styles — margins, padding, font sizes, list styles, heading weights — setting everything to a neutral baseline (usually 0 or inherit). The original Eric Meyer reset and the more recent reset.css by Josh Comeau are well-known examples.

After a reset, every element is essentially unstyled. You have a clean slate, but you must deliberately style every element you use. This gives maximum control but requires more upfront work.

/* Example of reset philosophy */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

Normalize.css

Normalize (normalize.css by Nicolas Gallagher) preserves useful browser defaults and only corrects inconsistencies between browsers. For example, it fixes `styling differences and ensures` renders a dotted underline consistently, without touching defaults that are already reasonable.

The philosophy is "fix what's broken, keep what's sensible." It results in less style override work because you start with a reasonable baseline.

Key differences

Reset Normalize
Approach Strip everything Fix inconsistencies
Starting point Blank slate Sensible defaults preserved
Work required Style all elements from scratch Only override what differs from your design
Size Very small Slightly larger (more targeted rules)

What most teams do in 2026

Many modern projects use a hybrid: box-sizing: border-box on all elements, zero margins on common elements, and a small set of opinionated normalisation rules — sometimes called a "CSS reset with opinions." Frameworks like Tailwind bundle @tailwind/base (which uses Preflight, a Tailwind-specific normalize/reset). Browser defaults have become more consistent over time, reducing the need for heavy resets.

↑ Back to top

Follow-up 1

Can you give an example of a situation where you would use normalize instead of reset?

One situation where you might choose to use normalize instead of reset is when you want to maintain the default styling of certain elements while fixing inconsistencies across different browsers.

For example, let's say you want to use the default styling of form elements like input fields, checkboxes, and buttons, but you also want to ensure consistent styling across different browsers. In this case, you can use normalize to normalize the styles of these form elements while leaving other elements untouched.

Normalize provides a solid foundation for building upon, allowing you to leverage the useful default styles provided by browsers while ensuring consistent styling.

Follow-up 2

Why would you choose one over the other?

The choice between CSS reset and normalize depends on your specific needs and preferences.

If you prefer complete control over the styling of all elements and want to start from scratch, CSS reset might be a better choice. It allows you to define your own styles without any interference from default browser styles. However, keep in mind that you will need to manually style every element, which can be time-consuming.

On the other hand, if you want to maintain some of the useful default styles provided by browsers while ensuring consistent styling across different browsers, normalize might be a better choice. It saves you time by fixing inconsistencies and provides a solid foundation to build upon.

Ultimately, the choice between CSS reset and normalize depends on your project requirements and personal preference.

Follow-up 3

What are the potential drawbacks of using a CSS reset?

While CSS reset can be useful in certain scenarios, it also has some potential drawbacks that you should consider:

  1. Increased development time: Since CSS reset removes all default styles, you will need to manually style every element from scratch. This can be time-consuming, especially for larger projects.

  2. Increased file size: CSS reset often involves defining styles for all elements, which can result in a larger CSS file size. This can impact page load times, especially for users with slower internet connections.

  3. Overriding useful default styles: CSS reset removes all default styles, including some useful ones provided by browsers. This means you will need to recreate those styles if you want to use them, adding extra work.

  4. Potential for unintended side effects: CSS reset can have unintended side effects if not implemented correctly. It's important to thoroughly test your styles across different browsers and devices to ensure consistent rendering.

2. What are CSS sprites and why are they used?

CSS sprites are a technique where multiple small images are combined into a single larger image file. Individual images are then displayed by applying the combined image as a CSS background-image and using background-position to offset to the correct region.

.icon-home {
  width: 24px;
  height: 24px;
  background-image: url('sprites.png');
  background-position: -48px -24px;
}

Why they were used

The original motivation was HTTP/1.1 performance: browsers under HTTP/1.1 could only open a limited number of parallel connections per domain (typically 6). Each image request consumed a connection slot. A page with 30 small icons made 30 separate HTTP requests. Sprites collapsed those into one, dramatically reducing page load time.

Why they matter less in 2026

HTTP/2 and HTTP/3 use multiplexing — many requests travel over a single connection with no per-request overhead. The core performance argument for sprites is largely gone on HTTP/2+ connections.

Modern alternatives for icons have also displaced sprites:

  • SVG icon sprites — an SVG file with elements, referenced via — readable, scalable, styleable with CSS.
  • Icon fonts (Font Awesome, Material Icons) — still used but carry accessibility concerns.
  • Inline SVG — gives full CSS control over individual paths.
  • CSS mask — load an SVG as a mask over a coloured background-color, allowing colour changes with CSS.

When sprites still make sense

Raster image sprites remain relevant for spritesheets in canvas-based games, pixel art assets, or cases where many small raster images (PNG, WebP) need to be batched and the server does not support HTTP/2.

Interview follow-up: "Does HTTP/2 make sprites obsolete?" For icon workflows, largely yes. But for game spritesheet animation or raster assets on servers that still serve HTTP/1.1, they remain useful.

↑ Back to top

Follow-up 1

How do CSS sprites improve web performance?

CSS sprites improve web performance by reducing the number of HTTP requests made by a webpage. When multiple images are combined into a single image file, the browser only needs to make a single request to fetch the image. This reduces the latency and overhead associated with making multiple requests. Additionally, CSS sprites allow for more efficient caching, as the single image file can be cached by the browser and reused across multiple elements on the webpage.

Follow-up 2

What are the potential drawbacks of using CSS sprites?

While CSS sprites offer benefits in terms of web performance, there are also potential drawbacks to consider. One drawback is that CSS sprites can increase the complexity of the code and make it harder to maintain. Another drawback is that CSS sprites may not be suitable for all types of images, especially if the images have different dimensions or require frequent updates. Additionally, CSS sprites can be challenging to implement for responsive designs, as the background positions need to be adjusted for different screen sizes.

Follow-up 3

Can you give an example of how to implement CSS sprites?

Sure! Here's an example of how to implement CSS sprites:

HTML:

<div class="sprite"></div>

CSS:

.sprite {
    width: 100px;
    height: 100px;
    background-image: url('sprites.png');
    background-position: -50px -50px;
}

In this example, we have a div element with a class of sprite. The sprites.png image file contains multiple images combined into a single sprite. By adjusting the background-position property, we can display a specific portion of the sprite for the div element.

3. Can you explain the concept of specificity in CSS?

Specificity is the algorithm browsers use to determine which CSS declaration wins when multiple rules target the same element and property. Higher specificity overrides lower specificity, regardless of source order.

How specificity is calculated

Specificity is represented as three numbers (A, B, C), sometimes written as a three-part score:

  • A — ID selectors: each #id adds 1 to the hundreds column (0,1,0)
  • B — Class, attribute, and pseudo-class selectors: each .class, [attr], :hover adds 1 to the tens column (0,0,1 in the new notation)
  • C — Type selectors and pseudo-elements: each div, p, ::before adds 1 to the ones column

Inline styles (style="") always beat any selector. The !important annotation beats everything except another !important with higher specificity.

Examples

Selector Specificity
* 0,0,0
p 0,0,1
.card 0,1,0
p.card 0,1,1
#header 1,0,0
#header .nav a 1,1,1
style="" Inline — beats all
!important Override layer — beats inline

Source order as tiebreaker

When two rules have equal specificity, the one that appears later in the source wins.

Modern additions

  • :is() and :not() take the specificity of their most specific argument.
  • :where() always has zero specificity — useful for writing low-specificity utility rules that are easy to override.
  • @layer (cascade layers) adds a new layer of the cascade above specificity: rules in a higher-priority layer beat rules in a lower-priority layer regardless of specificity.

Common interview gotcha: "Does !important always win?" Two !important declarations resolve by specificity among themselves. And a rule in an unlayered stylesheet beats an !important rule inside a lower-priority @layer, which surprises many developers.

Best practice is to keep specificity as flat as possible (prefer classes over IDs in selectors, avoid !important) so styles remain easy to override and maintain.

↑ Back to top

Follow-up 1

How does specificity affect the cascade in CSS?

Specificity affects the cascade in CSS by determining which styles take precedence when multiple conflicting styles are applied to an element. When two or more conflicting styles have the same specificity, the one that appears later in the CSS file or inline style will override the previous ones. However, when one style has a higher specificity than the others, it will always take precedence, regardless of its position in the CSS file.

Follow-up 2

Can you give an example of how specificity can be used to override styles?

Sure! Let's say we have the following CSS rules:

p {
  color: blue;
}

#my-paragraph {
  color: red;
}

In this case, the p selector has a lower specificity than the #my-paragraph selector because it targets all p elements, while the #my-paragraph selector targets a specific element with the ID my-paragraph. Therefore, the color: red; style will override the color: blue; style for the element with the ID my-paragraph.

Follow-up 3

What problems might arise if specificity is not properly managed?

If specificity is not properly managed, it can lead to unexpected styling behavior and make it difficult to maintain and debug CSS code. Some problems that might arise include:

  • Styles not being applied as intended, leading to inconsistent or incorrect visual appearance.
  • Styles being overridden unintentionally, causing unexpected changes in the layout or design.
  • Difficulty in overriding styles when needed, as higher-specificity styles may be difficult to override without using !important or modifying the HTML structure.
  • Increased complexity and difficulty in understanding and maintaining the CSS codebase.

4. What are some best practices for organizing CSS stylesheets?

Organising CSS well prevents specificity battles, reduces duplication, and makes large codebases navigable by any team member.

1. Adopt a naming methodology

BEM (Block_Element--Modifier) is the most widely used: .card, `.card_title,.card--featured`. It keeps specificity flat (all single classes), makes component boundaries explicit, and avoids accidental global style bleed.

2. Use a consistent file structure

Popular architectures like ITCSS (Inverted Triangle CSS) order files from lowest specificity to highest: settings, tools, generic, elements, objects, components, utilities. Placing high-specificity overrides at the end prevents cascade conflicts.

3. Use CSS Cascade Layers (@layer)

Layers give explicit control over cascade priority independent of specificity or source order:

@layer reset, base, components, utilities;

Rules in later-declared layers always win. This is the modern replacement for specificity hacks and !important.

4. Use CSS custom properties for design tokens

Define colours, spacing, and typography as variables on :root. This creates a single source of truth and enables theming:

:root {
  --color-primary: #3b82f6;
  --space-4: 1rem;
}

5. Co-locate styles with components

In component-based frameworks (React, Vue, Svelte), scoped styles or CSS Modules keep component styles alongside their markup, preventing cross-component interference.

6. Limit nesting depth (when using Sass or native CSS nesting)

Nest no more than three levels deep. Over-nesting produces overly specific selectors that are hard to override.

7. Minimise !important

Reserve !important for utility classes (where it is intentional and expected) and browser override hacks. Avoid it in component styles.

8. Use linting tools

Stylelint enforces naming conventions, property ordering, and specificity limits across the team, removing the burden from code review.

9. Document intentional patterns

A brief comment on a non-obvious rule (a magic number, a z-index value, a known browser hack) saves the next developer significant time.

10. Purge unused styles in production

Tools like PurgeCSS or Tailwind's built-in content scanning remove unused rules at build time, keeping bundles small.

↑ Back to top

Follow-up 1

Why is it important to keep CSS stylesheets organized?

Keeping CSS stylesheets organized is important for several reasons:

  1. Readability: Organized stylesheets are easier to read and understand, making it easier for developers to maintain and update the code.
  2. Scalability: Well-organized stylesheets are more scalable, allowing for easier addition and modification of styles as the project grows.
  3. Collaboration: Organized stylesheets make it easier for multiple developers to work on the same codebase, reducing conflicts and improving collaboration.
  4. Performance: Organized stylesheets can improve performance by reducing the file size and optimizing code, resulting in faster load times for web pages.

Follow-up 2

Can you give an example of a well-organized CSS stylesheet?

Sure! Here's an example of a well-organized CSS stylesheet:

/* Reset styles */

/* Typography styles */

/* Header styles */

/* Navigation styles */

/* Main content styles */

/* Sidebar styles */

/* Footer styles */

/* Media queries */

Follow-up 3

What tools or techniques can be used to maintain CSS organization?

There are several tools and techniques that can be used to maintain CSS organization:

  1. CSS preprocessors: CSS preprocessors like Sass or Less provide features such as variables, mixins, and nesting, which can help organize and modularize styles.
  2. CSS frameworks or libraries: Using a CSS framework or library like Bootstrap or Foundation can provide a structure and guidelines for organizing styles.
  3. CSS linters: CSS linters like Stylelint or CSSLint can help enforce coding standards and best practices, ensuring consistent organization of styles.
  4. CSS modules: CSS modules allow for local scoping of styles, preventing style conflicts and improving organization.
  5. CSS naming conventions: Following a consistent naming convention for classes and IDs can help maintain organization and readability of styles.
  6. IDE or text editor plugins: Many IDEs and text editors have plugins or extensions that provide features like code formatting, linting, and auto-completion, which can aid in maintaining CSS organization.

5. How can CSS be optimized for better performance?

CSS performance affects both initial load time (how large the stylesheet is) and rendering performance (how fast the browser can parse and apply styles).

Reduce file size

  • Minify CSS in production — remove whitespace, comments, and redundant rules. All modern bundlers (Vite, webpack, esbuild) do this automatically.
  • Enable gzip or Brotli compression on the server. Brotli typically achieves 15–20% better compression than gzip on CSS.
  • Remove unused CSS. PurgeCSS, Tailwind's built-in content scanning, and CSS Modules all prevent shipping rules that are never applied.

Reduce blocking

  • CSS in `` blocks rendering until downloaded and parsed. Keep the critical path lean.
  • Split CSS and load non-critical styles asynchronously using `with anonload` swap.
  • Inline critical CSS (above-the-fold styles) directly in the `` to avoid a render-blocking network round-trip.

Write efficient selectors

Browsers match selectors right-to-left. Overly broad right-most selectors like * { } or deeply nested chains like .nav .list .item .link span force the browser to examine many elements. Prefer flat, single-class selectors.

Use GPU-accelerated properties for animation

Animate transform and opacity instead of top/left/width/height. The former are composited on the GPU without triggering layout or paint; the latter trigger expensive layout recalculations.

Use will-change sparingly

will-change: transform promotes an element to its own compositor layer ahead of an animation, reducing jank. But overusing it wastes GPU memory and can hurt overall performance.

Prefer CSS animations and transitions over JavaScript for visual effects

CSS animations run on the compositor thread and do not block the main JavaScript thread.

Use contain and content-visibility

content-visibility: auto tells the browser to skip rendering off-screen content until it scrolls into view, dramatically improving initial render time on long pages.

Use modern layout (Grid and Flexbox)

These are optimised in browser layout engines. Avoid older hacks (floats for layout, absolute positioning grids) that trigger more complex layout calculations.

Avoid @import in production CSS

CSS @import is serial — each imported file stalls the next. Use a bundler to concatenate files instead.

↑ Back to top

Follow-up 1

What are some common mistakes that can slow down CSS rendering?

Some common mistakes that can slow down CSS rendering include:

  1. Using inefficient CSS selectors: Complex and inefficient selectors can cause the browser to perform extensive matching, resulting in slower rendering.

  2. Overusing CSS animations and transitions: Heavy animations or transitions can cause jank and slow down the rendering of the page.

  3. Not optimizing CSS file size: Large CSS files take longer to download and parse, slowing down the rendering process. Minifying and compressing CSS files can help reduce their size.

  4. Not using CSS sprites: Using multiple small images instead of combining them into a single sprite can increase the number of HTTP requests required to load the page.

  5. Using inline styles: Inline styles increase the size of the HTML file and make it harder to maintain and update the styles.

  6. Not using media queries: Not using media queries to apply different styles based on the device or screen size can result in inefficient rendering on different devices.

By avoiding these common mistakes, CSS rendering can be optimized for better performance.

Follow-up 2

How does the use of shorthand properties in CSS affect performance?

The use of shorthand properties in CSS can have a positive impact on performance. Shorthand properties allow multiple CSS properties to be set with a single declaration, which reduces the amount of code and improves the file size of the CSS file. This can result in faster download and parsing times.

However, it's important to note that the use of shorthand properties can also have a negative impact on performance if not used correctly. When using shorthand properties, all the individual properties within the shorthand declaration are set, even if they are not explicitly specified. This can lead to unintended side effects and conflicts with other CSS rules.

To ensure optimal performance when using shorthand properties, it's recommended to:

  • Only use shorthand properties when necessary and appropriate.
  • Be aware of the specific properties that are set by the shorthand declaration.
  • Avoid using shorthand properties in situations where individual control over each property is required.

By using shorthand properties judiciously and understanding their implications, CSS performance can be improved.

Follow-up 3

Can you give an example of how to optimize a CSS file for better performance?

Certainly! Here's an example of how to optimize a CSS file for better performance:

  1. Combine multiple CSS files into a single file: Instead of having multiple CSS files, merge them into a single file to reduce the number of HTTP requests required to load the stylesheets.

  2. Minify and compress the CSS file: Remove unnecessary whitespace, comments, and line breaks from the CSS file to reduce its file size. Additionally, enable gzip compression on the server to further reduce the size of the CSS file.

  3. Use shorthand properties: Instead of specifying individual properties, use shorthand properties to set multiple properties with a single declaration. This reduces the amount of code and improves the file size of the CSS file.

  4. Use CSS sprites: Combine multiple small images into a single larger image and use CSS background positioning to display the desired image. This reduces the number of HTTP requests required to load the page.

  5. Use media queries: Use media queries to apply different styles based on the device or screen size. This allows for a more optimized and responsive design.

By implementing these optimization techniques, the CSS file can be optimized for better performance.

Live mock interview

Mock interview: CSS Best Practices

Intermediate ~5 min Your own free AI key

Your voice and your AI key never touch our servers; the key stays in this browser and is sent only to Google. Only your round scores are saved to track progress.