-
Notifications
You must be signed in to change notification settings - Fork 1
Context CSS
Use when the value lands inside a CSS property value:
color: HERE;,background-image: url(HERE);,<style>div { color: HERE; }</style>.
escCss() whitelists [A-Za-z0-9]. Every other character is rewritten as the CSS escape sequence \HEX — with the mandatory trailing space that terminates the escape.
The trailing space looks redundant but it is required by the CSS spec: without it, the parser would eat hex-digit-looking characters that follow the escape into the same token.
public function escCss(string $str): string;Or via the facade:
Esc::esc(string $str, 'css', ?string $encoding = null): string;| Throws | When |
|---|---|
InvalidUtf8Exception |
$str is not valid UTF-8 (after any encoding conversion). |
EncodingConversionException |
iconv / mbstring fail during UTF-8 conversion. |
Esc::esc('red', 'css'); // red
Esc::esc('10px', 'css'); // 10px
Esc::esc('abcXYZ123', 'css'); // abcXYZ123Note: even # and units like %, em get escaped — escCss is intentionally strict because it cannot tell value from selector syntax.
Esc::esc('#ff0000', 'css'); // \23 ff0000
Esc::esc('expression(alert(1))', 'css');
// expression\28 alert\28 1\29 \29$untrusted = '</style><script>alert(1)</script>';
Esc::esc($untrusted, 'css');
// \3C \2F style\3E \3C script\3E alert\28 1\29 \3C \2F script\3E<, >, /, parentheses and spaces all turn into CSS escapes, so the attacker cannot close the <style> block and inject a script.
Esc::esc(' ', 'css'); // \20
Esc::esc('{', 'css'); // \7B
Esc::esc('}', 'css'); // \7D
Esc::esc("'", 'css'); // \27
Esc::esc('"', 'css'); // \22 Esc::esc('ş', 'css'); // \15F
Esc::esc('🚀', 'css'); // \1F680 Both come out as single CSS escape sequences regardless of how many UTF-8 bytes they used in the input.
Esc::esc('', 'css'); // ''
Esc::esc('42', 'css'); // 42| Location | Why | Use instead |
|---|---|---|
| Selectors built from user input |
escCss is for property values. Selectors built from user input are dangerous even with escaping — historic IE quirks like expression() could trigger script. |
Don't. Use a fixed selector list. |
url(HERE) where HERE is a URL |
The URL itself needs URL encoding before it's a candidate for CSS. |
escUrl, then drop the result into a fixed CSS template. |
Inline style="" attribute |
Two contexts at once: the value first needs to be HTML-attribute-safe, and the CSS inside needs to be CSS-safe. |
escCss on the CSS expression, then rely on the attribute quoting. The fixer below works. |
@import URLs |
Same as url(...) — encode the URL with escUrl first. |
escUrl |
$color = $untrustedColor; // e.g. "red; background: url(...)"
$css = "color: " . Esc::esc($color, 'css') . ";";
echo '<div style="' . $css . '">…</div>';
// <div style="color: red\3B \20 background\3A \20 url\28 \2E \2E \2E \29 ;">…</div>The attribute quoting (style="…") protects the surrounding HTML attribute parser; escCss protects the contents from being interpreted as CSS code.
Same as the attribute context — the matcher needs to address full code points. See Encodings.
-
HTML attribute context — for the
style=""wrapper -
URL context — for
url(...)values - Security Notes
- API Reference →
escCss
Getting Started
Entry Points
Output Contexts
Reference
Production
Migration & Help