<main class="page">
<article class="answer" aria-labelledby="answer-title">
<header class="answer-head">
<div class="answer-meta">
<span class="answer-badge">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M10 4Q10 12 18 12Q10 12 10 20Q10 12 2 12Q10 12 10 4Z"></path>
<path d="M19 2Q19 5.5 22.5 5.5Q19 5.5 19 9Q19 5.5 15.5 5.5Q19 5.5 19 2Z"></path>
</svg>
Grounded answer
</span>
<span class="answer-verified">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 12l2 2 4-4M22 12a10 10 0 1 1-20 0 10 10 0 0 1 20 0Z"></path></svg>
3 sources verified
</span>
</div>
<h1 class="answer-title" id="answer-title">How do browser HTTP caches validate a stale response?</h1>
</header>
<p class="answer-p">
When a cached response passes its <code>max-age</code> window, the browser does not have to download the whole file again
<span class="cite cite-1">
<a class="cite-pill" href="#source-1" aria-describedby="card-1"><span class="sr-only">Source </span>1</a>
<span class="cite-card" id="card-1" role="tooltip">
<span class="card-top">
<span class="card-ico" data-site="rfc">R</span>
<span class="card-domain">rfc-editor.org</span>
<span class="card-meta">RFC 9111</span>
</span>
<strong class="card-title">HTTP Caching: Section 4.3 Validation</strong>
<span class="card-summary">A cache that cannot serve a stored response, for example because it is stale, can send a conditional request so the next server can confirm or replace it.</span>
</span>
</span>.
Instead, it sends a conditional request with <code>If-None-Match</code> or <code>If-Modified-Since</code>, carrying the stored <code>ETag</code> or <code>Last-Modified</code> date
<span class="cite cite-2">
<a class="cite-pill" href="#source-2" aria-describedby="card-2"><span class="sr-only">Source </span>2</a>
<span class="cite-card cite-card-end" id="card-2" role="tooltip">
<span class="card-top">
<span class="card-ico" data-site="mdn">M</span>
<span class="card-domain">developer.mozilla.org</span>
<span class="card-meta">HTTP guides</span>
</span>
<strong class="card-title">HTTP conditional requests</strong>
<span class="card-summary">Once a cached response is stale, the client sends its validator in If-None-Match or If-Modified-Since and gets 304 Not Modified if nothing changed.</span>
</span>
</span>.
</p>
<p class="answer-p">
When the file has not changed, the origin server returns <code>304 Not Modified</code>
<span class="cite cite-3">
<a class="cite-pill" href="#source-3" aria-describedby="card-3"><span class="sr-only">Source </span>3</a>
<span class="cite-card cite-card-end" id="card-3" role="tooltip">
<span class="card-top">
<span class="card-ico" data-site="web">W</span>
<span class="card-domain">web.dev</span>
<span class="card-meta">Article</span>
</span>
<strong class="card-title">Prevent unnecessary network requests with the HTTP Cache</strong>
<span class="card-summary">When the validators match, the server answers 304 Not Modified with headers that say how much longer the file can be cached.</span>
</span>
</span>
with no body, and the browser keeps using its cached copy for as long as the new caching headers allow.
</p>
<footer class="sources-wrap" aria-labelledby="sources-title">
<h2 class="sources-title" id="sources-title">Cited sources</h2>
<ol class="sources">
<li class="source source-1" id="source-1">
<span class="source-ico" data-site="rfc">1</span>
<div class="source-body">
<a class="source-link" href="https://www.rfc-editor.org/rfc/rfc9111.html#section-4.3" target="_blank" rel="noopener">HTTP Caching: Section 4.3 Validation</a>
<span class="source-host">rfc-editor.org · RFC 9111</span>
</div>
</li>
<li class="source source-2" id="source-2">
<span class="source-ico" data-site="mdn">2</span>
<div class="source-body">
<a class="source-link" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Conditional_requests" target="_blank" rel="noopener">HTTP conditional requests</a>
<span class="source-host">developer.mozilla.org · HTTP guides</span>
</div>
</li>
<li class="source source-3" id="source-3">
<span class="source-ico" data-site="web">3</span>
<div class="source-body">
<a class="source-link" href="https://web.dev/articles/http-cache" target="_blank" rel="noopener">Prevent unnecessary network requests with the HTTP Cache</a>
<span class="source-host">web.dev · Article</span>
</div>
</li>
</ol>
</footer>
</article>
</main>*, *::before, *::after {
box-sizing: border-box;
}
:root {
--page: #f1f5f9;
--card: #ffffff;
--text: #0f172a;
--muted: #64748b;
--soft: #f1f5f9;
--accent: #2563eb;
--accent-soft: #eff6ff;
--accent-text: #1d4ed8;
--popup: #0f172a;
--popup-text: #f8fafc;
--popup-muted: #94a3b8;
}
body {
font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
margin: 0;
background: var(--page);
color: var(--text);
}
.page {
display: grid;
grid-template-columns: minmax(0, 620px);
justify-content: center;
align-content: center;
min-height: 100vh;
padding: 20px 16px;
}
.answer {
position: relative;
padding: 26px 28px;
border-radius: 22px;
background: var(--card);
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 18px 40px -14px rgba(15, 23, 42, 0.14);
}
.answer-head {
margin-bottom: 14px;
}
.answer-meta {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
margin-bottom: 8px;
}
.answer-badge {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 10px;
border-radius: 999px;
background: var(--accent-soft);
color: var(--accent-text);
font-size: 0.75rem;
font-weight: 600;
}
.answer-badge svg {
width: 14px;
height: 14px;
fill: currentColor;
}
.answer-verified {
display: inline-flex;
align-items: center;
gap: 5px;
font-size: 0.75rem;
font-weight: 500;
color: var(--muted);
}
.answer-verified svg {
width: 14px;
height: 14px;
fill: none;
stroke: #16a34a;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
}
.answer-title {
margin: 0;
font-size: 1.15rem;
letter-spacing: -0.015em;
line-height: 1.35;
}
.answer-p {
margin: 0 0 12px;
line-height: 1.7;
}
.answer-p code {
padding: 2px 6px;
border-radius: 6px;
background: var(--soft);
font-family: ui-monospace, Consolas, monospace;
font-size: 0.84em;
}
.cite {
position: relative;
display: inline-block;
vertical-align: baseline;
}
.cite-pill {
display: inline-grid;
place-items: center;
min-width: 20px;
height: 20px;
padding: 0 6px;
border-radius: 999px;
background: var(--accent-soft);
color: var(--accent-text);
font-size: 0.75rem;
font-weight: 700;
font-variant-numeric: tabular-nums;
line-height: 1;
text-decoration: none;
transition: background 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
.cite:hover .cite-pill,
.cite:focus-within .cite-pill,
.answer:not(:hover):not(:focus-within) .cite-1 .cite-pill {
background: var(--accent);
color: #ffffff;
transform: translateY(-1px);
}
.cite-pill:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
.cite-card {
position: absolute;
top: calc(100% + 10px);
left: 0;
z-index: 20;
display: grid;
gap: 6px;
width: 304px;
padding: 14px 16px;
border-radius: 16px;
background: var(--popup);
color: var(--popup-text);
box-shadow: 0 22px 44px -12px rgba(15, 23, 42, 0.45);
font-size: 0.8125rem;
line-height: 1.45;
opacity: 0;
visibility: hidden;
transform: translateY(4px);
pointer-events: none;
transition: opacity 0.16s ease, transform 0.16s ease, visibility 0.16s ease;
}
.cite-card-end {
right: 0;
left: auto;
}
.cite-card::before {
content: "";
position: absolute;
top: -12px;
right: 0;
left: 0;
height: 12px;
}
.cite:hover .cite-card,
.cite:focus-within .cite-card,
.answer:not(:hover):not(:focus-within) .cite-1 .cite-card {
opacity: 1;
visibility: visible;
transform: translateY(0);
}
.cite:hover .cite-card,
.cite:focus-within .cite-card {
pointer-events: auto;
}
.card-top {
display: flex;
align-items: center;
gap: 8px;
font-size: 0.75rem;
}
.card-ico,
.source-ico {
display: inline-grid;
place-items: center;
flex-shrink: 0;
width: 20px;
height: 20px;
border-radius: 6px;
background: #2563eb;
color: #ffffff;
font-size: 0.6875rem;
font-weight: 700;
}
.card-ico[data-site="mdn"],
.source-ico[data-site="mdn"] {
background: #7c3aed;
}
.card-ico[data-site="web"],
.source-ico[data-site="web"] {
background: #059669;
}
.card-domain {
font-weight: 600;
color: #ffffff;
}
.card-meta {
margin-left: auto;
padding: 2px 7px;
border-radius: 6px;
background: rgba(255, 255, 255, 0.1);
color: var(--popup-muted);
font-family: ui-monospace, Consolas, monospace;
font-size: 0.6875rem;
}
.card-title {
margin-top: 2px;
font-size: 0.875rem;
font-weight: 600;
color: #ffffff;
}
.card-summary {
padding-left: 10px;
border-left: 2px solid #60a5fa;
color: #cbd5e1;
font-size: 0.775rem;
}
.sources-wrap {
margin-top: 18px;
padding-top: 14px;
border-top: 1px solid var(--soft);
}
.sources-title {
margin: 0 0 8px;
font-size: 0.6875rem;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--muted);
}
.sources {
display: grid;
gap: 4px;
margin: 0;
padding: 0;
list-style: none;
}
.source {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 10px;
border-radius: 12px;
background: transparent;
font-size: 0.8125rem;
transition: background 0.15s ease;
}
.source-ico {
width: 22px;
height: 22px;
border-radius: 7px;
}
.source-body {
display: flex;
flex-wrap: wrap;
align-items: baseline;
justify-content: space-between;
gap: 4px 10px;
min-width: 0;
flex: 1;
}
.source-link {
font-weight: 600;
color: var(--text);
text-decoration: none;
}
.source-link:hover {
color: var(--accent-text);
}
.source-link:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
border-radius: 4px;
}
.source-host {
font-size: 0.75rem;
color: var(--muted);
}
.source:target,
.answer:has(.cite-1:hover, .cite-1:focus-within) .source-1,
.answer:has(.cite-2:hover, .cite-2:focus-within) .source-2,
.answer:has(.cite-3:hover, .cite-3:focus-within) .source-3,
.answer:not(:hover):not(:focus-within) .source-1 {
background: var(--accent-soft);
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
}
@media (max-width: 560px) {
.answer {
padding: 20px 18px;
}
.cite {
position: static;
}
.cite-card,
.cite-card-end {
top: auto;
right: 16px;
left: 16px;
width: auto;
margin-top: 8px;
}
}
@media (pointer: coarse) {
.cite-pill {
position: relative;
}
.cite-pill::before {
content: "";
position: absolute;
inset: -12px;
}
.source-link {
display: inline-flex;
align-items: center;
min-height: 44px;
}
}
@media (prefers-color-scheme: dark) {
:root {
--page: #0b1120;
--card: #151e30;
--text: #f1f5f9;
--muted: #94a3b8;
--soft: #1e293b;
--accent: #3b82f6;
--accent-soft: #172554;
--accent-text: #93c5fd;
--popup: #090d16;
}
}
@media (forced-colors: active) {
.cite-pill,
.cite-card,
.source {
border: 1px solid CanvasText;
}
}
@media (prefers-reduced-motion: reduce) {
.cite-pill,
.cite-card,
.source {
transition: none;
}
}Click any element to find its code Esc
Check this code before you run it
It came from a shared link. It runs with fewer permissions, so it cannot open pop-ups, submit forms or start downloads.
element.animate() call shows up here as it plays.