41. Old version after deploy with a service worker
Your service worker serves index.html with a stale-while-revalidate strategy. After a deploy, users see the old app on the first reload and the new one on the second. Why?
- A.The browser HTTP cache ignores service workers for HTML files
- B.The worker answers immediately from the cache and fetches the new HTML in the background to update the cache for next time
- C.stale-while-revalidate always waits for the network before responding
- D.Service workers can only update once every 24 hours
Show answer
Answer: B. The worker answers immediately from the cache and fetches the new HTML in the background to update the cache for next time
Stale-while-revalidate trades freshness for speed: it returns the cached copy at once and refreshes the cache in the background. That is great for avatars or non-critical data, but for the HTML shell it means one stale visit after each deploy. Use network-first for HTML or show an "update available" prompt when a new worker is waiting.
42. aria-hidden on a parent of a button
A whole off-screen cart drawer has aria-hidden="true", but its buttons can still be reached with Tab. What is the problem?
- A.aria-hidden makes the buttons unclickable for mouse users
- B.The drawer cannot be shown again later
- C.Users focus buttons that screen readers announce as nothing
- D.aria-hidden is not valid on div elements
Show answer
Answer: C. Users focus buttons that screen readers announce as nothing
aria-hidden removes content from the accessibility tree but does not stop keyboard focus. Screen reader users then land on silent, invisible controls. Use the inert attribute or display: none on closed drawers so their contents cannot be focused.
43. Focus after client-side navigation
In a single-page app, clicking a nav link swaps the content but keyboard focus stays on the old link and screen readers say nothing. What is the usual fix?
- A.Move focus to the new heading and update the title
- B.Reload the full page on every navigation
- C.Add aria-live="assertive" to the whole body element
- D.Blur the link so nothing has focus
Show answer
Answer: A. Move focus to the new heading and update the title
Full page loads reset focus and announce the new title, but client-side routing does not. Moving focus to the new h1 (with tabindex="-1") or main region and updating document.title tells users where they are. A live region over the whole page would be noisy.
44. Global CSS and a shadow root
A web component renders a <button> inside an open shadow root. The page stylesheet has button { background: red }. What happens?
- A.The button turns red like any other button
- B.The rule does not reach the button inside the shadow root
- C.The rule applies only if the component is in <body>
- D.The page stylesheet is copied into the shadow root
Show answer
Answer: B. The rule does not reach the button inside the shadow root
Shadow DOM scopes styles: page selectors do not match elements inside a shadow root, and the component’s styles do not leak out. Inherited properties like color and font still pass through, and custom properties and ::part() let the page theme it on purpose.
45. What is inside a template tag
A <template id="row"> holds a <tr> with an <img src="a.png">. What happens before you clone it?
- A.The row is shown at the end of the page
- B.The image downloads, but the row is hidden
- C.The browser throws because tr needs a table
- D.Nothing renders and the image is not fetched
Show answer
Answer: D. Nothing renders and the image is not fetched
Template content is parsed into an inert DocumentFragment: it is not rendered, images do not load and scripts do not run. You clone it with template.content.cloneNode(true) and insert the copy, which then behaves normally.
46. A field that stays invalid
A form shows "Passwords do not match" forever, even after the user fixes it. What is missing?
confirm.addEventListener("input", () => {
if (confirm.value !== pass.value) {
confirm.setCustomValidity("Passwords do not match")
}
})- A.A call to confirm.reportValidity() at load time
- B.The novalidate attribute on the form
- C.An else branch calling confirm.setCustomValidity("")
- D.A required attribute on the confirm field
Show answer
Answer: C. An else branch calling confirm.setCustomValidity("")
Any non-empty custom validity message keeps the field invalid. You must reset it with setCustomValidity("") when the value becomes valid. Otherwise the form will never submit.
47. A parent that ignores floated children
A container holds only floated images and collapses to zero height, so its border does not wrap them. What is the modern fix?
- A.height: auto on the container
- B.float: none on the container
- C.display: flow-root on the container
- D.position: relative on the container
Show answer
Answer: C. display: flow-root on the container
Floats are taken out of normal flow, so a parent that only has floats has no in-flow height. display: flow-root makes the parent a new block formatting context, which contains its floats, without the old clearfix hack.
48. What padding-top: 50% is based on
A box inside a 400px wide, 1000px tall container has padding-top: 50%. How tall is that padding?
- A.200px
- B.500px
- C.50% of the box’s own height
- D.0px, since percentage padding needs a fixed height
Show answer
Answer: A. 200px
Percentage padding and margin, even on top and bottom, are based on the containing block’s width. So 50% of 400px is 200px. This was the old trick for fixed aspect ratios, now replaced by the aspect-ratio property.
49. A fixed modal that scrolls away
A modal with position: fixed sits inside a wrapper with transform: translateX(0). The modal now scrolls with the page and is clipped. Why?
- A.position: fixed is not supported inside divs
- B.The transformed wrapper becomes its containing block
- C.transform turns every child into position: static instead
- D.The modal needs z-index above 1000
Show answer
Answer: B. The transformed wrapper becomes its containing block
An ancestor with transform, filter, perspective or certain contain values becomes the containing block for fixed descendants. The modal is then fixed to that wrapper, not the viewport. Render modals near the end of body (for example with a portal).
50. Aligning titles across cards
Cards in a grid each have a title, text and a button. Long titles make buttons sit at different heights across a row. Which CSS feature lines up the inner parts of every card?
- A.align-items: baseline on the grid
- B.height: 100% on every card
- C.grid-template-rows: subgrid on each card
- D.display: table-cell on each card
Show answer
Answer: C. grid-template-rows: subgrid on each card
With subgrid, a card that spans several rows of the parent grid uses those parent rows for its own children. Titles, text and buttons across cards then share the same row tracks and line up. Subgrid is supported in all modern browsers.
51. What dense packing does
A photo gallery uses grid-auto-flow: dense to fill holes left by wide images. What is the side effect?
- A.Images are resized to fit the holes
- B.Rows become fixed at 100px
- C.Items can appear out of their DOM order
- D.Wide images are skipped
Show answer
Answer: C. Items can appear out of their DOM order
dense lets the grid place later items into earlier gaps, so the visual order can differ from the source order. That is fine for a photo wall, but for content that is read or tabbed through it breaks the expected order.
52. Animating a gradient angle
A transition on --angle in background: conic-gradient(from var(--angle), ...) jumps instead of animating smoothly. What makes it animate?
- A.Add will-change: background to the element
- B.Use transition: all instead of naming --angle
- C.Write the angle values in radians, not degrees
- D.Register --angle with @property as an <angle>
Show answer
Answer: D. Register --angle with @property as an <angle>
Unregistered custom properties are just token strings, so the browser cannot interpolate them and flips at the midpoint. @property --angle { syntax: "<angle>"; inherits: false; initial-value: 0deg } gives it a type, so it can be transitioned and animated.
53. Centring an absolute box with auto margins
A 300×200 dialog box has position: absolute; inset: 0. What else centres it inside its positioned parent?
- A.text-align: center on the dialog
- B.width: 300px; height: 200px; margin: auto
- C.vertical-align: middle on the parent
- D.float: left; margin: 50%
Show answer
Answer: B. width: 300px; height: 200px; margin: auto
With all four insets set and a fixed width and height, the leftover space is shared by auto margins on both axes, centring the box. This is the classic way to centre an absolute element without transforms.
54. Arabic and English user comments
Comments on a UAE site can be in Arabic or English, and Arabic ones show punctuation in the wrong place. What fixes direction per comment?
- A.dir="rtl" on the whole page
- B.text-align: right on all comments
- C.unicode-bidi: normal on the body
- D.dir="auto" on each comment element
Show answer
Answer: D. dir="auto" on each comment element
dir="auto" makes the browser pick the direction from the first strong character in that element, so Arabic comments become RTL and English ones LTR. text-align only moves the text; it does not fix the order of punctuation and mixed words.
55. Percentages in left versus translate
A 200px wide tooltip inside a 1000px wide parent has position: absolute; left: 50%; transform: translateX(-50%). Where is its left edge?
- A.At 500px from the parent’s left edge
- B.At 400px from the parent’s left edge
- C.At 0px, because the two cancel out
- D.At 300px from the parent’s left edge
Show answer
Answer: B. At 400px from the parent’s left edge
left: 50% is relative to the containing block, so it places the left edge at 500px. translateX(-50%) is relative to the element’s own width, moving it back 100px. The edge ends at 400px and the tooltip is centred.
56. Visual order changed with CSS
A developer uses CSS order on a flex container to show the price above the product name, while the DOM has name, then description, then price. A screen reader reads them in DOM order. When does this become a WCAG 1.3.2 failure?
.card { display: flex; flex-direction: column; }
.price { order: -1; }- A.Whenever the CSS order property is used
- B.When the order change alters the meaning
- C.Only if the price is in a table
- D.Never, as screen readers ignore CSS
Show answer
Answer: B. When the order change alters the meaning
1.3.2 Meaningful Sequence fails only when the reading order differs in a way that changes meaning. Large differences between visual and DOM order also confuse keyboard users, so keeping the DOM in a logical order is the safest approach.
57. A live region added with its message
A script inserts <div aria-live="polite">Saved</div> into the page at the moment it wants the message read. Many screen readers stay silent. Why?
- A.Polite regions are never announced
- B.The region should already exist, then get the text
- C.The div must also be focusable
- D.The text must be longer than 10 characters
Show answer
Answer: B. The region should already exist, then get the text
Live regions are most reliable when the empty container is in the DOM before its content changes; screen readers then notice the update. Inserting a region and its text together is often missed, except with role="alert" in some browsers.
58. aria-label on a plain div
A developer puts aria-label="Product details" on a <div> with no role. What is the result?
- A.It becomes a region landmark
- B.It is read out as a heading
- C.It is not supported and often ignored
- D.It is read before every child
Show answer
Answer: C. It is not supported and often ignored
Generic elements like a plain <div> or <span> do not support naming, so aria-label is prohibited there and is often ignored. Give it a suitable role, such as region or group, or use a visible heading instead.
59. role="presentation" on a table
A developer adds role="presentation" to a <table> that holds a real data grid. What do screen reader users lose?
- A.Only the table's border styling
- B.Nothing, as tables ignore the role
- C.Table semantics such as headers
- D.Only the ability to tab to cells
Show answer
Answer: C. Table semantics such as headers
role="presentation" (or none) removes the element's implicit semantics, and for tables the row and cell structure too. Users can no longer navigate by cell or hear headers, so it suits only layout tables.
60. Making layout tables accessible
A screen reader reads your email as "table with 5 rows and 3 columns" again and again. What fixes this?
- A.Add role="presentation" to the layout tables
- B.Replace all text with images that have alt text
- C.Add a caption to every layout table
- D.Set the font size of every table to zero
Show answer
Answer: A. Add role="presentation" to the layout tables
role="presentation" tells assistive technology that the table is for layout, not data, so it reads the content without announcing rows and columns. Also set lang on the html element and use real text for headings.