Last updated
What Does the Whitespace Visualizer Do?
The Whitespace Visualizer makes invisible whitespace characters visible — spaces, tabs, newlines, non-breaking spaces, zero-width characters, and more. It's essential for debugging Python indentation errors, mixed line endings, trailing spaces, and hidden Unicode characters that cause mysterious behavior.
Whitespace Symbol Legend
Symbol Character Unicode Description
------ --------- ------- -----------
· Regular space U+0020 Standard space
→ Tab U+0009 Horizontal tab
↵ Line feed (LF) U+000A Unix newline
↩ Carriage return (CR) U+000D Old Mac newline
↵↩ CRLF U+000D+A Windows newline
· Non-breaking space U+00A0 Looks like space, isn't
Zero-width space U+200B Completely invisible
Zero-width non-joiner U+200C Invisible
Zero-width joiner U+200D Invisible (used in emoji)
· En space U+2002 Wider than regular space
· Em space U+2003 Even wider
Python Indentation — Mixed Tabs and Spaces
Input code (looks correct in editor):
def calculate(x):
if x > 0:
return x * 2
return -x
With whitespace visualized:
def·calculate(x):↵
····if·x·>·0:↵
········return·x·*·2↵
→return·-x↵
Problem identified:
Line 4 uses TAB (→) for indentation
Lines 2-3 use SPACES (····) for indentation
Python 3 raises: TabError: inconsistent use of tabs and spaces
Fix: Replace tab with 4 spaces on line 4
Trailing Whitespace Detection
Input (trailing spaces invisible in editor):
function hello() {
console.log("Hello");
}
With whitespace visualized:
function·hello()·{···↵
··console.log("Hello");···↵
}···↵
Trailing spaces found:
Line 1: 3 trailing spaces
Line 2: 3 trailing spaces
Line 3: 3 trailing spaces
Why this matters:
- Causes test failures in many testing frameworks
- Creates noisy git diffs (whitespace-only changes)
- Violates most linting rules (ESLint, Prettier)
- Can break YAML parsing in some cases
Mixed Line Endings
Input file (mixed CRLF and LF):
Line 1 (Windows)
Line 2 (Unix)
Line 3 (Windows)
With whitespace visualized:
Line·1·(Windows)↵↩
Line·2·(Unix)↵
Line·3·(Windows)↵↩
Problem: Mixed line endings
Lines 1, 3: CRLF (Windows) ↵↩
Line 2: LF (Unix) ↵
Why this matters:
- Git shows entire file as changed when line endings differ
- Some tools fail to parse files with mixed endings
- Shell scripts with CRLF fail on Linux/macOS
Fix options:
Convert all to LF: sed -i 's/\r//' file.txt
Convert all to CRLF: unix2dos file.txt
Git config: git config core.autocrlf true (Windows)
git config core.autocrlf input (Mac/Linux)
Non-Breaking Space Detection
Input (copied from a Word document):
Hello World
With whitespace visualized:
Hello·World
Wait — that looks normal. Let's check the character:
Hello[U+00A0]World
Non-breaking space (U+00A0) found between "Hello" and "World"!
Why this matters:
- Looks identical to regular space in most editors
- NOT treated as whitespace by many parsers
- Causes string comparison failures:
"Hello World" === "Hello World" → FALSE ✗
(one has U+0020, other has U+00A0)
- Breaks word-wrap in some contexts
- Often appears in content copied from Word, PDFs, or web pages
Fix: Replace U+00A0 with regular space U+0020
Zero-Width Character Detection
Input (looks like "admin" but isn't):
admin
With whitespace visualized:
admin
Zero-width spaces (U+200B) found between every character!
This is a security concern:
"admin" (with ZWS) !== "admin" (without ZWS)
Can be used to bypass username filters
Can create visually identical but technically different strings
Used in phishing attacks with lookalike domain names
Detection in JavaScript:
const hasZeroWidth = /[\u200B\u200C\u200D\uFEFF]/.test(text);
// Remove zero-width characters
const cleaned = text.replace(/[\u200B\u200C\u200D\uFEFF]/g, '');
YAML Indentation Debugging
Input YAML (fails to parse):
services:
web:
image: nginx
ports:
- "80:80"
With whitespace visualized:
services:↵
··web:↵
····image:·nginx↵
→ports:↵
······-·"80:80"↵
Problem: Line 4 uses TAB (→) instead of spaces
YAML does not allow tabs for indentation
Fix: Replace tab with 4 spaces:
services:↵
··web:↵
····image:·nginx↵
····ports:↵
······-·"80:80"↵
Removing Whitespace Issues in Code
// JavaScript — remove various whitespace issues
function cleanText(text) {
return text
.replace(/\u00A0/g, ' ') // non-breaking space → space
.replace(/[\u200B-\u200D\uFEFF]/g, '') // zero-width chars → remove
.replace(/\r\n/g, '\n') // CRLF → LF
.replace(/\r/g, '\n') // CR → LF
.replace(/[ \t]+$/gm, ''); // trailing whitespace → remove
}
// Python — strip all whitespace variants
import re
import unicodedata
def clean_text(text):
# Normalize unicode whitespace
text = unicodedata.normalize('NFC', text)
# Remove zero-width characters
text = re.sub(r'[\u200b\u200c\u200d\ufeff]', '', text)
# Replace non-breaking spaces
text = text.replace('\u00a0', ' ')
# Normalize line endings
text = text.replace('\r\n', '\n').replace('\r', '\n')
return text
Common Use Cases
- Debugging Python IndentationError from mixed tabs and spaces
- Finding trailing whitespace causing test failures
- Identifying mixed line endings causing git diff noise
- Detecting non-breaking spaces in content copied from Word/PDF
- Security: finding zero-width characters in usernames or URLs
- Debugging YAML and Makefile indentation issues