interviewDeck

Your one-stop platform to prepare, practice and ace your interviews.

Loading your questions…

All Questions

Filters & tools

CSS Interview Questions and Answers

35 hand-picked CSS interview questions with detailed answers. Open the interactive version above to search, filter by difficulty, run code, bookmark questions and track your progress.

Explain the box model and box-sizing.

Every element is a box: content → padding → border → margin. By default (content-box) width applies to content only, so padding/border add to the total size.

box-sizing: border-box makes width include padding and border — far more predictable, which is why most resets set it globally.

* { box-sizing: border-box; }

When should you use Flexbox instead of CSS Grid?

Flexbox is a one-dimensional layout system that arranges items in a single row or column. It is ideal for navigation bars, toolbars, buttons, and aligning or distributing items along one axis. CSS Grid is a two-dimensional layout system that manages both rows and columns simultaneously, making it the preferred choice for page layouts, dashboards, galleries, and complex responsive designs.

/* Flexbox */
.nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

/* CSS Grid */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
}

How does CSS specificity work?

When multiple CSS rules match the same element, the browser decides which one to apply using the cascade and specificity. Specificity is calculated in the order: Inline styles > IDs > Classes, attributes & pseudo-classes > Elements & pseudo-elements. If two selectors have the same specificity, the rule that appears later in the stylesheet wins. Although !important overrides normal specificity, it should generally be avoided because it makes CSS harder to maintain.

/* Specificity Examples */
#header {
  color: blue;
}

.menu .item {
  color: red;
}

p {
  color: green;
}

/* #header wins because IDs have higher specificity */

Explain the difference between position: relative, absolute, fixed, and sticky.

The position property controls how an element is placed in the document. relative keeps the element in the normal document flow while allowing it to be offset from its original position. absolute removes the element from the normal flow and positions it relative to its nearest positioned ancestor. fixed positions the element relative to the viewport, so it stays in the same place even while scrolling. sticky behaves like relative until a specified scroll threshold (such as top: 0) is reached, after which it behaves like fixed within its scrolling container.

/* Relative */
.card {
  position: relative;
}

/* Absolute */
.badge {
  position: absolute;
  top: 8px;
  right: 8px;
}

/* Fixed */
.chat-button {
  position: fixed;
  bottom: 20px;
  right: 20px;
}

/* Sticky */
.header {
  position: sticky;
  top: 0;
}

What is the difference between px, em, rem, %, vh, and vw in CSS?

CSS provides different units for sizing elements. px is a fixed pixel unit. em is relative to the font size of its parent (or the element itself for certain properties). rem is relative to the root (html) font size. % is relative to the size of the parent element. vh and vw represent 1% of the viewport's height and width respectively, making them useful for responsive layouts.

.container {
  width: 80%;
  padding: 2rem;
}

h1 {
  font-size: 2rem;
}

.card {
  width: 50vw;
  height: 40vh;
}

button {
  font-size: 1.2em;
}

How do you center an element?

Modern answer: flexbox or grid.

  • Flex: display:flex; justify-content:center; align-items:center;
  • Grid: display:grid; place-items:center;
  • Absolute: top:50%; left:50%; transform:translate(-50%,-50%);
.box { display: grid; place-items: center; }

What is the difference between a pseudo-class and a pseudo-element?

A pseudo-class selects an existing element based on its state or position, such as :hover, :focus, or :nth-child(). A pseudo-element selects or creates a specific part of an element, such as ::before, ::after, ::first-line, or ::placeholder.

button:hover {
  background: royalblue;
}

li:nth-child(2) {
  color: red;
}

.badge::after {
  content: '✓';
  color: green;
}

p::first-line {
  font-weight: bold;
}

What are CSS custom properties (CSS variables)?

CSS custom properties (also called CSS variables) are reusable values defined using the -- prefix and accessed with the var() function. Unlike preprocessor variables (Sass/Less), CSS variables exist at runtime, participate in the CSS cascade, inherit by default, and can be updated dynamically using JavaScript. They are commonly used for theming, design systems, and reducing duplicated values.

:root {
  --primary-color: #2563eb;
  --border-radius: 8px;
}

[data-theme="dark"] {
  --primary-color: #60a5fa;
}

.button {
  background: var(--primary-color);
  border-radius: var(--border-radius);
}

How do you build a responsive layout in CSS?

A responsive layout adapts to different screen sizes and devices. Use a mobile-first approach by writing base styles for smaller screens, then enhance the layout using min-width media queries. Combine flexible layouts like Flexbox and CSS Grid with fluid units such as %, rem, fr, and functions like minmax(). Also include the viewport meta tag so layouts scale correctly on mobile devices.

<!-- HTML -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">

/* CSS */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 16px;
}

@media (min-width: 768px) {
  .sidebar {
    display: block;
  }
}

What are CSS combinators? Explain the descendant, child, adjacent sibling, and general sibling combinators.

CSS combinators define the relationship between selectors. The descendant combinator (A B) selects any matching descendant. The child combinator (A > B) selects only direct children. The adjacent sibling combinator (A + B) selects the immediate next sibling. The general sibling combinator (A ~ B) selects all following siblings that share the same parent.

/* Descendant */
.card p {
  color: blue;
}

/* Direct Child */
.card > p {
  font-weight: bold;
}

/* Adjacent Sibling */
h2 + p {
  margin-top: 0;
}

/* General Sibling */
h2 ~ p {
  color: gray;
}

Why doesn't my z-index work? (stacking context)

z-index only compares elements within the same stacking context. Properties like transform, opacity < 1, filter, and position + z-index create new contexts, trapping children's z-index inside them.

Which CSS properties are best for smooth animations?

For smooth, high-performance animations, prefer animating transform and opacity. These properties are handled by the browser's compositor and typically avoid layout recalculations and repainting. Avoid animating layout-related properties such as width, height, top, left, and margin, as they trigger layout updates and can cause janky animations.

.card {
  transition: transform 0.2s ease, opacity 0.2s ease;
}

.card:hover {
  transform: translateY(-4px) scale(1.02);
  opacity: 0.9;
}

What is BEM, and why is it used in CSS?

BEM (Block, Element, Modifier) is a CSS naming convention that makes class names predictable, reusable, and easy to maintain. It promotes low-specificity selectors, avoids deeply nested CSS, and makes components easier to understand and modify. BEM is especially useful in large projects and teams because it reduces style conflicts and improves code organization.

/* Block */
.card {}

/* Element */
.card__title {}
.card__image {}

/* Modifier */
.card--featured {}
.card__button--disabled {}

Explain flex-grow, flex-shrink, and flex-basis.

The flex shorthand controls how items share space:

  • flex-grow — how much an item grows to fill free space.
  • flex-shrink — how much it shrinks when space is tight.
  • flex-basis — the starting size before grow/shrink.

flex: 1 = 1 1 0 (grow equally from zero).

.col { flex: 1 1 200px; } /* grow, shrink, basis */

What is grid-template-areas and when is it used?

grid-template-areas lets you define named regions in a CSS Grid using a readable, text-based layout. Child elements are assigned to these regions using the grid-area property. This makes complex layouts easier to understand, maintain, and rearrange for responsive designs by simply changing the area definitions.

.layout {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
  gap: 16px;
}

.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }

@media (max-width: 768px) {
  .layout {
    grid-template-columns: 1fr;
    grid-template-areas:
      "header"
      "main"
      "sidebar"
      "footer";
  }
}

What is clamp() and when is it used?

The clamp() function lets you define a responsive value by specifying a minimum, a preferred, and a maximum value. The browser uses the preferred value as long as it stays within the specified range. It is commonly used for fluid typography, spacing, widths, and other responsive values without relying on multiple media queries.

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

.container {
  padding: clamp(1rem, 3vw, 2rem);
}

How do you keep an element's aspect ratio?

The aspect-ratio property reserves space in a fixed ratio (e.g. 16/9) so the box sizes correctly and avoids layout shift — replacing the old padding-top hack. Great for video/image placeholders.

.video { aspect-ratio: 16 / 9; width: 100%; }

What does object-fit do?

Controls how a replaced element (img/video) fills its box: cover (fill, crop), contain (fit, letterbox), fill (stretch). Pair with object-position to control the crop focus.

.avatar { width: 64px; height: 64px; object-fit: cover; }

What are CSS Container Queries, and how do they differ from Media Queries?

Container Queries allow a component to change its styles based on the size of its parent container, whereas Media Queries respond to the size of the viewport. This makes components truly reusable because they adapt to the space available rather than the device size. Container Queries are ideal for building responsive UI components that may appear in sidebars, cards, or full-page layouts.

.wrapper {
  container-type: inline-size;
}

.card {
  display: block;
}

@container (min-width: 400px) {
  .card {
    display: flex;
    gap: 1rem;
  }
}

What is the :has() selector?

The long-awaited parent selector: style an element based on its descendants or following siblings. E.g. style a card that contains an image, or a label whose input is invalid — logic that previously required JavaScript.

.card:has(img) { padding: 0; }
label:has(input:invalid) { color: red; }

What are cascade layers (@layer)?

@layer lets you group styles into ordered layers (e.g. reset, base, components, utilities). Layer order wins over specificity, so you can manage the cascade predictably and stop fighting !important in large codebases.

@layer reset, base, components;
@layer components { .btn { color: red; } }

What are logical properties (margin-inline, inset)?

Direction-aware properties that adapt to writing mode/text direction: margin-inline/block, padding-inline, inset. They make layouts work automatically in RTL languages without separate stylesheets.

.box { margin-inline: auto; padding-block: 1rem; }

What does will-change do, and when should you avoid it?

will-change hints the browser to promote an element to its own GPU layer ahead of an animation, reducing jank. But overusing it wastes memory and can hurt performance — apply it sparingly, ideally just before animating, and remove it after.

.modal { will-change: transform, opacity; }

display:none vs visibility:hidden vs opacity:0 — how do they differ?

Takes space?Clickable?Screen readers?
display:noneno (removed from layout)nono
visibility:hiddenyes (space reserved)nono
opacity:0yesyes (still there)yes
.gone   { display: none; }      /* no space, not rendered */
.hidden { visibility: hidden; } /* space kept, invisible */
.faded  { opacity: 0; }         /* space kept, still interactive */

What is float, and what problem does clearfix solve?

float pulls an element to the left/right and lets text/inline content wrap around it — its original purpose (e.g. an image inside a paragraph). Floated elements are taken out of normal flow, so a parent containing only floats collapses to zero height.

clearfix forces the parent to contain its floats. The modern one-liner is display: flow-root; the old trick is a clearing pseudo-element.

/* modern */ .parent { display: flow-root; }
/* legacy  */ .clearfix::after { content: ''; display: block; clear: both; }

What is the overflow property in CSS?

The overflow property controls what happens when an element's content exceeds its available space. visible lets content overflow outside the element. hidden clips the overflow without showing scrollbars. auto displays scrollbars only when needed. scroll always shows scrollbars, even if there is no overflow. clip clips overflowing content like hidden but completely disables scrolling, including programmatic scrolling.

.container {
  height: 300px;
  overflow: auto;
}

.image {
  overflow: hidden;
}

.code-block {
  overflow-x: auto;
}

What is the difference between width, min-width and max-width?

width sets the preferred width. min-width prevents the element from becoming smaller than a given size. max-width prevents it from growing beyond a given size. Together they make layouts responsive while avoiding elements becoming too small or too large.

.card {
  width: 100%;
  max-width: 400px;
  min-width: 250px;
}

Why does a Flexbox child sometimes overflow even though flex-shrink is enabled?

Flex items have a default min-width:auto, which prevents them from shrinking smaller than their content. Long text or large elements can therefore overflow. Setting min-width:0 allows the item to shrink correctly.

.content {
  flex: 1;
  min-width: 0;
}

What is the difference between height and min-height?

height fixes the element's height. If the content is larger, it may overflow. min-height sets the minimum height but allows the element to grow if more content is added. It is commonly used for responsive layouts and full-page sections.

.hero {
  min-height: 100vh;
}

What does pointer-events: none do and when should you use it?

pointer-events:none prevents an element from receiving mouse or touch events. Clicks pass through to the element underneath. It is useful for disabled overlays, decorative elements, loading screens, or invisible elements with opacity:0.

.overlay {
  opacity: 0;
  pointer-events: none;
}

When should you use transform: translate() instead of top/left positioning?

transform: translate() moves an element visually without affecting document layout, making it ideal for animations and transitions. Changing top or left can trigger layout recalculations (reflow), making animations less efficient.

.box {
  transform: translateX(100px);
  transition: transform .3s ease;
}

What is the difference between CSS Transition and CSS Animation?

Transition animates between two states when a property changes (for example on hover). Animation uses @keyframes and can run automatically, repeat infinitely, or contain multiple stages without user interaction.

/* Transition */
.button:hover {
  background: blue;
  transition: background .3s;
}

/* Animation */
@keyframes spin {
  to { transform: rotate(360deg); }
}
.loader {
  animation: spin 1s linear infinite;
}

How do you display an ellipsis (...) when text overflows?

Use the combination of white-space: nowrap, overflow: hidden, and text-overflow: ellipsis. All three properties are required for single-line text truncation.

.title {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

How do you create a triangle using only CSS?

A CSS triangle is created by giving an element zero width and height, then applying transparent borders on three sides and a colored border on the remaining side.

.triangle {
  width: 0;
  height: 0;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-bottom: 20px solid red;
}

What is the difference between display:none, visibility:hidden, opacity:0 and pointer-events:none?

  • display:none removes the element from the layout.
  • visibility:hidden hides the element but still reserves its space.
  • opacity:0 makes the element invisible but it still occupies space and remains clickable.
  • pointer-events:none disables mouse/touch interaction while keeping the element visible (or invisible).
.hidden {
  opacity: 0;
  pointer-events: none;
}

.removed {
  display: none;
}