HTML Guides for font-family
Learn how to identify and fix common HTML validation errors flagged by the W3C Validator — so your pages are standards-compliant and render correctly across every browser. Also check our Accessibility Guides.
A CSS syntax error in your font-family declaration is using an invalid character or operator where the validator expects a comma-separated list of font names.
The font-family property expects font names separated by commas. A common mistake is using operators like +, =, or / between font names, or copying malformed font names from URLs (like Google Fonts link URLs where + replaces spaces). Font names with spaces must be wrapped in quotes.
For example, font-family: Open+Sans is invalid because + is not a valid CSS operator in this context. The correct form is font-family: "Open Sans". Similarly, using font-family: Arial / Helvetica is invalid — a comma should separate fallback fonts.
Invalid Example
<pstyle="font-family: Open+Sans, sans-serif;">Hello</p>
Fixed Example
<pstyle="font-family:'Open Sans', sans-serif;">Hello</p>
Double-check that your font names use commas as separators, quotes around names with spaces, and no stray characters like +, /, or =.
The CSS font shorthand property has a specific syntax defined in the CSS specification. At minimum, it requires both a font-size and a font-family value. Optionally, you can prepend font-style, font-variant, and font-weight, and you can append a line-height value after the font-size using a slash separator. The full syntax looks like this:
font: [font-style] [font-variant] [font-weight] font-size[/line-height] font-family;
When the W3C validator reports that a value "is not a font-family value," it means the parser reached a point in the font declaration where it expected to find a font family name but instead found something it couldn't interpret as one. This often happens in two scenarios:
- Using
fontwhen you meant a specific property — For example, writingfont: 300when you only intended to set the font weight. The validator tries to parse300as a completefontvalue, and since there's nofont-sizeorfont-family, it fails. - Incomplete
fontshorthand — Providing some values but forgetting the mandatoryfont-familyat the end, such asfont: 300 16pxwithout a family name.
This matters because browsers may ignore an invalid font declaration entirely, causing your text to render with default or inherited styles instead of what you intended. Keeping your CSS valid also ensures consistent behavior across different browsers and helps maintain clean, predictable stylesheets.
How to fix it:
- If you only need to set a single font-related property, use the specific property (
font-weight,font-size,font-style,font-variant, orfont-family) instead of thefontshorthand. - If you want to use the
fontshorthand, make sure you include at leastfont-sizeandfont-family, and that all values appear in the correct order. - Remember that the
fontshorthand resets any omitted font sub-properties to their initial values, so use it deliberately.
Examples
Incorrect: Using font to set only the weight
<pstyle="font:300;">This text has an invalid font declaration.</p>
The validator reports that 300 is not a valid font-family value because the font shorthand expects at least a font-size and font-family.
Correct: Using font-weight directly
<pstyle="font-weight:300;">This text has a light font weight.</p>
Incorrect: Missing font-family in the shorthand
<pstyle="font: italic 30016px;">This is also invalid.</p>
Even though font-style, font-weight, and font-size are all present, the required font-family is missing.
Correct: Complete font shorthand
<pstyle="font: italic 30016px/1.5 'Helvetica', sans-serif;">This is valid.</p>
This includes all components in the correct order: font-style, font-weight, font-size/line-height, and font-family.
Correct: Minimal valid font shorthand
<pstyle="font:16px sans-serif;">Only size and family — the minimum required.</p>
Correct: Using individual properties instead of the shorthand
<pstyle="font-style: italic;font-weight:300;font-size:16px;line-height:1.5;font-family:'Helvetica', sans-serif;">
Each property set individually.
</p>
Using individual properties avoids the pitfalls of the shorthand and gives you explicit control without accidentally resetting other font sub-properties.
The <tt> element was a purely presentational element — it described how text should look (monospaced) rather than what the text meant. HTML5 removed it as part of a broader effort to separate content from presentation. Browsers still render <tt> for backward compatibility, but validators will flag it as obsolete, and its use is discouraged in all new code.
The key issue is that <tt> was used for many different purposes — displaying code snippets, keyboard input, sample output, variables, filenames, and more — yet it conveyed none of that meaning to assistive technologies or search engines. HTML5 provides dedicated semantic elements for most of these use cases, making your content more meaningful and accessible.
Choosing the Right Replacement
Before reaching for a generic <span>, consider what the monospaced text actually represents:
- Code: Use
<code>for inline code fragments (e.g., variable names, short statements). - Keyboard input: Use
<kbd>for text the user should type. - Sample output: Use
<samp>for output from a program or system. - Variables: Use
<var>for mathematical or programming variables. - No semantic meaning: Use a
<span>with CSS when the monospaced styling is purely visual and none of the above elements apply.
All of these elements render in a monospaced font by default in most browsers (except <var>, which is typically italic). You can further style them with CSS as needed.
Examples
❌ Obsolete usage with <tt>
<p>Run the command <tt>npm install</tt> to install dependencies.</p>
<p>The variable <tt>x</tt> holds the result.</p>
<p>The output was <tt>Hello, world!</tt></p>
These all trigger the validator error: The "tt" element is obsolete. Use CSS instead.
✅ Fixed with semantic elements
<p>Run the command <kbd>npm install</kbd> to install dependencies.</p>
<p>The variable <var>x</var> holds the result.</p>
<p>The output was <samp>Hello, world!</samp></p>
Each replacement conveys the meaning of the text. <kbd> tells assistive technologies this is something the user types, <var> marks a variable, and <samp> indicates program output.
✅ Fixed with <code> for inline code
<p>Use the <code>Array.prototype.map()</code> method to transform each element.</p>
✅ Fixed with a <span> and CSS when no semantic element fits
If the monospaced text doesn't represent code, input, output, or a variable — for example, a stylistic choice for a filename or an arbitrary design decision — use a <span> with CSS:
<p>Edit the file <spanclass="mono">config.yaml</span> to change the settings.</p>
.mono{
font-family: monospace;
}
This keeps your HTML valid and your styling in the CSS layer where it belongs.
✅ Block-level code with <pre> and <code>
If you previously used <tt> inside a <pre> block for multi-line code, the standard approach is to combine <pre> with <code>:
<pre><code>function greet(name) {
return "Hello, " + name;
}</code></pre>
Summary
Replace every <tt> element with the semantic HTML element that best describes its content — <code>, <kbd>, <samp>, or <var>. If none of these fit, use a <span> styled with font-family: monospace in CSS. This keeps your markup valid, meaningful, and accessible.
Validate at scale.
Ship accessible websites, faster.
Automated HTML & accessibility validation for large sites. Check thousands of pages against WCAG guidelines and W3C standards in minutes, not days.
Pro Trial
Full Pro access. Cancel anytime.
Start Pro Trial →Join teams across 40+ countries