diff --git a/CHANGES.md b/CHANGES.md
index a5ba4a83d8..6473bcde11 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -19,6 +19,7 @@ Core Grammars:
- enh(bash) add reserved keywords `time` and `coproc` [Álvaro Mondéjar][]
- fix(c) - Fixed hex numbers with decimals [Dxuian]
- fix(ruby) - fix `|=` operator false positives (as block arguments) [Aboobacker MK]
+- fix(css) - Fixed css escape chars [Dxuian]
New Grammars:
diff --git a/src/languages/css.js b/src/languages/css.js
index e76259c266..ffc787a3ea 100644
--- a/src/languages/css.js
+++ b/src/languages/css.js
@@ -13,8 +13,9 @@ export default function(hljs) {
const modes = css.MODES(hljs);
const VENDOR_PREFIX = { begin: /-(webkit|moz|ms|o)-(?=[a-z])/ };
const AT_MODIFIERS = "and or not only";
- const AT_PROPERTY_RE = /@-?\w[\w]*(-\w+)*/; // @-webkit-keyframes
- const IDENT_RE = '[a-zA-Z-][a-zA-Z0-9_-]*';
+ const AT_PROPERTY_RE = /@-?\b\w[\w-]*\b/; // @-webkit-keyframes
+ const IDENT_RE = /[a-zA-Z-][a-zA-Z0-9_-]*/;
+ const SELECTOR_RE = /[a-zA-Z_-]([a-zA-Z0-9_-]|\\[.$^&+|~=:<>*\[\]@])*/;
const STRINGS = [
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE
@@ -37,12 +38,12 @@ export default function(hljs) {
modes.CSS_NUMBER_MODE,
{
className: 'selector-id',
- begin: /#[A-Za-z0-9_-]+/,
+ begin: regex.concat(/#/, IDENT_RE),
relevance: 0
},
{
className: 'selector-class',
- begin: '\\.' + IDENT_RE,
+ begin: regex.concat(/\./, SELECTOR_RE),
relevance: 0
},
modes.ATTRIBUTE_SELECTOR_MODE,
diff --git a/test/markup/css/pseudo-selector.expect.txt b/test/markup/css/pseudo-selector.expect.txt
index b684638e6f..cde342fffd 100644
--- a/test/markup/css/pseudo-selector.expect.txt
+++ b/test/markup/css/pseudo-selector.expect.txt
@@ -22,3 +22,57 @@
font-weight: bold;
color: brown;
}
+
+
+.dark\:hover\:bg-sky-900\:text-white\:border\:rounded\:shadow:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgb(12 74 110 / var(--tw-bg-opacity));
+ color: white;
+ border: 1px solid white;
+ border-radius: 0.5rem;
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
+}
+
+.class\:name {
+ color: red;
+}
+
+.class\.name {
+ font-weight: bold;
+}
+
+.at\@sign {
+ font-family: monospace;
+}
+
+.aske\$dollar {
+ color: green;
+}
+
+.caret\^sign {
+ text-transform: uppercase;
+}
+
+.and\&sign {
+ background-color: yellow;
+}
+
+.asterisk\*sign {
+ font-size: 1.2em;
+}
+
+.plus\+sign {
+ letter-spacing: 2px;
+}
+
+.pipe\|class {
+ border: 1px solid black;
+}
+
+.tilde\~sign {
+ text-shadow: 1px 1px 2px gray;
+}
+
+.equals\=sign {
+ text-align: center;
+}
\ No newline at end of file
diff --git a/test/markup/css/pseudo-selector.txt b/test/markup/css/pseudo-selector.txt
index 3365f6583a..c5bc0b8590 100644
--- a/test/markup/css/pseudo-selector.txt
+++ b/test/markup/css/pseudo-selector.txt
@@ -22,3 +22,57 @@ p::first-letter {
font-weight: bold;
color: brown;
}
+
+
+.dark\:hover\:bg-sky-900\:text-white\:border\:rounded\:shadow:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgb(12 74 110 / var(--tw-bg-opacity));
+ color: white;
+ border: 1px solid white;
+ border-radius: 0.5rem;
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
+}
+
+.class\:name {
+ color: red;
+}
+
+.class\.name {
+ font-weight: bold;
+}
+
+.at\@sign {
+ font-family: monospace;
+}
+
+.aske\$dollar {
+ color: green;
+}
+
+.caret\^sign {
+ text-transform: uppercase;
+}
+
+.and\&sign {
+ background-color: yellow;
+}
+
+.asterisk\*sign {
+ font-size: 1.2em;
+}
+
+.plus\+sign {
+ letter-spacing: 2px;
+}
+
+.pipe\|class {
+ border: 1px solid black;
+}
+
+.tilde\~sign {
+ text-shadow: 1px 1px 2px gray;
+}
+
+.equals\=sign {
+ text-align: center;
+}
\ No newline at end of file