String HTML methods (bold, italics, link…)

Netscape shipped these in 1995 and the web never let them go. They are normatively optional, they generate tags that HTML5 removed, and they interpolate without escaping. Documented here so you recognise them — not so you use them.

String methods (Annex B)Annex B (legacy)Live demo
Common call
'text'.bold()
Returns
'<b>text</b>' — unescaped
Replaces
nothing; CSS and real DOM APIs replace THEM
Watch out
no escaping at all — an XSS hazard on any dynamic input
string.bold(), string.link(url), string.fontcolor(c)
→ string

Demo

Live evaluation
Try:
Inputs
sstringtext to wrap
Output
'hello'.bold()
'<b>hello</b>'

bold() stands in for the whole family — every one of the thirteen does the same thing with a different tag name. The third case is the reason this page exists as a warning rather than a recommendation: the input is dropped into the output verbatim, so anything that looks like markup stays markup. Wrapping user input this way and inserting the result with innerHTML is a textbook XSS hole, and the tag it produces was removed from HTML5 anyway.

Parameters

NameTypeRequiredDescription
valuestringno (none)Only four of the thirteen take an argument: link(url), anchor(name), fontcolor(color) and fontsize(size). The value is inserted into the attribute with quotes escaped but nothing else.

Return value

string — The string wrapped in an HTML tag. No escaping is performed on the text OR on the attribute values, which is why these are unsafe as well as obsolete.

Common patterns

Style with CSS
What bold, italics and the font methods should be.
el.style.fontWeight = "bold";
Build elements safely
textContent escapes; innerHTML does not.
const a = document.createElement("a");
a.href = url;
a.textContent = label;
Semantic markup in a template
With the text escaped by whatever renders it.
const html = `<strong>${escapeHtml(text)}</strong>`;

Examples

1. bold
'hi'.bold()
Returns
'<b>hi</b>'
2. italics
'hi'.italics()
Returns
'<i>hi</i>'
3. link
'hi'.link('/x')
Returns
'<a href="/x">hi</a>'
4. fontcolor
'hi'.fontcolor('red')
Returns
'<font color="red">hi</font>'
5. Not escaped
'<b>'.bold()
Returns
'<b><b></b>'
6. blink, really
'hi'.blink()
Returns
'<blink>hi</blink>'

Pitfalls

1. They do not escape the text
The content is concatenated in as-is. Wrapping anything a user supplied and then assigning the result to innerHTML executes whatever they sent — these methods predate the web taking injection seriously.
Markup survives
'<img src=x onerror=alert(1)>'.bold()
'<b><img src=x onerror=alert(1)></b>'
Escape, or use textContent
el.textContent = userInput;
inert text
2. They generate tags HTML5 removed
font, blink, strike and big are all obsolete. Browsers still render most of them for compatibility, blink does nothing at all any more, and validators reject the lot.
Obsolete element
'hi'.fontsize(7)
'<font size="7">hi</font>'
CSS
el.style.fontSize = "2em";
supported
3. They are Annex B, not the core language
Annex B is normatively OPTIONAL — required only for web browsers. A non-browser JavaScript runtime is free to omit them entirely, so code relying on them is not portable even though it works today.
May not exist
'hi'.bold()
TypeError in a conforming non-browser host
Plain string
`<strong>${escapeHtml(s)}</strong>`
portable
4. anchor and link only escape quotes
The argument has its double quotes replaced with &quot; and nothing else, so the attribute cannot be broken out of by quoting — but a javascript: URL in link() is passed straight through.
Dangerous scheme
'click'.link('javascript:alert(1)')
'<a href="javascript:alert(1)">click</a>'
Validate the URL
new URL(u).protocol === 'https:'
checked

When to use

Use it
  • Never in new code
  • Recognising them while reading something written long ago
Reach for something else
  • Styling text → CSS
  • Building markup → createElement with textContent, or a templating layer that escapes
  • Anything involving user input → these escape nothing
  • Portable code → Annex B is optional outside browsers

Notes

Complexity
O(n) — a concatenation
Return
A new string; the original is untouched
CPython impl
V8: Builtins-string-html — one shared helper for all thirteen
Memory
Allocates the wrapped string
Thread-safe
Single-threaded

FAQ

Thirteen: anchor, big, blink, bold, fixed, fontcolor, fontsize, italics, link, small, strike, sub and sup. Four take an argument — anchor, link, fontcolor and fontsize — and the rest simply wrap.

'x'.bold();      // '<b>x</b>'
'x'.sub();       // '<sub>x</sub>'
'x'.link('/y');  // '<a href="/y">x</a>'

History

Netscape 2
Added in 1995 alongside the original String methods, when generating HTML from JavaScript meant string concatenation.
ES5
Documented in Annex B as normatively optional legacy features required for web compatibility.
HTML5
font, big, strike and blink removed from the HTML specification; the JavaScript methods that generate them remain.