Skip to content
RED SAGSkills

CSS interview questions and answers

CSS interview questions test layout and the cascade. Expect to explain why a style does not apply, how flexbox and grid place items, and how to build layouts that work on every screen size.

Below are 60 CSS questions with the correct answer and a short explanation, grouped from fresher to experienced level. Try each one before you open the answer.

What CSS interviews usually check

  • ✓The cascade, specificity and inheritance
  • ✓The box model, margins, padding and box-sizing
  • ✓Flexbox and CSS Grid layouts
  • ✓Positioning, stacking contexts and z-index
  • ✓Responsive design, media queries and units like rem and vw

CSS interview questions for freshers easy

1. Width with border-box

A div has width: 200px, padding: 20px and border: 5px, with box-sizing: border-box. What is its total rendered width?

  1. A.200px
  2. B.250px
  3. C.240px
  4. D.210px
Show answer

Answer: A. 200px

With border-box, the declared width includes padding and border, so the box stays 200px wide and the content area shrinks to 150px. With the default content-box, the total would be 200 + 40 + 10 = 250px.

2. Where absolute elements are placed

An element has position: absolute; top: 0; left: 0. Its top-left corner is placed relative to what?

  1. A.Its direct parent element, whatever position value that parent has
  2. B.The browser viewport, even when the page is scrolled
  3. C.The nearest ancestor whose position is not static
  4. D.The element that comes right before it in the HTML source
Show answer

Answer: C. The nearest ancestor whose position is not static

An absolutely positioned element is placed inside its containing block, which is the nearest ancestor with position relative, absolute, fixed or sticky (or the initial containing block if there is none). That is why you add position: relative to a card when you want a badge pinned to its corner. Fixed positioning is the one that uses the viewport.

3. Grid columns with fr units

A grid container is exactly 300px wide with no gap and no padding. How wide are the two columns?

.grid {
  display: grid;
  grid-template-columns: 1fr 2fr;
}
  1. A.150px and 150px
  2. B.1px and 2px
  3. C.200px and 100px
  4. D.100px and 200px
Show answer

Answer: D. 100px and 200px

The fr unit shares out the free space in the grid track by fractions. There are 3 fractions in total, so each fraction is 100px: the first column gets 1 share (100px) and the second gets 2 shares (200px). fr is the simplest way to build flexible, proportional columns.

4. Media query for mobile-first CSS

In a mobile-first stylesheet, the base styles are written for small screens. Which media query should wrap the extra styles for tablets and larger screens?

  1. A.@media (min-width: 768px)
  2. B.@media (max-width: 768px)
  3. C.@media print
  4. D.@media (orientation: portrait)
Show answer

Answer: A. @media (min-width: 768px)

Mobile-first means the default CSS targets small screens and you add layers for wider screens with min-width queries. A min-width query applies from that width and up. max-width queries are used in a desktop-first approach, where you start wide and override for smaller screens.

5. Tailwind md: prefix

In Tailwind CSS, when does the text-lg style apply on this element?

<p class="text-sm md:text-lg">Hello</p>
  1. A.Only between 768px and 1023px wide
  2. B.Only on screens narrower than 768px
  3. C.From the md breakpoint (768px by default) and wider
  4. D.Only when the user has chosen a larger text size
Show answer

Answer: C. From the md breakpoint (768px by default) and wider

Tailwind is mobile-first: an unprefixed class applies at every size, and a prefix like md: means "at this min-width and above". So the text is small on phones and large from 768px up, including on large desktops. To target only a range you would combine a breakpoint with a max-* variant.

6. Link or button

A control opens the /pricing page. Another control opens a filter panel on the same page. Which elements should they be?

  1. A.<a href="/pricing"> and <button>
  2. B.<button> for both of them
  3. C.<a href="#"> for both of them
  4. D.<div onclick> for both of them
Show answer

Answer: A. <a href="/pricing"> and <button>

Links navigate to a URL; buttons perform actions on the current page. Using the right element gives the correct keyboard behaviour, screen reader role and browser features like open in new tab for links.

7. Caption for a chart image

A report shows a chart image with a caption "Sales by emirate, 2025" under it. What is the semantic way to mark this up?

  1. A.<div> with <img> and <p class="caption">
  2. B.<figure> with <img> and <figcaption>
  3. C.<img> with a title attribute only
  4. D.<section> with <img> and <h6>
Show answer

Answer: B. <figure> with <img> and <figcaption>

<figure> groups self-contained media with its caption, and <figcaption> ties the caption to it for assistive technology. The image still needs its own alt text describing the chart.

8. Two elements with the same id

A page has two inputs with id="phone". What can go wrong?

  1. A.The page fails to load in strict browsers
  2. B.Both inputs are merged into one field
  3. C.CSS #phone rules stop working entirely
  4. D.Labels and getElementById reach only one of them
Show answer

Answer: D. Labels and getElementById reach only one of them

An id must be unique in the document. getElementById returns only the first match, <label for="phone"> links to only one input, and aria-describedby can point to the wrong element. Copy-pasted components often cause this.

9. A FAQ that opens and closes

Which HTML gives an accessible expand/collapse FAQ item with no JavaScript?

  1. A.<details><summary>Question</summary>Answer</details>
  2. B.<div class="faq" hidden>Answer</div>
  3. C.<dialog open>Question Answer</dialog>
  4. D.<section toggle>Question Answer</section>
Show answer

Answer: A. <details><summary>Question</summary>Answer</details>

<details> and <summary> make a native disclosure widget. The summary is focusable, works with Enter and Space, and screen readers announce whether it is expanded. The name attribute can group several so only one stays open.

10. Total width with content-box

With the default box-sizing: content-box, how wide does this box appear on screen?

.card {
  width: 200px;
  padding: 20px;
  border: 2px solid #ccc;
}
  1. A.200px
  2. B.240px
  3. C.222px
  4. D.244px
Show answer

Answer: D. 244px

In content-box, width sets only the content area. Padding and border are added outside it: 200 + 20 + 20 + 2 + 2 = 244px. With border-box, the whole box would be 200px instead.

11. Properties that inherit

A parent has color: navy and border: 1px solid red. Which of these does a child <p> inherit by default?

  1. A.border only
  2. B.both color and border
  3. C.neither
  4. D.color only
Show answer

Answer: D. color only

Text-related properties such as color, font and line-height inherit by default. Box properties like border, padding, margin and background do not. You can force inheritance with the inherit keyword.

12. first-child versus first-of-type

An article starts with an <h2>, then several <p> elements. Which selector styles the first paragraph?

  1. A.article p:first-child
  2. B.article:first-child p
  3. C.article > :first-child
  4. D.article p:first-of-type
Show answer

Answer: D. article p:first-of-type

:first-child matches only if the element is the very first child of its parent; here that is the h2, so p:first-child matches nothing. :first-of-type picks the first element of that tag name among its siblings.

13. Following the system dark mode

How can CSS switch to dark colours when the user’s phone or laptop is set to dark mode?

  1. A.@media (theme: dark) and (screen) { ... }
  2. B.@media (prefers-color-scheme: dark) { ... }
  3. C.@media (color: black) or (night) { ... }
  4. D.:root:dark, :root:night { ... }
Show answer

Answer: B. @media (prefers-color-scheme: dark) { ... }

The prefers-color-scheme media feature reports the user’s system theme as light or dark. Redefine your colour custom properties inside it so the whole site switches with one block of CSS.

14. Invisible text while fonts load

On slow 3G, headings stay blank for seconds until the web font arrives. Which @font-face setting shows fallback text at once?

  1. A.font-display: block
  2. B.font-weight: normal
  3. C.font-display: swap
  4. D.font-style: fallback
Show answer

Answer: C. font-display: swap

font-display: swap shows text in a fallback font immediately and swaps in the web font when it loads. block hides the text for a short period first. Pair swap with a well-matched fallback to limit layout shift.

15. Printing an invoice page

When a customer prints an invoice, the site header and chat widget should be hidden. Where should that CSS go?

  1. A.Inside @media screen { ... }
  2. B.Inside @media (max-width: 600px) { ... }
  3. C.In a script that runs on window.onload
  4. D.Inside @media print { ... }
Show answer

Answer: D. Inside @media print { ... }

@media print rules apply only when printing or saving as PDF. Hide navigation and widgets there, and use break-inside: avoid on table rows or cards so they are not split across pages.

16. A heading with one word on the last line

A two-line heading leaves a single word alone on its second line. Which CSS evens out the line lengths?

  1. A.text-wrap: balance
  2. B.white-space: nowrap
  3. C.word-break: break-all
  4. D.text-align: justify
Show answer

Answer: A. text-wrap: balance

text-wrap: balance makes the browser choose line breaks so lines are about equal length, which suits short headings. nowrap prevents wrapping entirely, and break-all splits words in the middle.

17. Why CSS blocks rendering

Why does a normal stylesheet link in the head delay the first paint?

  1. A.The browser waits for CSS so it does not paint unstyled content
  2. B.The browser cannot download CSS and HTML together
  3. C.CSS must be executed like JavaScript first
  4. D.Stylesheets are always loaded after images
Show answer

Answer: A. The browser waits for CSS so it does not paint unstyled content

The browser needs the CSSOM to know how things look, so by default it holds the first render until stylesheets in the head arrive. That avoids a flash of unstyled content, but it means large or slow CSS files delay FCP and LCP.

18. Oversized product photo

A product thumbnail shows at 300 × 300 CSS pixels, but the file is 3000 × 3000 pixels. On a phone with a 2x screen, what size is enough?

  1. A.About 3000 × 3000 pixels
  2. B.About 150 × 150 pixels
  3. C.About 600 × 600 pixels
  4. D.About 1200 × 1200 pixels
Show answer

Answer: C. About 600 × 600 pixels

A 2x screen uses two device pixels per CSS pixel, so 300 × 2 = 600 pixels each side is sharp. The 3000 px file has 25 times as many pixels as needed, wasting bandwidth and decode time.

19. Brotli compared to gzip

For text files like JS and CSS, how does Brotli usually compare to gzip?

  1. A.Smaller files at similar decompress speed
  2. B.Larger files but much faster to compress
  3. C.It works only on images, not on text
  4. D.It is no longer supported by browsers
Show answer

Answer: A. Smaller files at similar decompress speed

Brotli usually makes text files about 15–25% smaller than gzip. Static files can be compressed at high Brotli levels once at build time, so the slower compression does not matter.

20. Rounded vs exact numbers

Which claim is likely to feel more credible to readers?

  1. A.'Customers save tons of time every week'
  2. B.'Customers save an average of 3.2 hours a week'
  3. C.'Customers save so much time it is crazy'
  4. D.'Customers save countless hours'
Show answer

Answer: B. 'Customers save an average of 3.2 hours a week'

A precise figure suggests it was measured, so it feels more believable than vague praise. It must be accurate and you should be able to show how it was measured. Vague words like 'tons' or 'countless' are easy to dismiss.

CSS intermediate interview questions medium

21. Responsive card grid without media queries

You want a card grid that fits as many columns as possible, each at least 200px wide, with the columns stretching to fill the row. Which grid-template-columns value does this?

  1. A.repeat(4, 200px)
  2. B.repeat(auto-fit, minmax(200px, 1fr))
  3. C.repeat(auto-fit, 1fr)
  4. D.minmax(200px, 1fr) auto
Show answer

Answer: B. repeat(auto-fit, minmax(200px, 1fr))

auto-fit creates as many tracks as fit in the container, and minmax(200px, 1fr) lets each track be at least 200px but grow to share the leftover space. The layout changes column count by itself as the width changes. repeat(auto-fit, 1fr) is invalid because auto-repeat needs a definite minimum size.

22. Native element or ARIA

A developer adds role="checkbox", aria-checked and key handlers to a styled <div>. What does the "first rule of ARIA" suggest?

  1. A.Add role="button" as well to be safe
  2. B.Use a native <input type="checkbox"> and style it
  3. C.Put tabindex="-1" on the div
  4. D.Wrap the div in a <label> to finish it
Show answer

Answer: B. Use a native <input type="checkbox"> and style it

If a native HTML element already has the meaning and behaviour you need, use it instead of rebuilding it with ARIA. Native inputs come with focus, keyboard support, form submission and correct announcements for free; ARIA only changes what is announced.

23. Announcing "Added to cart"

After clicking Add to cart, a small text "Added to cart" appears. Screen reader users hear nothing. What fixes it?

  1. A.Add tabindex="0" to the message element
  2. B.Put it in a role="status" region that exists on load
  3. C.Give the message a bright colour and icon
  4. D.Show it with alert() instead of on-page text
Show answer

Answer: B. Put it in a role="status" region that exists on load

Screen readers announce changes inside a live region (role="status" or aria-live="polite"). The empty region should exist in the DOM before the text is added, otherwise some readers miss the change. alert() works but interrupts every user.

24. Autofill for an OTP field

Which attribute lets phones offer the SMS one-time password straight from the keyboard?

  1. A.autocomplete="one-time-code"
  2. B.type="otp"
  3. C.autocomplete="off"
  4. D.pattern="[0-9]{6}" alone
Show answer

Answer: A. autocomplete="one-time-code"

autocomplete="one-time-code" tells iOS and Android the field expects an SMS code, so they suggest it above the keyboard. Combine it with inputmode="numeric". There is no input type="otp".

25. Live versus static lists

You add a new .item element after taking both lists. Which list includes it?

const a = document.querySelectorAll(".item")
const b = document.getElementsByClassName("item")
container.append(newItem) // newItem has class "item"
  1. A.Only a
  2. B.Only b
  3. C.Both a and b
  4. D.Neither
Show answer

Answer: B. Only b

querySelectorAll returns a static NodeList, a snapshot taken at call time. getElementsByClassName returns a live HTMLCollection that updates as the DOM changes. Looping over a live collection while removing items can skip elements.

26. hidden versus aria-hidden

What is the difference between the hidden attribute and aria-hidden="true"?

  1. A.They do exactly the same thing
  2. B.aria-hidden hides it visually; hidden only from screen readers
  3. C.hidden only works on form fields
  4. D.hidden hides it from everyone; aria-hidden only from assistive tech
Show answer

Answer: D. hidden hides it from everyone; aria-hidden only from assistive tech

The hidden attribute applies display: none, so the element is neither shown nor announced. aria-hidden="true" leaves it visible but removes it from the accessibility tree, which suits decorative icons. A CSS display rule can override hidden.

27. State of a menu button

A hamburger <button> opens and closes the mobile menu. What should change on the button when the menu opens?

  1. A.aria-hidden from "true" to "false"
  2. B.aria-expanded from "false" to "true"
  3. C.role from "button" to "menu"
  4. D.tabindex from "0" to "-1"
Show answer

Answer: B. aria-expanded from "false" to "true"

aria-expanded tells screen readers whether the control’s related content is open, so they announce "Menu, button, expanded". Pair it with aria-controls pointing at the menu’s id if useful. The role should stay button.

28. Pressing Enter in a search field

A <form> has one text input and a submit button. The user presses Enter in the input. What happens?

  1. A.The form submits, as if the button was clicked
  2. B.Nothing; Enter only adds a new line
  3. C.Only the input’s change event fires
  4. D.The browser asks for confirmation first
Show answer

Answer: A. The form submits, as if the button was clicked

Browsers support implicit submission: Enter in a text field submits the form through its default button. This is good for search boxes and logins. If you build forms with divs and no <form>, you lose this behaviour.

29. Pushing one nav item to the right

A header flex row has a logo, three links and a Login button. Only Login should sit at the far right. What is the simplest CSS?

  1. A.margin-left: auto on the Login button
  2. B.float: right on the Login button
  3. C.justify-content: flex-end on the header
  4. D.position: absolute on the Login button
Show answer

Answer: A. margin-left: auto on the Login button

In flexbox, an auto margin absorbs all free space on that side. margin-left: auto on Login pushes it, and only it, to the end. float has no effect on flex items, and flex-end would move everything right.

30. Width that leaves room for a sidebar

A main column must take the full width minus a 280px sidebar. Which value works?

  1. A.width: 100% - 280px
  2. B.width: calc(100%-280px)
  3. C.width: calc(100% minus 280px)
  4. D.width: calc(100% - 280px)
Show answer

Answer: D. width: calc(100% - 280px)

calc() can mix units like % and px, but + and − must have spaces around them. calc(100%-280px) is invalid because it reads as a single token, and plain 100% - 280px is not valid CSS.

31. Font size from clamp()

With a 16px root font size, what is the font size at a 1000px wide viewport, and at 400px?

h1 { font-size: clamp(1rem, 2.5vw, 2rem); }
  1. A.25px at 1000px, and 10px at 400px
  2. B.25px at 1000px, and 16px at 400px
  3. C.32px at 1000px, and 16px at 400px
  4. D.16px at 1000px, and 25px at 400px
Show answer

Answer: B. 25px at 1000px, and 16px at 400px

clamp(min, preferred, max) uses the preferred value but limits it. 2.5vw is 25px at 1000px, which is between 16px and 32px. At 400px it would be 10px, so the minimum 16px is used.

32. Resetting a property

A component sets button { all: unset } and the buttons lose their browser styles. What does revert do differently from initial?

  1. A.revert goes back to the browser default; initial uses the spec default
  2. B.They are identical in every case
  3. C.revert removes the element from the page
  4. D.initial uses the parent value; revert uses the spec value
Show answer

Answer: A. revert goes back to the browser default; initial uses the spec default

initial sets the property’s spec default, so display: initial is inline even for a div. revert rolls back to what the previous origin set, usually the browser stylesheet, so a div gets display: block again. unset inherits if the property inherits, else acts like initial.

33. Why a big CSS file delays first paint

A 300 KB stylesheet in <head> makes the page stay white for two seconds on slow networks. Why?

  1. A.CSS is executed line by line like JavaScript
  2. B.Stylesheets block all image downloads
  3. C.Browsers wait for CSS in head before the first paint
  4. D.The browser paints, then clears the screen for CSS
Show answer

Answer: C. Browsers wait for CSS in head before the first paint

To avoid showing unstyled content, the browser holds rendering until stylesheets in the head are downloaded and parsed. Inline the small critical CSS for above-the-fold content and load the rest later or split it by page.

34. A print stylesheet and render blocking

Does <link rel="stylesheet" href="print.css" media="print"> delay the first paint on screen?

  1. A.Yes; every stylesheet blocks rendering
  2. B.It is not downloaded at all until printing
  3. C.No; it downloads at low priority without blocking
  4. D.Yes, but only on mobile devices
Show answer

Answer: C. No; it downloads at low priority without blocking

A stylesheet whose media query does not match the current environment is still downloaded, but at low priority and without blocking rendering. Splitting CSS by media type is a simple way to shrink the blocking CSS.

35. A slow loop that resizes cards

Why is this loop slow with 500 cards?

cards.forEach((c) => {
  c.style.height = "auto"
  c.style.height = c.offsetHeight + 10 + "px"
})
  1. A.style.height is a slow property for the browser to set
  2. B.forEach is slower than a for loop by 500×
  3. C.String joining with + is slow in loops
  4. D.Each offsetHeight read after a write forces layout
Show answer

Answer: D. Each offsetHeight read after a write forces layout

Reading layout values like offsetHeight right after changing styles forces the browser to compute layout immediately. Doing write, read, write in a loop causes 500 forced layouts. Read all heights first, then write all changes.

36. Skipping off-screen rendering

A long article page spends a lot of time in layout. Which CSS can let the browser skip rendering sections that are off screen?

  1. A.display: contents on every article section
  2. B.visibility: hidden on all the off-screen sections
  3. C.will-change: transform set on the body element
  4. D.content-visibility: auto with contain-intrinsic-size
Show answer

Answer: D. content-visibility: auto with contain-intrinsic-size

content-visibility: auto lets the browser skip layout and paint for off-screen content until it nears the viewport. contain-intrinsic-size gives a placeholder size so the scrollbar does not jump as sections render.

37. Finding unused JavaScript

Which Chrome DevTools tool shows how many bytes of each JS and CSS file were actually used during a page load?

  1. A.The Elements panel
  2. B.The Coverage tab
  3. C.The Application panel
  4. D.The Sources snippets
Show answer

Answer: B. The Coverage tab

Coverage records which bytes ran or which CSS rules applied, and shows unused bytes in red. Large unused shares point to code that should be split, lazy-loaded or removed.

38. Limiting layout work

A widget updates often and its changes cause layout work across the whole page. Which CSS can limit the work to the widget?

  1. A.contain: layout paint on the widget
  2. B.position: static on the widget
  3. C.overflow: visible on the body
  4. D.z-index: 9999 on the widget
Show answer

Answer: A. contain: layout paint on the widget

contain tells the browser that the element's insides do not affect outside layout or paint. Changes inside it can then be handled locally, which cuts style and layout cost on busy pages.

39. Smooth CSS animation

A front-end card animation stutters when it animates the CSS "left" property. Which change usually makes it smooth?

  1. A.Animate margin-left instead of left
  2. B.Animate transform: translate instead of left
  3. C.Animate width at the same time
  4. D.Wrap it in a table element
Show answer

Answer: B. Animate transform: translate instead of left

Changing left triggers layout and paint every frame. transform and opacity can be handled by the compositor on the GPU without re-layout, so they animate smoothly even when the main thread is busy. Use will-change sparingly, as layers use memory.

40. Focus styles only for keyboard users

A design team dislikes focus rings appearing on mouse clicks but must keep them for keyboard users. What CSS approach fits?

button:focus-visible {
  outline: 3px solid #1d4ed8;
  outline-offset: 2px;
}
  1. A.Style focus with :focus-visible
  2. B.Use outline: none on :focus
  3. C.Show focus only on :hover
  4. D.Use :active for focus styles
Show answer

Answer: A. Style focus with :focus-visible

:focus-visible lets browsers show focus styles when focus came from the keyboard or when it is otherwise helpful, and not after most mouse clicks. Focus must never simply be removed, as WCAG 2.4.7 requires it to be visible.

CSS interview questions for experienced candidates hard

41. z-index that does not work

A modal has position: fixed; z-index: 9999 but appears behind a header with z-index: 10. The modal is inside a parent with transform: translateZ(0) and z-index: 1. Why?

  1. A.position: fixed ignores z-index
  2. B.The parent creates a stacking context, so the modal is stacked inside the parent, which is below the header
  3. C.z-index values above 1000 are ignored
  4. D.The header must also use position: fixed
Show answer

Answer: B. The parent creates a stacking context, so the modal is stacked inside the parent, which is below the header

transform (and also opacity below 1, filter, or z-index on a positioned element) creates a new stacking context. Children can only be ordered within that context, so the whole parent layer, at z-index 1, sits below the header at 10. Rendering the modal in a portal near the body or using the native <dialog> top layer fixes it.

42. Ellipsis that never truncates in Flexbox

The .title has white-space: nowrap; overflow: hidden; text-overflow: ellipsis, but a long title pushes .main wider than the screen instead of truncating. What fixes it?

.layout { display: flex; }
.sidebar { width: 240px; flex-shrink: 0; }
.main { flex: 1; }
.main .title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  1. A.Add flex-wrap: wrap to .layout
  2. B.Set width: 100% on .title
  3. C.Add min-width: 0 to .main
  4. D.Replace flex: 1 with flex-grow: 2 on .main
Show answer

Answer: C. Add min-width: 0 to .main

Flex items default to min-width: auto, which means they refuse to shrink below the width of their content. The long nowrap title sets that minimum, so .main grows past the container and the ellipsis never kicks in. min-width: 0 (or overflow: hidden on .main) lets the item shrink, so the title can truncate.

43. Janky slide-in animation

A side drawer slides in by animating its left property from -300px to 0. It stutters on mid-range phones. What is the best change?

  1. A.Animate margin-left instead of left
  2. B.Run the animation with setInterval every 16ms instead of CSS
  3. C.Animate transform: translateX() instead, so it can run on the compositor without layout or paint
  4. D.Add will-change: left to the drawer
Show answer

Answer: C. Animate transform: translateX() instead, so it can run on the compositor without layout or paint

Changing left or margin triggers layout and paint on every frame, which is expensive on the main thread. transform and opacity can be handled by the compositor on the GPU, so the animation stays smooth even when JavaScript is busy. will-change does not help a property that still needs layout each frame.

44. Card layout based on its own width

The same ProductCard appears in a narrow sidebar and a wide main area on the same screen. It should switch to a horizontal layout when the card itself has at least 400px. What is the right tool?

  1. A.A @media (min-width: 400px) query inside the card styles
  2. B.JavaScript that reads window.innerWidth on resize
  3. C.The vw unit for all card dimensions
  4. D.container-type: inline-size on the card wrapper and an @container (min-width: 400px) rule
Show answer

Answer: D. container-type: inline-size on the card wrapper and an @container (min-width: 400px) rule

Media queries respond to the viewport, which is the same for both cards, so they cannot tell a narrow slot from a wide one. Container queries respond to the size of a chosen ancestor container, which makes the component adapt wherever it is placed. They are supported in all modern browsers.

45. Which label wins

What accessible name does a screen reader give this input?

<span id="x">Mobile number</span>
<label for="p">Phone</label>
<input id="p" aria-label="Contact" aria-labelledby="x">
  1. A.Phone
  2. B.Contact
  3. C.Mobile number
  4. D.Phone Contact Mobile number
Show answer

Answer: C. Mobile number

In the accessible name calculation, aria-labelledby comes first, then aria-label, then native labels like <label>, then title or placeholder. Mixing several is confusing; keep one clear label that matches the visible text.

46. Locking the page behind a drawer

A custom side drawer is open. What is the simplest way to stop Tab and screen readers from reaching the page behind it?

  1. A.Set tabindex="-1" on the body element
  2. B.Set pointer-events: none on the page
  3. C.Set z-index: 9999 on the drawer
  4. D.Set inert on the page content outside the drawer
Show answer

Answer: D. Set inert on the page content outside the drawer

The inert attribute makes an element and its subtree non-focusable, non-clickable and hidden from assistive technology. It is supported in all modern browsers. pointer-events only affects the mouse, and z-index only changes what is painted on top.

47. Minimum size of a tap target

WCAG 2.2 added a level AA rule for pointer target size. What is the minimum, unless enough spacing is given?

  1. A.16 by 16 CSS pixels
  2. B.44 by 44 CSS pixels
  3. C.48 by 48 device pixels
  4. D.24 by 24 CSS pixels
Show answer

Answer: D. 24 by 24 CSS pixels

Success criterion 2.5.8 Target Size (Minimum) asks for at least 24 × 24 CSS pixels, or enough space around smaller targets. 44 × 44 is the stricter AAA rule (2.5.5) and the size Apple recommends, which is still a good goal for main buttons.

48. Reordering with CSS order

A designer moved the "Buy" button visually above the price with order: -1 in a flex container. What accessibility issue does this cause?

  1. A.The button can no longer be clicked or tapped at all
  2. B.Tab and screen reader order still follow the DOM
  3. C.Screen readers skip elements that use order
  4. D.order changes the element’s role to presentation
Show answer

Answer: B. Tab and screen reader order still follow the DOM

Flexbox order and grid placement change only the visual position. Keyboard focus and screen readers still go through the DOM order, so what users see and what they hear no longer match. Change the HTML order when the meaning changes.

49. Relying on accept for uploads

A KYC upload uses <input type="file" accept=".pdf,.jpg">. Why is server-side checking still required?

  1. A.accept blocks every file larger than 1 MB
  2. B.accept only filters the picker; any file can still be sent
  3. C.accept is ignored on all mobile phones
  4. D.accept converts other files to PDF before upload
Show answer

Answer: B. accept only filters the picker; any file can still be sent

accept is a hint to the file picker. Users can choose "All files", and attackers can send any request directly. The server must check size, the real file type (magic bytes, not just the extension) and scan for malware.

50. When a MutationObserver fires

A script appends 100 list items in one loop while a MutationObserver watches the list. How is the callback called?

  1. A.100 times, synchronously during the loop itself
  2. B.Once per animation frame, 100 times
  3. C.Never, because append is not a mutation
  4. D.Once after the loop, with a batch of records
Show answer

Answer: D. Once after the loop, with a batch of records

MutationObserver queues records and delivers them in a microtask after the current script finishes, so the loop’s changes arrive together in one call. This makes it far cheaper than the old synchronous mutation events.

51. Child margin pushes the parent down

A hero section has a background colour. Its first child h1 has margin-top: 40px, but the gap appears above the coloured section instead of inside it. Why?

  1. A.h1 margins are always applied to the body
  2. B.Background colours do not cover margins of the element itself
  3. C.The child’s top margin collapses through the parent
  4. D.margin-top only works on inline elements
Show answer

Answer: C. The child’s top margin collapses through the parent

If a parent has no top padding, border or new formatting context, its first child’s top margin collapses with its own and shows outside it. Add padding-top, a border, or display: flow-root on the parent, or use padding on the child.

52. auto-fill versus auto-fit with few items

A 1200px grid uses repeat(auto-fill, minmax(200px, 1fr)) and has only 2 cards. What happens, and what would auto-fit do?

  1. A.auto-fill stretches the 2 cards; auto-fit keeps empty tracks
  2. B.auto-fill keeps empty tracks; auto-fit lets the 2 cards stretch
  3. C.Both stretch the 2 cards to 600px each
  4. D.Both make 6 columns and leave 4 empty
Show answer

Answer: B. auto-fill keeps empty tracks; auto-fit lets the 2 cards stretch

Both create as many 200px+ tracks as fit, here 6. auto-fill keeps the empty tracks, so the 2 cards stay about 200px wide. auto-fit collapses empty tracks to zero, so the 1fr columns grow and each card becomes about 600px.

53. height: 100% that does nothing

A sidebar has height: 100%, but it is only as tall as its content. Its parent has no height set. Why?

  1. A.height only accepts px values
  2. B.Percentage heights are relative to the width
  3. C.The sidebar must use display: inline
  4. D.A percentage height needs a parent with a definite height
Show answer

Answer: D. A percentage height needs a parent with a definite height

If the parent’s height depends on its content (height: auto), a percentage height on the child has nothing definite to resolve against and behaves like auto. Give the chain a definite height, or use flexbox or grid stretch, or min-height: 100dvh.

54. Order of values in gap

A grid has gap: 24px 8px. What does each value set?

  1. A.Column gap 24px and row gap 8px
  2. B.Outer gap 24px and inner gap 8px
  3. C.Horizontal padding 24px and vertical 8px
  4. D.Row gap 24px and column gap 8px
Show answer

Answer: D. Row gap 24px and column gap 8px

gap is shorthand for row-gap then column-gap. So 24px goes between rows (vertical space) and 8px between columns. With one value both are the same.

55. A view transition that is skipped

Every product card in a list has view-transition-name: product-image. Calling document.startViewTransition() now skips the animation. Why?

  1. A.View transitions need a duration in HTML
  2. B.Images cannot have a view-transition-name
  3. C.Each view-transition-name must be unique on the page
  4. D.startViewTransition only runs on page reload
Show answer

Answer: C. Each view-transition-name must be unique on the page

The View Transitions API pairs old and new elements by name, so two visible elements with the same name is an error and the transition is skipped. Give each card a unique name, or set the name only on the clicked card.

56. Buttons vanish in high contrast mode

In Windows High Contrast (forced colors) mode, buttons styled only with a background colour and no border look like plain text. What is the usual fix?

  1. A.Add !important to the button background colour
  2. B.Use a box-shadow as the only visible outline
  3. C.Turn off forced colours with JavaScript
  4. D.Add a transparent border, which that mode draws
Show answer

Answer: D. Add a transparent border, which that mode draws

Forced colors mode replaces author colours with the user’s system palette and removes box-shadows, so background-only buttons lose their shape. A transparent border costs nothing normally but is drawn in the system colour in that mode. Test with @media (forced-colors: active).

57. Page jumps when a modal opens

Opening a modal sets body { overflow: hidden }, and the whole page shifts sideways by the scrollbar width on Windows. Which property prevents the jump?

  1. A.scrollbar-gutter: stable on the scroller
  2. B.overflow: scroll on the modal element itself
  3. C.scrollbar-width: none on the body
  4. D.position: fixed on the page header
Show answer

Answer: A. scrollbar-gutter: stable on the scroller

When the scrollbar disappears, the content area gets wider and everything moves. scrollbar-gutter: stable keeps the space for the scrollbar reserved even when it is not shown, so the layout stays still.

58. Loading five font weights

A site loads Inter in weights 300, 400, 500, 600 and 700 as five files. What is usually the better option?

  1. A.One variable font file covering the weight range
  2. B.Five files, but each preloaded with fetchpriority high
  3. C.Faux bold from font-synthesis for all weights
  4. D.Converting the fonts to SVG images
Show answer

Answer: A. One variable font file covering the weight range

A variable font holds a continuous weight axis in a single file, so one request replaces five and any weight like 550 is possible. It is often smaller in total. Faux bold looks poor, and preloading many files competes with more important resources.

59. No Cache-Control header

A server returns a CSS file with Last-Modified ten days ago but no Cache-Control or Expires. What may a browser do?

  1. A.Never cache it and always download it again
  2. B.Cache it forever until the user clears site data
  3. C.Treat it as fresh for about 10% of its age
  4. D.Cache it for exactly 60 seconds in all browsers
Show answer

Answer: C. Treat it as fresh for about 10% of its age

Without explicit freshness, caches may use heuristic freshness, commonly 10% of the time since Last-Modified. Ten days gives about one day, so users can see stale CSS. Always send clear Cache-Control headers.

60. Wide data tables at 400% zoom

At 320 CSS pixels wide, a financial data table with 12 columns needs horizontal scrolling. Does that fail WCAG 1.4.10 Reflow?

  1. A.No, content needing 2D layout is exempt
  2. B.Yes, all content must fit 320 pixels
  3. C.Yes, unless it is an image
  4. D.No, tables are exempt from all WCAG rules
Show answer

Answer: A. No, content needing 2D layout is exempt

Reflow exempts content that requires two-dimensional layout for usage or meaning, such as data tables, maps and complex diagrams. The rest of the page must still reflow, and the table should scroll within its own container.

Ready to test yourself?

Take a 15-question CSS MCQ test with a score at the end, or practise the full CSS question bank and earn points on the leaderboard.