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?
- A.position: fixed ignores z-index
- B.The parent creates a stacking context, so the modal is stacked inside the parent, which is below the header
- C.z-index values above 1000 are ignored
- 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; }- A.Add flex-wrap: wrap to .layout
- B.Set width: 100% on .title
- C.Add min-width: 0 to .main
- 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?
- A.Animate margin-left instead of left
- B.Run the animation with setInterval every 16ms instead of CSS
- C.Animate transform: translateX() instead, so it can run on the compositor without layout or paint
- 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?
- A.A @media (min-width: 400px) query inside the card styles
- B.JavaScript that reads window.innerWidth on resize
- C.The vw unit for all card dimensions
- 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">
- A.Phone
- B.Contact
- C.Mobile number
- 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?
- A.Set tabindex="-1" on the body element
- B.Set pointer-events: none on the page
- C.Set z-index: 9999 on the drawer
- 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?
- A.16 by 16 CSS pixels
- B.44 by 44 CSS pixels
- C.48 by 48 device pixels
- 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?
- A.The button can no longer be clicked or tapped at all
- B.Tab and screen reader order still follow the DOM
- C.Screen readers skip elements that use order
- 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?
- A.accept blocks every file larger than 1 MB
- B.accept only filters the picker; any file can still be sent
- C.accept is ignored on all mobile phones
- 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?
- A.100 times, synchronously during the loop itself
- B.Once per animation frame, 100 times
- C.Never, because append is not a mutation
- 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?
- A.h1 margins are always applied to the body
- B.Background colours do not cover margins of the element itself
- C.The child’s top margin collapses through the parent
- 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?
- A.auto-fill stretches the 2 cards; auto-fit keeps empty tracks
- B.auto-fill keeps empty tracks; auto-fit lets the 2 cards stretch
- C.Both stretch the 2 cards to 600px each
- 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?
- A.height only accepts px values
- B.Percentage heights are relative to the width
- C.The sidebar must use display: inline
- 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?
- A.Column gap 24px and row gap 8px
- B.Outer gap 24px and inner gap 8px
- C.Horizontal padding 24px and vertical 8px
- 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?
- A.View transitions need a duration in HTML
- B.Images cannot have a view-transition-name
- C.Each view-transition-name must be unique on the page
- 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?
- A.Add !important to the button background colour
- B.Use a box-shadow as the only visible outline
- C.Turn off forced colours with JavaScript
- 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?
- A.scrollbar-gutter: stable on the scroller
- B.overflow: scroll on the modal element itself
- C.scrollbar-width: none on the body
- 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?
- A.One variable font file covering the weight range
- B.Five files, but each preloaded with fetchpriority high
- C.Faux bold from font-synthesis for all weights
- 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?
- A.Never cache it and always download it again
- B.Cache it forever until the user clears site data
- C.Treat it as fresh for about 10% of its age
- 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?
- A.No, content needing 2D layout is exempt
- B.Yes, all content must fit 320 pixels
- C.Yes, unless it is an image
- 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.