HTML Guides for bad value
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.
The srcset attribute allows you to provide multiple image sources so the browser can choose the most appropriate one based on the user's viewport size or screen density. There are two distinct modes for srcset:
- Width descriptor mode — each candidate specifies its intrinsic width using a
wdescriptor (e.g.,400w). This mode requires thesizesattribute so the browser knows how much space the image will occupy in the layout and can calculate which source to download. - Pixel density descriptor mode — each candidate specifies a pixel density using an
xdescriptor (e.g.,2x). This mode must not include asizesattribute.
When you include a sizes attribute but forget to add width descriptors to one or more srcset entries, the browser has incomplete information. The HTML specification explicitly states that if sizes is present, all image candidate strings must use width descriptors. An entry without a descriptor defaults to 1x (a pixel density descriptor), which conflicts with the width descriptor mode triggered by sizes. This mismatch causes the W3C validator to report the error.
Beyond validation, this matters for real-world performance. Responsive images are one of the most effective tools for reducing page weight on smaller screens. If the descriptors are missing or mismatched, browsers may download an image that is too large or too small, hurting both performance and visual quality.
How to fix it
You have two options depending on your use case:
Option 1: Add width descriptors to all srcset candidates
If you need the browser to select images based on viewport size (the most common responsive images pattern), keep the sizes attribute and ensure every srcset entry has a w descriptor that matches the image's intrinsic pixel width.
Option 2: Remove sizes and use pixel density descriptors
If you only need to serve higher-resolution images for high-DPI screens (e.g., Retina displays) and the image always renders at the same CSS size, remove the sizes attribute and use x descriptors instead.
Examples
❌ Incorrect: sizes present but srcset entry has no width descriptor
<img
src="photo-800.jpg"
srcset="photo-400.jpg, photo-800.jpg"
sizes="(min-width: 600px) 800px, 100vw"
alt="A mountain landscape">
Both srcset entries lack a width descriptor. Because sizes is present, the validator reports an error for each candidate.
✅ Correct: sizes present with width descriptors on every candidate
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w"
sizes="(min-width: 600px) 800px, 100vw"
alt="A mountain landscape">
Each candidate now specifies its intrinsic width (400w and 800w), which tells the browser the actual pixel width of each source file. The browser combines this with the sizes value to pick the best match.
❌ Incorrect: mixing width descriptors and bare entries
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg"
sizes="(min-width: 600px) 800px, 100vw"
alt="A mountain landscape">
The second candidate (photo-800.jpg) is missing its width descriptor. All candidates must have one when sizes is present — not just some of them.
✅ Correct: pixel density descriptors without sizes
<img
src="photo-800.jpg"
srcset="photo-800.jpg 1x, photo-1600.jpg 2x"
alt="A mountain landscape">
Here the sizes attribute is removed, and each srcset entry uses a pixel density descriptor (1x, 2x). This is valid and appropriate when the image always occupies the same CSS dimensions regardless of viewport width.
❌ Incorrect: using sizes with pixel density descriptors
<img
src="photo-800.jpg"
srcset="photo-800.jpg 1x, photo-1600.jpg 2x"
sizes="(min-width: 600px) 800px, 100vw"
alt="A mountain landscape">
The sizes attribute and x descriptors cannot be combined. Either switch to w descriptors or remove sizes.
Quick reference
| Pattern | srcset descriptor | sizes required? |
|---|---|---|
| Viewport-based selection | Width (w) | Yes |
| Density-based selection | Pixel density (x) | No — must be omitted |
Remember that the w value in srcset refers to the image file's intrinsic pixel width (e.g., an 800-pixel-wide image gets 800w), while values in sizes use CSS length units like px, vw, or em to describe how wide the image will render in the layout.
The srcset attribute lets browsers intelligently choose which image to load based on the viewport size and device pixel ratio. Each entry in a srcset consists of a URL followed by either a width descriptor (like 300w) or a pixel density descriptor (like 2x). When using width descriptors, the value represents the intrinsic pixel width of the image file — that is, the actual width of the image as stored on disk.
A width descriptor of 0w violates the HTML specification, which requires width descriptors to be integers greater than zero. A zero-width image cannot meaningfully participate in the browser's source selection process. The browser uses these width values in combination with the sizes attribute to calculate which image best fits the current layout — a value of zero would break this calculation entirely.
This issue commonly occurs when:
- Image dimensions are dynamically generated and a fallback of
0is used for missing data. - A placeholder or empty state is accidentally included in the
srcset. - A CMS or build tool outputs a
0wdescriptor for images whose dimensions weren't computed.
Why it matters
- Standards compliance: The HTML specification explicitly requires width descriptors to be positive integers. Validators will flag
0was an error. - Browser behavior: While browsers may silently ignore the invalid entry, you can't rely on consistent handling across all browsers and versions. The image selection algorithm may behave unpredictably.
- Performance: A well-formed
srcsetis key to responsive image loading. Invalid descriptors can prevent browsers from selecting the optimal image, leading to unnecessarily large downloads or poor image quality.
How to fix it
- Open the image file associated with the
0wdescriptor and check its actual pixel width using an image editor or the command line. - Replace
0wwith the correct width (e.g.,150wfor a 150-pixel-wide image). - If the image is truly zero-width or a placeholder, remove that entry from the
srcsetentirely. - Ensure every remaining entry has a unique, positive width descriptor.
Examples
❌ Invalid: width descriptor of 0w
<picture>
<source
srcset="/images/icon_placeholder.png 0w,
/images/icon_large.png 600w"
media="(max-width: 600px)">
<img src="/images/icon_fallback.png" alt="App logo">
</picture>
The 0w descriptor triggers the validation error because zero is not a valid width.
✅ Fixed: all width descriptors are positive
<picture>
<source
srcset="/images/icon_small.png 300w,
/images/icon_large.png 600w"
media="(max-width: 600px)">
<img src="/images/icon_fallback.png" alt="App logo">
</picture>
Each entry now has a meaningful width descriptor (300w and 600w) that reflects the actual pixel width of the corresponding image.
❌ Invalid: 0w on an <img> element
<img
srcset="/images/hero_tiny.jpg 0w,
/images/hero_medium.jpg 800w,
/images/hero_large.jpg 1200w"
sizes="100vw"
src="/images/hero_medium.jpg"
alt="Mountain landscape">
✅ Fixed: placeholder entry removed or corrected
If the tiny image is 400 pixels wide, use 400w:
<img
srcset="/images/hero_tiny.jpg 400w,
/images/hero_medium.jpg 800w,
/images/hero_large.jpg 1200w"
sizes="100vw"
src="/images/hero_medium.jpg"
alt="Mountain landscape">
Alternatively, if the image doesn't belong in the set at all, simply remove it:
<img
srcset="/images/hero_medium.jpg 800w,
/images/hero_large.jpg 1200w"
sizes="100vw"
src="/images/hero_medium.jpg"
alt="Mountain landscape">
When using a build tool or CMS that generates srcset values dynamically, add a check to filter out any entries where the computed width is zero or missing before rendering the attribute. This prevents the invalid markup from reaching production.
The type attribute on an <a> element is an advisory hint that tells the browser what media type (MIME type) to expect at the linked resource. A valid MIME type follows a strict format: a type, a / separator, and a subtype (e.g., text/html, application/pdf, image/png). Each part must consist of token characters — letters, digits, and certain symbols — but not spaces.
This validation error occurs when the MIME type value contains a space or other unexpected character in a position where only token characters or a / are allowed. Common causes include:
- Accidental spaces within the MIME type (e.g.,
application/ pdforapplication /pdf). - Multiple MIME types separated by spaces (e.g.,
text/html text/plain), which is not valid since the attribute accepts only a single MIME type. - Typos or copy-paste errors that introduce whitespace or non-token characters.
While the type attribute is purely advisory and browsers won't refuse to follow a link based on it, an invalid value defeats its purpose and signals sloppy markup. Standards-compliant HTML ensures your pages are interpreted consistently and avoids confusing tools, screen readers, or other user agents that may parse this attribute.
Examples
Incorrect: Space within the MIME type
<a href="report.pdf" type="application/ pdf">Download Report</a>
The space after the / makes this an invalid MIME type.
Incorrect: Multiple MIME types separated by a space
<a href="data.csv" type="text/csv text/plain">Download Data</a>
The type attribute only accepts a single MIME type. The space between text/csv and text/plain triggers the error.
Incorrect: Leading or trailing spaces
<a href="photo.jpg" type=" image/jpeg ">View Photo</a>
Spaces before or after the MIME type are not permitted.
Correct: Valid MIME type with no spaces
<a href="report.pdf" type="application/pdf">Download Report</a>
Correct: Other common valid MIME types
<a href="data.csv" type="text/csv">Download Data</a>
<a href="photo.jpg" type="image/jpeg">View Photo</a>
<a href="archive.zip" type="application/zip">Download Archive</a>
Correct: MIME type with a parameter
MIME types can include parameters separated by a semicolon — no spaces are required, though a single space after the semicolon is permitted per the MIME specification:
<a href="page.html" type="text/html; charset=utf-8">View Page</a>
How to Fix
- Inspect the
typevalue — look for any spaces within the type or subtype portions (before or after the/). - Remove extra spaces — ensure the value is a single, properly formatted MIME type like
type/subtype. - Use only one MIME type — if you've listed multiple types, pick the one that accurately describes the linked resource.
- Verify the MIME type is valid — consult the IANA Media Types registry to confirm you're using a recognized type.
- Consider removing the attribute — since
typeis purely advisory on<a>elements, if you're unsure of the correct MIME type, omitting the attribute entirely is perfectly valid.
A MIME type (also called a media type) always follows the format type/subtype, such as text/html, application/pdf, or image/jpeg. The "type" part indicates the general category (e.g., text, image, application, audio, video), and the "subtype" specifies the exact format within that category. When the validator reports "Subtype missing," it means the value you provided either lacks the /subtype portion or isn't a valid MIME type structure at all.
A common cause of this error is misunderstanding the purpose of the type attribute on <a> elements. The type attribute is not used to change the behavior or appearance of the link (the way type works on <input> or <button> elements). Instead, it serves as an advisory hint to the browser about what kind of resource the link points to. The browser may use this information to adjust its UI — for example, showing a download prompt for application/pdf — but it is not required to act on it.
Because of this misunderstanding, developers sometimes write type="button" on an <a> element, thinking it will make the link behave like a button. The value button is not a valid MIME type (it has no subtype), so the validator flags it. If you need a button, use a <button> element instead. If you need a styled link that looks like a button, keep the <a> element and use CSS for styling.
Why this matters
- Standards compliance: The HTML specification requires the
typeattribute on<a>to be a valid MIME type string. An invalid value violates the spec and may be ignored by browsers or cause unexpected behavior. - Accessibility and semantics: Using
type="button"on a link can create confusion about the element's role. Screen readers and assistive technologies rely on correct semantics to convey meaning to users. - Browser behavior: While browsers are generally forgiving, an invalid
typevalue provides no useful information and could interfere with how the browser handles the linked resource.
How to fix it
- If you intended to hint at the linked resource's MIME type, make sure you provide a complete
type/subtypevalue — for example,application/pdfrather than justapplication. - If you used
typeto try to style or change the link's behavior, remove thetypeattribute entirely. Use CSS for visual styling or switch to a more appropriate element like<button>. - If you don't need the
typeattribute, simply remove it. It's entirely optional on<a>elements.
Examples
Incorrect: missing subtype
<a href="report.pdf" type="application">Download report</a>
The value application is incomplete — it's missing the subtype portion after the slash.
Incorrect: not a MIME type at all
<a href="/order.php" type="button">Submit</a>
The value button is not a MIME type. This often stems from confusing the type attribute on <a> with the type attribute on <input> or <button>.
Correct: valid MIME type
<a href="report.pdf" type="application/pdf">Download report</a>
<a href="photo.jpeg" type="image/jpeg">See a photo</a>
The type attribute uses a properly formatted MIME type with both a type and subtype.
Correct: removing the attribute entirely
<a href="/order.php">Submit</a>
If the type attribute isn't serving a real purpose, the simplest fix is to remove it.
Correct: using a button element instead
<button type="submit">Submit</button>
If you need actual button behavior (such as submitting a form), use a <button> element rather than an <a> element with an invalid type.
The type attribute on a <button> only accepts three keywords — submit, reset, and button — so any other value is rejected.
type is an enumerated attribute, not a free-form one. submit posts the form (and is what a button does when the attribute is absent), reset clears the form fields, and button does nothing on its own and is meant to be wired up with JavaScript. Anything outside that set is invalid markup, and the browser falls back to submit, so a button you expected to stay inert may submit the form instead.
If you want the default behavior, leave the attribute off or write type="submit" explicitly; if the button should not submit, use type="button".
Invalid example
<button type="default">Save</button>
Valid example
<button type="submit">Save</button>
The type attribute on a <link> element specifies the MIME type of the linked resource. MIME types follow a specific format: a type and subtype separated by a single forward slash, like text/css, image/png, or application/json. They never contain the :// sequence found in URLs.
This error most commonly occurs when a URL is accidentally placed in the type attribute instead of in the href attribute, or when the attributes are confused with one another. For example, writing type="https://example.com/style.css" triggers this error because the validator encounters the colon in https: where it expects a valid MIME type token.
Another common cause is copying type values from other contexts (such as XML namespaces or schema references) that use URL-like strings, and mistakenly applying them to the type attribute.
Why this matters
- Standards compliance: The HTML specification requires the
typeattribute to contain a valid MIME type. Invalid values violate the spec and may cause browsers to misinterpret or ignore the linked resource. - Browser behavior: Browsers use the
typeattribute as a hint for how to handle the resource. An invalid MIME type could lead the browser to skip loading the resource entirely, causing missing styles, icons, or other assets. - Maintainability: Incorrect attribute values signal to other developers (and automated tools) that something is misconfigured, making the code harder to maintain.
How to fix it
- Check that
typecontains a valid MIME type, not a URL or other string. Common valid values includetext/css,image/png,image/x-icon,image/svg+xml, andapplication/rss+xml. - Ensure URLs are in the
hrefattribute, nottype. - Consider removing
typeentirely. For stylesheets, modern browsers default totext/css, sotype="text/css"is optional. For many use cases, thetypeattribute can be safely omitted.
Examples
❌ Incorrect: URL used as the type value
<link rel="stylesheet" type="https://example.com/style.css">
The validator sees the colon in https: and reports the error because this is a URL, not a MIME type.
❌ Incorrect: Attributes swapped
<link rel="icon" type="https://example.com/favicon.png" href="image/png">
Here the type and href values have been accidentally swapped.
✅ Correct: Valid MIME type with proper href
<link rel="icon" type="image/png" href="https://example.com/favicon.png">
✅ Correct: Stylesheet with valid type
<link rel="stylesheet" type="text/css" href="/css/style.css">
✅ Correct: Stylesheet without type (also valid)
<link rel="stylesheet" href="/css/style.css">
Since browsers default to text/css for stylesheets, omitting type is perfectly valid and keeps your markup cleaner.
✅ Correct: RSS feed link
<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="/feed.xml">
Why This Matters
While HTML5 is quite permissive with id values (allowing almost anything except spaces), elements within XML-based vocabularies like SVG and MathML are held to stricter rules. When these elements appear in your HTML document, their attributes must still conform to XML 1.0 naming conventions as defined by the relevant specification.
XML 1.0 names must follow these rules:
- Must start with a letter (
a–z,A–Z) or an underscore (_) - Subsequent characters can be letters, digits (
0–9), hyphens (-), underscores (_), and periods (.) - Cannot contain spaces, colons (outside of namespaced contexts), or special characters like
@,#,$,!, etc.
This error typically appears when design tools (such as Figma, Illustrator, or Sketch) export SVG files with auto-generated id values that include spaces or other invalid characters. Browsers may still render the content, but relying on non-conformant names can cause problems with CSS selectors, JavaScript's getElementById(), URL fragment references, and accessibility tools that depend on valid identifiers.
How to Fix It
- Remove spaces — replace them with hyphens or underscores, or use camelCase.
- Ensure the name starts with a letter or underscore — if it starts with a digit, prefix it with a letter or underscore.
- Strip out special characters — remove or replace characters like
@,#,(,), etc. - Review exported SVG files — if you're embedding SVGs from design tools, clean up the generated
idvalues before adding them to your HTML.
Examples
Invalid: Space in the id value
The space in "Group 270" makes this an invalid XML 1.0 name:
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<g id="Group 270">
<circle cx="50" cy="50" r="40" />
</g>
</svg>
Invalid: Name starts with a digit
XML 1.0 names cannot begin with a number:
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect id="1st-rectangle" width="100" height="50" />
</svg>
Invalid: Special characters in the name
Characters like ( and ) are not allowed:
<svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
<path id="icon(home)" d="M10 80 L50 10 L90 80 Z" />
</svg>
Fixed: Valid XML 1.0 names
Replace spaces with hyphens, prefix digit-leading names with a letter, and remove special characters:
<svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
<g id="group-270">
<circle cx="50" cy="50" r="40" />
</g>
<rect id="first-rectangle" width="100" height="50" />
<path id="icon-home" d="M10 80 L50 10 L90 80 Z" />
</svg>
Tip: Cleaning up exported SVGs
Design tools often produce id values like "Frame 42", "Vector (Stroke)", or "123_layer". A quick find-and-replace workflow can fix these before they land in your codebase. You can also use tools like SVGO to optimize and clean up SVG output, including stripping or renaming invalid identifiers.
The text-transform CSS property controls the capitalization of text within an element. It's commonly used to enforce consistent text casing — for example, making headings appear in all uppercase or ensuring navigation links are lowercase — without changing the actual content in the HTML. When the validator encounters a value it doesn't recognize for this property, it flags it as invalid.
This error can occur for several reasons:
- Typos — writing
upppercaseinstead ofuppercase, orCapitalizeinstead ofcapitalize(CSS values are case-sensitive in validation contexts). - Incorrect values — using values from other properties, like
bold,italic, orcenter, which don't apply totext-transform. - Non-standard values — using browser-specific or experimental values that aren't part of the CSS specification.
- Wrong property — confusing
text-transformwithtext-decoration,text-align, orfont-variant, and using their values here instead.
Fixing this matters because invalid CSS can lead to unpredictable rendering across browsers. While most browsers will simply ignore an invalid declaration, your intended styling won't be applied, potentially breaking your design. Keeping your CSS valid also improves maintainability and ensures forward compatibility.
Valid values for text-transform
| Value | Effect |
|---|---|
none | No capitalization change (default) |
capitalize | First letter of each word is uppercased |
uppercase | All characters are converted to uppercase |
lowercase | All characters are converted to lowercase |
full-width | Forces characters into a full-width form (useful for CJK typography) |
full-size-kana | Converts small kana characters to full-size equivalents |
Examples
Incorrect — invalid value
In this example, bold is not a valid text-transform value. It likely belongs on the font-weight property instead.
<p style="text-transform: bold;">Welcome to our site</p>
Similarly, a simple typo will trigger this error:
<p style="text-transform: uppercse;">Welcome to our site</p>
Correct — using valid values
<p style="text-transform: uppercase;">Welcome to our site</p>
<p style="text-transform: capitalize;">Welcome to our site</p>
Correct — separating concerns with the right properties
If you intended to make text bold and uppercase, use the appropriate property for each effect:
<p style="font-weight: bold; text-transform: uppercase;">Welcome to our site</p>
Correct — using text-transform in a stylesheet
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Text Transform Example</title>
<style>
.heading {
text-transform: uppercase;
}
.name {
text-transform: capitalize;
}
.code-snippet {
text-transform: none;
}
</style>
</head>
<body>
<h1 class="heading">site navigation</h1>
<p class="name">john doe</p>
<code class="code-snippet">myVariable</code>
</body>
</html>
If you're unsure which value you need, uppercase and capitalize are the most commonly used. Use none when you need to override a text-transform rule inherited from a parent element.
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