Skip to content

font_family_without_font_face lint check fails to match @font-face declarations in complex/large CSS blocks #1534

@Johnson-Jia

Description

@Johnson-Jia

Summary

The font_family_without_font_face lint checker (strengthened to error severity in 0.6.109) correctly identifies @font-face declarations in simple HTML but fails to match them in complex HTML with large CSS blocks (>100 lines, multiple @keyframes, full CSS framework). This produces false-positive errors that block rendering.

In 0.6.107 and earlier, this was a warning (non-blocking), so the issue was masked.

Version

  • HyperFrames: 0.6.109
  • Node: v24.11.1
  • OS: Windows 10

Reproduction

✅ Simple HTML — passes (0 errors)

<!DOCTYPE html>
<html><head><style>
@font-face { font-family: 'Noto Sans SC'; font-weight: 400;
  src: url('file:///C:/Users/example/cache/noto-sans-sc/400-normal.woff2') format('woff2'); }
.title { font-family: 'Noto Sans SC'; }
</style></head><body>
<div data-composition-id="t" data-width="1080" data-height="1920" data-start="0" data-duration="1">
<div class="clip" data-start="0" data-duration="1"><h1 class="title">Test</h1></div>
</div>
<script>window.__hf={duration:1,seek:function(t){}};window.__timelines={};</script>
</body></html>

Result: 0 error(s), 1 warning(s)@font-face correctly matched ✅

❌ Complex HTML — fails (false-positive error)

Same @font-face declaration, but <style> block contains ~200 lines of additional CSS (base reset, layout classes, 10+ @keyframes, component styles):

<style>
@font-face { font-family: 'Noto Sans SC'; font-weight: 400; src: url('...') format('woff2'); }
@font-face { font-family: 'Noto Sans SC'; font-weight: 700; src: url('...') format('woff2'); }
@font-face { font-family: 'JetBrains Mono'; font-weight: 700; src: url('...') format('woff2'); }
@keyframes fxAura { 0%,100%{opacity:.45} 50%{opacity:.8} }
@keyframes fxRingExp { 0%,100%{opacity:.3} 50%{opacity:.65} }
/* ... 8 more @keyframes ... */
*{margin:0;padding:0;box-sizing:border-box}
.clip{position:absolute;top:0;left:0;width:1080px;height:1920px}
.layer-content{position:relative;z-index:3;height:100%;color:#fff;font-size:48px}
.phase{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;flex-direction:column}
/* ... 50+ more component class rules ... */
.ct-title { font-family: 'Noto Sans SC'; font-weight: 900; font-size: 88px; }
.ct-sub { font-family: 'Noto Sans SC'; font-size: 36px; }
</style>

Result:

✗ font_family_without_font_face: Font family used without @font-face declaration: noto sans sc.
◇  1 error(s), 2 warning(s)

The @font-face for 'Noto Sans SC' is present (confirmed via grep "@font-face" index.html → 6 declarations including Noto Sans SC 400 + 700), but the checker doesn't find it.

Expected behavior

font_family_without_font_face should match @font-face declarations regardless of CSS block size. If @font-face { font-family: 'Noto Sans SC'; ... } exists in the same <style>, it should not error on font-family: 'Noto Sans SC' usage.

Actual behavior

In complex CSS (>100 lines with multiple @keyframes), the checker fails to match the @font-face declaration → false-positive errornpx hyperframes lint exits 1 → npx hyperframes render blocked.

Root cause hypothesis

The checker's CSS parser appears to lose track of @font-face declarations when scanning through large CSS blocks with many @keyframes / rules. The @font-facefont-family match works in <50 line CSS but breaks at ~200 lines.

Workaround

Pin to 0.6.107 (where this check is a non-blocking warning):

npx hyperframes@0.6.107 lint
npx hyperframes@0.6.107 render .

Additional context

  1. CSS custom properties (var(--font-family)) are also not resolved by this checker — but that's a separate feature request. This issue is specifically: concrete @font-face with literal font-family names not matched in complex CSS.

  2. The related google_fonts_import checker (also new error in 0.6.109) forces projects to move from Google Fonts <link> to local @font-face — but then font_family_without_font_face blocks them with this false positive. The two checkers are contradictory for projects using local fonts.

  3. Minimal HTML with identical @font-face + font-family passes — the issue is triggered specifically by CSS block complexity/size, not by the @font-face syntax.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions