no-font-face-in-media-query
Disallow @font-face blocks nested inside @media, @supports, or @container at-rules.
Rule catalog ID: R025
Targeted pattern scopeโ
@font-faceblocks whose parent chain contains a@media,@supports, or@containerconditional at-rule.
What this rule reportsโ
- Any
@font-facedeclaration block found nested inside a@media,@supports, or@containerrule.
Why this rule existsโ
The CSS Fonts specification technically allows @font-face inside conditional at-rules, but browser behavior for when the font file is downloaded varies across implementations:
- Firefox: Downloads the font only when the media condition is matched.
- Chrome/Safari (historical): Some versions downloaded the font regardless of the media condition when the
@font-facewas encountered during parse. - Result: In some browser/version combinations a font declared only inside
@media printis downloaded on every page load, defeating the purpose of the condition.
This inconsistency makes nested @font-face unreliable for conditional loading strategies. For print vs screen distinctions, prefer using unicode-range and separate family names, or use JavaScript-based font loading via the CSS Font Loading API.
The rule is set to recommended: false because there are legitimate historical patterns (especially legacy print stylesheet integration) where nesting is intentional and accepted.
โ Incorrectโ
/* @font-face inside @media โ download behavior is inconsistent across browsers */
@media screen {
@font-face {
font-family: "Inter";
src: url("./inter.woff2") format("woff2");
}
}
@supports (font-variation-settings: normal) {
@font-face {
font-family: "InterVar";
src: url("./inter-variable.woff2") format("woff2");
}
}
โ Correctโ
/* Top-level @font-face โ reliable and spec-aligned */
@font-face {
font-family: "Inter";
src: url("./inter.woff2") format("woff2");
}
/* Conditional font behavior via unicode-range and separate family names */
@font-face {
font-family: "InterPrint";
src: url("./inter-print.woff2") format("woff2");
}
When not to use itโ
- Legacy print stylesheets that intentionally scope print-only
@font-facedeclarations inside@media print. - Codebases that rely on browser-specific behavior for conditional font loading.
Disable the rule with an inline comment in those files:
/* stylelint-disable font/no-font-face-in-media-query */
@media print {
@font-face {
font-family: "PrintFont";
src: url("./print-font.woff2") format("woff2");
}
}
/* stylelint-enable font/no-font-face-in-media-query */