This page covers 28 front-end developer interview questions about the browser platform itself: semantic HTML and accessibility, modern CSS layout, Core Web Vitals, rendering performance, bundling and caching, and front-end security such as XSS and Content Security Policy. Framework questions are on our React page and language questions on our JavaScript page. When Ryz evaluates senior front-end engineers, recruiters source people with shipped interfaces behind them, candidates complete structured NTRVSTA AI interviews on platform knowledge and debugging, and recruiters review results before and after. AI scores are advisory. People make the call.
Front-end interviews often turn into framework quizzes, and then teams hire people who cannot build an accessible dialog or explain a slow page. These questions test what stays true whatever framework you use. Mid-level candidates should handle Fundamentals and Intermediate. Senior candidates should be comfortable diagnosing Core Web Vitals from real data and designing security headers.
Ask for specifics: which DevTools panel, which metric, which WCAG criterion. Combine the conversation with a hands-on task on a real page, since accessibility and layout problems are much easier to spot when someone has to fix them.
<div class="btn" onclick="save()">Save</div>
It cannot be reached with Tab, does not respond to Enter or Space, and screen readers do not announce it as a button. Use <button type="button">, which provides focus, keyboard activation and the right role for free. Rebuilding that with role, tabindex and key handlers is more code and easier to get wrong.
What a strong answer shows: They reach for native elements first and know the first rule of ARIA: do not use it when a native element does the job.
Origin and importance come first, then cascade layers, then specificity, then source order. Layers let you order whole groups of styles explicitly, so a utility class can beat a component style without a specificity fight.
@layer reset, base, components, utilities;
@layer components {
.card .title { color: var(--text-strong); }
}
@layer utilities {
.text-muted { color: var(--text-muted); } /* wins despite lower specificity */
}
What a strong answer shows: They know unlayered styles beat layered ones for normal declarations, which matters when importing third-party CSS.
Flex items default to min-width: auto, so they will not shrink below their content's minimum size, and an unbroken URL is wide. Set min-width: 0 on the item and allow wrapping with overflow-wrap: anywhere. In Grid, 1fr has the same auto minimum, so use minmax(0, 1fr).
What a strong answer shows: They know this from debugging rather than guesswork, and check it in the DevTools layout panel.
Flexbox lays out items along one axis and sizes them from their content, which suits toolbars, nav bars and rows of tags. Grid controls rows and columns together from the container, which suits page layouts, card galleries and forms where items must line up. subgrid lets nested items align to the parent grid.
What a strong answer shows: They use gap instead of margins for spacing and can build a responsive card grid with repeat(auto-fill, minmax(16rem, 1fr)) without media queries.
<img
src="/img/hero-800.avif"
srcset="/img/hero-400.avif 400w, /img/hero-800.avif 800w, /img/hero-1600.avif 1600w"
sizes="(min-width: 64rem) 50vw, 100vw"
width="1600" height="900"
alt="Dashboard showing weekly revenue by region"
fetchpriority="high">
srcset and sizes let the browser choose the right file, width and height reserve space to prevent layout shift, and modern formats cut bytes. Lazy-load images below the fold, but never the main hero image.
What a strong answer shows: They write useful alt text, or an empty alt for decorative images.
The browser needs the HTML, then CSS in the head to build the CSSOM before painting. Classic <script> tags without defer or async block HTML parsing. Fixes: defer scripts, inline or prioritize critical CSS, preload key fonts and images, and reduce redirects and server response time.
What a strong answer shows: They know defer preserves order and runs after parsing, while async runs whenever the script arrives.
Session tokens belong in HttpOnly, Secure, SameSite cookies, where JavaScript cannot read them. localStorage is synchronous, string-only and readable by any script on the origin, so it suits small non-sensitive preferences. IndexedDB suits larger structured data and offline caches.
What a strong answer shows: They explain that any XSS can read localStorage, which is why tokens do not go there.
Media queries respond to the viewport. A component placed in a narrow sidebar on a wide screen still gets the wide layout. Container queries respond to the size of a containing element, so components adapt to wherever they are placed.
.product-list { container-type: inline-size; }
@container (min-width: 30rem) {
.product-card { display: grid; grid-template-columns: 10rem 1fr; }
}
What a strong answer shows: They see container queries as the tool for reusable components and still use media queries for page-level layout and user preferences.
Use the native <dialog> element with showModal(), which gives a top-layer element, makes the rest of the page inert, and closes on Escape. Give it an accessible name with aria-labelledby, move focus into it on open, and return focus to the triggering element on close. Prevent background scroll.
What a strong answer shows: They test with a keyboard and screen reader, and know the native element replaced most hand-rolled focus traps.
Every input has a visible <label>. Errors are text, not only red borders, linked to the field with aria-describedby, and the field gets aria-invalid="true". On submit, move focus to the first invalid field or an error summary. Use correct type and autocomplete attributes so browsers and password managers help.
What a strong answer shows: They do not rely on color alone and avoid placeholder text as the only label.
Automated checks with axe in CI and component tests catch some issues, such as missing labels and contrast. The rest needs manual work: keyboard-only navigation, a screen reader (VoiceOver, NVDA), 200 percent zoom and reflow at narrow widths, and reduced motion settings. Target WCAG 2.2 AA.
What a strong answer shows: They know automated tools catch only part of the problems and name WCAG 2.2 additions such as focus not obscured and minimum target size.
The browser blocks the page from reading a cross-origin response unless the server allows it with Access-Control-Allow-Origin. Non-simple requests, such as JSON bodies or custom headers, first send an OPTIONS preflight. The fix is server configuration: allow the specific origin, methods and headers, and Access-Control-Allow-Credentials if cookies are sent, which forbids a wildcard origin.
What a strong answer shows: They know CORS protects users, not servers, and that a proxy in development hides the problem rather than fixing it.
Fingerprinted assets such as app.3f9a1c.js get Cache-Control: public, max-age=31536000, immutable. The HTML entry point gets no-cache so browsers revalidate and pick up new asset names on deploy. Keep old assets available for a while so users with an open tab can still load lazy chunks.
What a strong answer shows: They have handled "chunk failed to load" errors after a deploy and know why they happen.
Use font-display: swap or optional, self-host and subset fonts to the characters you need, preload the one or two critical files, and serve WOFF2. Reduce the shift with a fallback font tuned through size-adjust and the ascent and descent overrides in @font-face.
What a strong answer shows: They question how many font weights the design really needs.
Largest Contentful Paint (good at 2.5 seconds or less), Interaction to Next Paint (200 milliseconds or less), which replaced First Input Delay in 2024, and Cumulative Layout Shift (0.1 or less). They are assessed at the 75th percentile of real user visits, as reported in the Chrome UX Report.
What a strong answer shows: They distinguish field data from lab tools like Lighthouse, and fix based on field data.
Identify the LCP element, usually the hero image, then break LCP into its parts: server response time, resource load delay, resource load time and render delay. Typical fixes: make the image discoverable in the initial HTML instead of injected by JavaScript, add fetchpriority="high", remove lazy loading from it, serve a properly sized modern format, cache HTML at the CDN, and cut render-blocking CSS and scripts.
What a strong answer shows: They use the LCP breakdown to find which phase is slow instead of applying every tip at once.
Use field data with attribution (for example the web-vitals library) to find which interactions and elements are slow, then reproduce with the Performance panel. Causes are long tasks in event handlers, heavy re-rendering, and third-party scripts on the main thread. Do the minimal visual update first, then yield to the main thread before the remaining work, break up long tasks, and move heavy computation to a Web Worker.
What a strong answer shows: They understand that INP covers input delay, processing time and presentation delay, and that yielding matters as much as raw speed.
Reserve space before content loads with width and height or aspect-ratio, give ad slots a minimum height, insert dynamic banners only in response to user input or below the viewport, and animate with transform rather than properties that move other content.
What a strong answer shows: They can find the shifting elements with the Layout Shift regions view or Performance panel.
// Forces a synchronous layout on every iteration
for (const el of cards) {
el.style.height = `${el.offsetWidth * 0.75}px`;
}
// Read everything, then write everything
const widths = cards.map((el) => el.offsetWidth);
cards.forEach((el, i) => { el.style.height = `${widths[i] * 0.75}px`; });
Reading a layout property after a style write forces the browser to recalculate layout immediately. Interleaving reads and writes repeats that for every element. Batching reads before writes lets layout run once. Here, CSS aspect-ratio would remove the JavaScript entirely.
What a strong answer shows: They know which properties trigger layout, paint or only compositing, and animate transform and opacity.
Analyze it with a bundle visualizer to find the biggest modules and duplicates. Split by route and lazy-load heavy, rarely used features with dynamic import(). Replace large dependencies with lighter ones or platform APIs, check that packages are tree-shakable and declare sideEffects correctly, and add a size budget to CI so it cannot drift again.
What a strong answer shows: They measure compressed size and parse cost on a mid-range phone, not only file size on disk.
Reduce the DOM: render only what is visible with virtualization, paginate, or simplify markup. content-visibility: auto with contain-intrinsic-size lets the browser skip rendering work for off-screen sections. Avoid expensive selectors and large paint areas.
What a strong answer shows: They know virtualization has accessibility and find-in-page costs, and when content-visibility is the simpler fix.
Frameworks escape text by default, so XSS usually enters through escape hatches: innerHTML, dangerouslySetInnerHTML or v-html with user content, javascript: URLs in links, unsafe Markdown rendering, and third-party scripts. Sanitize HTML with DOMPurify, validate URL schemes, and enforce it with Trusted Types and a strict CSP.
What a strong answer shows: They review the escape hatches in a codebase first and treat CSP as defense in depth, not the only defense.
Content-Security-Policy-Report-Only:
script-src 'nonce-{random-per-response}' 'strict-dynamic';
object-src 'none'; base-uri 'none'; frame-ancestors 'self';
report-to csp-reports
Start in report-only mode, collect violations, and remove inline scripts and event handler attributes or give them nonces. A nonce-based policy with 'strict-dynamic' is easier to maintain than long host allowlists. Switch to enforcing once reports are clean, and add require-trusted-types-for 'script' later.
What a strong answer shows: They generate a new nonce per response and know that caching HTML with a fixed nonce defeats it.
SameSite=Lax or Strict cookies block most cross-site requests. Add anti-CSRF tokens or check the Origin header for state-changing requests, never change state on GET, and keep cookies HttpOnly and Secure.
What a strong answer shows: They know SameSite treats subdomains as same-site, so a compromised subdomain still matters.
Static generation suits content that changes rarely, such as marketing pages and docs. Server rendering with streaming suits personalized pages that need fast first paint and SEO. Client rendering suits authenticated dashboards behind a login. Islands architecture fits mostly static pages with a few interactive parts.
What a strong answer shows: They decide per route and weigh hosting cost, caching and team skills, not trends.
Define tokens as CSS custom properties in layers: raw palette values, then semantic tokens such as --surface and --text-muted that components use. Switch themes by redefining semantic tokens under prefers-color-scheme or a data attribute. Respect prefers-reduced-motion and check contrast in both themes.
What a strong answer shows: Components that never reference raw colors, so a theme change touches one file.
Measure the current cost of third parties on INP and LCP, set a performance budget, and load scripts with async or after user interaction. Use facades for heavy embeds such as chat widgets and video players, review what each script can access, and remove tags that are no longer used.
What a strong answer shows: They negotiate with data instead of refusing, and consider privacy and security as well as speed.
Real user monitoring of Core Web Vitals segmented by page, device and country, JavaScript error tracking with uploaded source maps, and release markers so regressions link to deploys. In CI, run Lighthouse or WebPageTest on key pages with budgets that fail the build.
What a strong answer shows: They keep source maps private and connect metrics to business pages that matter.
divs and adds ARIA to compensate.!important as the main way to win specificity battles.localStorage and calls it fine because the app is a single-page app.Give a 3-hour take-home on a prepared static product page with seeded problems: a hero image loaded through JavaScript, a cookie banner that shifts content, a custom dropdown built from divs, an inaccessible signup form, a layout that breaks at 320 pixels wide, and a long task in a "filter" click handler. Ask the candidate to fix the most important issues and write a short report with before and after measurements of LCP, CLS and INP from DevTools, plus axe results.
Ryz places front-end engineers who build fast, accessible interfaces as a matter of course. Hire senior front-end developers from the top 1% of the candidates we interview, working on your team and repos, within ±1h of US time zones. Read about our vetting process or start from our front-end developer job description.
A front-end interview tests the platform every framework renders into: HTML semantics, CSS, accessibility, performance and browser security. A React interview tests component and state design. Many roles need both, and weak platform skills show up in production as slow, inaccessible pages.
Yes, with a practical check such as building a form or dialog and using it by keyboard. Accessibility is part of front-end quality, and in many industries it is a legal requirement as well.
About six, mixing one each from CSS, accessibility, performance and security, plus time for follow-ups. Pair it with a short live task on a real page, such as fixing a layout or a keyboard trap.
Questions we didn't answer? Email info@ryzlabs.com.