About This CSS Issue
Older builds of the validator reported at-rules like @keyframes and @font-face outside an @scope block in a <style> element in the <body>, but the HTML standard allows them there.
Since October 2026, a <style> element can sit in the <body> as long as its styles can't reach anything earlier in the page. Its style rules have to go inside an @scope block, and it can't use @import. An earlier draft of that change allowed only a few at-rules at the top level of the style sheet, such as @media, @supports and @layer. Builds of the Nu HTML Checker from late September and early October 2026 followed the draft and reported every other at-rule with this message.
The final rule lets at-rules that don't select elements stay outside @scope, at the top level or inside @media. That includes @keyframes, @font-face, @page and @counter-style. Current builds of the validator don't report them, so the code doesn't need to change: validate the page again and the error goes away. @import is still not allowed, and it now has a message of its own.
The names these at-rules define, such as an animation name or a font family, apply to the whole page. The HTML standard suggests using them only in the scoped rules of the same <style> element, and picking names that nothing else on the page uses. That way they can't restyle content the browser has already drawn.
Example
Older builds reported both at-rules in this <style> element. Current builds accept it, because the only style rule is inside @scope:
<div class="card">
<style>
@font-face {
font-family: "Card Sans";
src: url("card-sans.woff2") format("woff2");
}
@keyframes card-fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@scope {
p {
font-family: "Card Sans", sans-serif;
animation: card-fade-in 0.3s ease-in;
}
}
</style>
<p>Card content</p>
</div>
Find issues like this automatically
Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.