RecallDeck

Interview track

Frontend Developer interview prep

A spaced-repetition deck of 121+ Frontend Developer interview questions — organised by topic and difficulty, and resurfaced right before you'd forget. Preview a few cards below, then sign in to study the whole track on an Anki-style SM-2 schedule.

121 cards9 topics

Free · sign in with GitHub · your progress stays yours.

What's covered

Every topic in this track, grouped the way you'd study it.

Behavioral

35 cards
Behavioral

HTML & CSS

12 cards
Html Css

JavaScript

14 cards
Javascript

TypeScript

10 cards
Typescript

React & Frameworks

14 cards
React

Browser & Performance

10 cards
Performance

Accessibility

8 cards
Accessibility

Tooling, Build & Testing

10 cards
Tooling

Frontend System Design

8 cards
System Design

Sample questions

A few cards from the deck — reveal each answer, then sign in to study the full set on a schedule.

What is semantic HTML and why does it matter (accessibility, SEO, maintainability)?

Short answer: Semantic HTML means using tags for their meaning (<nav>, <article>, <button>) instead of <div> for everything. Browsers and assistive tech understand the document structure, which buys you accessibility, SEO, and readable code.

In depth:

  1. Accessibility (a11y) — screen readers build the accessibility tree from tags: <nav>, <main>, <h1> enable landmark and heading navigation. Div soup is announced as unstructured text.
  2. SEO — search engines treat <article>, <h1><h6>, <time> as structure and content-importance signals.
  3. Maintainability<header>/<footer>/<aside> self-document the markup; you don't read class names to learn a block's role.
  4. Free behavior<button> is focusable and reacts to Enter/Space, <a> navigates, <details> toggles — no JS required.
<!-- ❌ div soup -->
<div class="nav"><div class="link" onclick="go()">Home</div></div>

<!-- ✅ semantic -->
<header>
  <nav aria-label="Primary">
    <a href="/">Home</a>
  </nav>
</header>
<main>
  <article>
    <h1>Article title</h1>
    <time datetime="2026-06-30">June 30, 2026</time>
  </article>
</main>

⚠️ Common mistake: making a clickable <div onclick> instead of a <button> — you lose focus, keyboard handling, and the screen-reader role.

Explain the CSS box model and how box-sizing: border-box changes sizing.

Short answer: Every element is nested layers: content → padding → border → margin. By default (content-box) width sizes only the content, and padding plus border are added on top. border-box makes padding and border fit inside the declared width.

In depth:

  1. content — the content area, which width/height refer to under content-box.
  2. padding — inner spacing, painted with the element's background.
  3. border — the frame between padding and margin.
  4. margin — outer spacing, transparent; adjacent vertical margins collapse (margin collapse).
┌──────────── margin ────────────┐
│  ┌───────── border ─────────┐  │
│  │  ┌────── padding ─────┐  │  │
│  │  │     content        │  │  │
│  │  └────────────────────┘  │  │
│  └──────────────────────────┘  │
└────────────────────────────────┘
/* content-box: actual width = 200 + 2*16 + 2*2 = 236px */
.a { box-sizing: content-box; width: 200px; padding: 16px; border: 2px solid; }

/* border-box: actual width is exactly 200px, padding/border inside */
.b { box-sizing: border-box; width: 200px; padding: 16px; border: 2px solid; }

/* common reset */
*, *::before, *::after { box-sizing: border-box; }

⚠️ Common mistake: setting width: 100% plus padding under content-box — the box overflows its container; border-box fixes it.

What's the difference between block, inline, and inline-block, and what is normal document flow?

Short answer: Block elements take the full line width and accept any size/spacing; inline elements sit within a line, sized by content, and ignore width/vertical margins; inline-block sits inline but with controllable sizing. Normal flow is the order in which elements lay out top-to-bottom (block) and left-to-right (inline) without positioning.

In depth:

  1. block (<div>, <p>, <section>) — starts a new line, defaults to full width, honors width/height and all margins/padding.
  2. inline (<span>, <a>, <strong>) — flows within text; width/height and vertical margins are ignored, horizontal ones apply.
  3. inline-block — sits inline like inline, but with full sizing and spacing — the classic for "buttons" in a row.
  4. Normal flow — the default layout; position, float, flex/grid take elements out of it.
display Line break width/height Vert. margin
block yes yes yes
inline no no no
inline-block no yes yes
.tag { display: inline-block; width: 80px; padding: 4px 8px; }

⚠️ Common mistake: setting width/height on a pure inline element and expecting an effect — they don't exist there; use inline-block or block.

What is hoisting, and how do var, let, and const differ in scope and TDZ?

Short answer: Hoisting is moving declarations to the top of their scope at compile time. var is hoisted and initialized to undefined (function scope), while let/const are hoisted but stay in the TDZ (temporal dead zone) until the declaration line and have block scope.

In depth:

  1. var — function scope, readable as undefined before declaration, re-declarable.
  2. let — block scope, in the TDZ until declaration, reassignment allowed.
  3. const — like let but no reassignment (the object's value itself is still mutable).
  4. TDZ — accessing a let/const before declaration throws ReferenceError instead of returning undefined.
console.log(a); // undefined — var hoisted
var a = 1;

console.log(b); // ReferenceError — b in TDZ
let b = 2;
Scope Before declaration Reassign
var function undefined yes
let block TDZ → error yes
const block TDZ → error no

⚠️ Common mistake: believing let/const "aren't hoisted." They are — but accessing them before initialization throws because of the TDZ.

What's the difference between == and ===? Explain type coercion, truthy/falsy, and common gotchas.

Short answer: === compares without coercion (strict equality), == first coerces operands to a common type (loose). Because coercions are unpredictable, code almost always uses ===. Eight values are falsy; everything else is truthy.

In depth:

  1. === — equal only if both type and value match.
  2. == — coerces types by intricate rules (number ↔ string, to-primitive, etc.).
  3. Falsy — exactly eight: false, 0, -0, 0n, '', null, undefined, NaN. Everything else is truthy.
Expression Result Why
0 == '' true both → number 0
0 == '0' true '0'0
null == undefined true special rule
null == 0 false null equals only undefined
NaN === NaN false NaN equals nothing
[] == ![] true ![]false0, []''0

⚠️ Common mistake: seeing if (x == null) and assuming it's a bug. It's actually an idiom — it catches both null and undefined. It's == with numbers and strings that breeds bugs; use ===.

Why use TypeScript over JavaScript, and what is structural (duck) typing?

Short answer: TypeScript adds static type checking on top of JS: errors are caught in the editor and at build time instead of at runtime. Its typing is structural — compatibility is decided by an object's shape (its set of fields), not by the type's name or an explicit implements.

In depth:

  1. What TS buys you — autocompletion and navigation, safe refactoring, self-documenting contracts, catching typos and undefined before running.
  2. Structural vs nominal — in Java/C# types match by name (nominal typing). In TS, if an object has the required fields it fits, even if it was created with no knowledge of the target type.
  3. Type erasure — types exist only at compile time; at runtime it is plain JS. You can't instanceof-check an interface.
interface Point { x: number; y: number }

function len(p: Point): number {
  return Math.hypot(p.x, p.y);
}

// the object never declared implements Point, but its shape fits
const v = { x: 3, y: 4, label: "v" };
len(v); // OK — structural typing: the extra label field is fine

⚠️ Common mistake: assuming TS protects you at runtime. Data from an API must be validated (zod, etc.) — the compiler takes your annotations on faith.

Ready to make it stick?

Start your first session in under a minute. Your future self, mid-interview, will thank you.

Other interview tracks

RecallDeckSpaced-repetition interview prep