css-analyzer
css-analyzer copied to clipboard
🧱 Incorrect font destructuring
From cssday.nl
body {
font: 100% Source Code Pro, Inconsolata, Menlo, monospace;
}
Expected:
font-size: 100%font-family: Source Code Pro, Inconsolata, Menlo, monospace
Actual:
font-size: Codefont-family: Pro, Inconsolata, Menlo, monospace
The font-family isn't quoted, to the individual parts of Source Code Pro end up being Identifier, which messes with our algorithm.
Related to https://github.com/projectwallace/css-analyzer/issues/321 because of our whacky font destructuring algorithm.
Example from exaprint.fr:
font: Styrene A,sans-serif;
produces a font-size -> Styrene and a fontFamily -> A,sans-serif
from cssday.nl
font: 100% source code pro, inconsolata, menlo, monospace
reports as font-size: code
See Twitter thread here https://twitter.com/csstree/status/1632496974921342976
See “Syntax matching” in usage section of readme https://github.com/csstree/csstree#usage It also should work with string values beside of AST nodes.
Using CSSTree's syntax matching to destructure a font shorthand:
import * as csstree from 'css-tree'
let fonts = [
'1em / 2px sans-serif, "Test me"',
'100% Source Code Pro, Inconsolata, Menlo, monospace',
// 'Styrene A, sans-serif',
'400 1em -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"',
// '14px/1 var(--font-sans)',
]
for (let font of fonts) {
let ast = csstree.parse(font, { context: 'value' })
let matchResult = csstree.lexer.matchProperty('font', ast)
console.log(font)
console.log(JSON.stringify(matchResult.matched.match, null, 2))
}
// 1em / 2px sans-serif, "Test me"
// [
// {
// syntax: { type: 'Property', name: 'font-size' },
// match: [ [Object] ]
// },
// {
// syntax: { type: 'Token', value: '/' },
// token: '/',
// node: { type: 'Operator', loc: null, value: '/' }
// },
// {
// syntax: { type: 'Property', name: 'line-height' },
// match: [ [Object] ]
// },
// {
// syntax: { type: 'Property', name: 'font-family' },
// match: [ [Object], [Object], [Object] ]
// }
// ]
But it errors when mixing with var()