Rendering Verification
When to use: After deploying. After changing CSS tokens, themes, or framework versions. When something "looks wrong" but you can't pinpoint why.
The test: Every element you intended to be visible is visible. Every color you intended to render actually renders.
Token Resolution
Every CSS custom property and design token must resolve to a concrete value.
| Check | Threshold | How to Measure |
|---|---|---|
| Custom properties resolve | Zero unset/initial/empty values | DevTools: Computed tab, filter for custom properties |
| Background colors produce visible values | Computed background-color is not transparent or rgba(0,0,0,0) | DevTools: select element, check Computed styles |
| Text colors differ from backgrounds | Delta E (CIEDE2000) between text and background greater than 20 | Browser contrast checker or getComputedStyle() comparison |
| Border colors render | Computed border-color is not same as background-color | DevTools: compare computed values |
Token Audit Checklist
- Every
var(--token)in use has a defined value in the active theme - No fallback values masking missing definitions (e.g.,
var(--missing, transparent)) - Tokens defined in the correct layer for your framework version
- Dark mode tokens tested separately from light mode
CSS Cascade
Framework defaults, resets, and utility classes can silently override each other.
| Check | Threshold | How to Measure |
|---|---|---|
| Utility classes win | Your utility has higher specificity than framework defaults | DevTools: Styles panel shows utility not struck through |
No !important wars | Zero instances of !important overriding !important | Search codebase: count !important occurrences |
| Reset doesn't zero your values | Elements retain intended padding, margin, font-size | Compare computed values against your design tokens |
Cascade Checklist
- Framework CSS loads before custom CSS
- Utility layer has correct specificity for your framework version
- No global selectors (
*,body,html) overriding component styles - Scoped styles don't leak into or out of components
Visual Rendering
Elements exist in the DOM but produce no visual output more often than you think.
| Check | Threshold | How to Measure |
|---|---|---|
| Images render with visible dimensions | Width and height both greater than 0px | DevTools: element inspector, check computed dimensions |
| SVGs render with fill or stroke | fill is not none/transparent when content expected | DevTools: check computed fill and stroke |
| Icons have visible size | Minimum 16x16px rendered dimensions | DevTools: computed width/height |
| Fonts loaded | Rendered font-family matches intended font | DevTools: Computed tab, check font-family |
Rendering Checklist
- No zero-height containers hiding content
-
overflow: hiddennot clipping intended content -
opacitygreater than 0.1 on all informational elements -
visibilityisvisible(nothiddenorcollapse) -
displayis notnoneon intended elements -
z-indexstacking shows elements in correct order
Overflow and Layout
| Check | Threshold | How to Measure |
|---|---|---|
| No horizontal overflow | Page width equals viewport width at every breakpoint | Scroll horizontally - if you can, it fails |
| No text overflow | All text visible, no unintended ... truncation | Visual scan at each breakpoint |
| Containers contain their children | No child elements visually outside parent bounds | DevTools: hover parent, check child positions |
| Flex/grid items wrap correctly | No items hidden off-screen | Resize browser, watch for disappearing elements |
Automated Audit
Run this in the browser console to catch common rendering failures:
// Check for invisible text (same color as background)
document.querySelectorAll("p, h1, h2, h3, h4, span, a, li, td, th, label, button").forEach((el) => {
const styles = getComputedStyle(el);
const color = styles.color;
const bg = styles.backgroundColor;
if (color === bg && el.textContent.trim()) {
console.warn("Invisible text:", el.textContent.substring(0, 50), el);
}
});
// Check for zero-dimension elements that have content
document.querySelectorAll("div, section, article, main, aside, nav").forEach((el) => {
const rect = el.getBoundingClientRect();
if ((rect.width === 0 || rect.height === 0) && el.children.length > 0) {
console.warn("Zero-dimension container with children:", el);
}
});
// Check for unresolved CSS variables
document.querySelectorAll("*").forEach((el) => {
const styles = getComputedStyle(el);
for (const prop of styles) {
const value = styles.getPropertyValue(prop);
if (value.includes("var(") && value.includes(")")) {
console.warn("Unresolved CSS variable on", el, prop, value);
}
}
});
Quick Diagnosis
| Symptom | Likely Cause | Fix |
|---|---|---|
| White-on-white text | Token defined in wrong layer/format | Check framework version, register token correctly |
| Elements missing | display: none or zero dimensions | Check computed display, width, height |
| Colors all the same | Tokens resolve to same value | Audit computed values, check theme definition |
| Borders invisible | Border color matches background | Set explicit border color different from background |
| Icons missing | SVG fill is none or font not loaded | Check computed fill, verify font loading |
| Layout broken after deploy | CSS load order changed | Verify stylesheet order in build output |
Context
- Visual Design -- Once it renders, make it look right
- Design Review -- The full review process
- Standards -- Why verification matters