diff --git a/dlls/mshtml/main.c b/dlls/mshtml/main.c
index bbaed1f1967872f40d8771c2c7b4c5a30fc744ee..1a64bdb9b7dc106640b6e8d455a258233f391788 100644
--- a/dlls/mshtml/main.c
+++ b/dlls/mshtml/main.c
@@ -154,7 +154,7 @@ static BOOL read_compat_mode(HKEY key, compat_mode_t *r)
     if(status != ERROR_SUCCESS || type != REG_SZ)
         return FALSE;
 
-    return parse_compat_version(version, r);
+    return parse_compat_version(version, r) != NULL;
 }
 
 static BOOL WINAPI load_compat_settings(INIT_ONCE *once, void *param, void **context)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index d8b4ddef249396bad8d84b6c7c580fb2746fd342..2e30210db2e7013eac35c5e7af0051fd68325140 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -297,6 +297,7 @@ PRIVATE_TID_LIST
 } tid_t;
 
 typedef enum {
+    COMPAT_MODE_INVALID = -1,
     COMPAT_MODE_QUIRKS,
     COMPAT_MODE_IE5,
     COMPAT_MODE_IE7,
@@ -1253,7 +1254,7 @@ HRESULT set_task_timer(HTMLInnerWindow*,LONG,enum timer_type,IDispatch*,LONG*) D
 HRESULT clear_task_timer(HTMLInnerWindow*,DWORD) DECLSPEC_HIDDEN;
 HRESULT clear_animation_timer(HTMLInnerWindow*,DWORD) DECLSPEC_HIDDEN;
 
-BOOL parse_compat_version(const WCHAR*,compat_mode_t*) DECLSPEC_HIDDEN;
+const WCHAR *parse_compat_version(const WCHAR*,compat_mode_t*) DECLSPEC_HIDDEN;
 
 const char *debugstr_mshtml_guid(const GUID*) DECLSPEC_HIDDEN;
 
diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c
index 79918278b3d99702c07b54d0536c3c58f2459adf..02b511e309ebfa0d1ac954880ef6f39a68ce6237 100644
--- a/dlls/mshtml/mutation.c
+++ b/dlls/mshtml/mutation.c
@@ -412,15 +412,20 @@ static void set_document_mode(HTMLDocumentNode *doc, compat_mode_t document_mode
         lock_document_mode(doc);
 }
 
-BOOL parse_compat_version(const WCHAR *version_string, compat_mode_t *r)
+static BOOL is_ua_compatible_delimiter(WCHAR c)
+{
+    return !c || c == ';' || c == ',' || iswspace(c);
+}
+
+const WCHAR *parse_compat_version(const WCHAR *version_string, compat_mode_t *r)
 {
     DWORD version = 0;
     const WCHAR *p;
 
     for(p = version_string; '0' <= *p && *p <= '9'; p++)
         version = version * 10 + *p-'0';
-    if((*p && *p != ';') || p == version_string)
-        return FALSE;
+    if(!is_ua_compatible_delimiter(*p) || p == version_string)
+        return NULL;
 
     switch(version){
     case 5:
@@ -442,13 +447,14 @@ BOOL parse_compat_version(const WCHAR *version_string, compat_mode_t *r)
     default:
         *r = version < 5 ? COMPAT_MODE_QUIRKS : COMPAT_MODE_IE11;
     }
-    return TRUE;
+    return p;
 }
 
 static BOOL parse_ua_compatible(const WCHAR *p, compat_mode_t *r)
 {
     static const WCHAR ie_eqW[] = {'I','E','='};
     static const WCHAR edgeW[] = {'e','d','g','e'};
+    compat_mode_t mode = COMPAT_MODE_INVALID;
 
     TRACE("%s\n", debugstr_w(p));
 
@@ -456,15 +462,22 @@ static BOOL parse_ua_compatible(const WCHAR *p, compat_mode_t *r)
         return FALSE;
     p += 3;
 
-    if(!wcsnicmp(p, edgeW, ARRAY_SIZE(edgeW))) {
-        p += ARRAY_SIZE(edgeW);
-        if(*p && *p != ';')
-            return FALSE;
-        *r = COMPAT_MODE_IE11;
-        return TRUE;
-    }
+    do {
+        while(iswspace(*p)) p++;
+        if(!wcsnicmp(p, edgeW, ARRAY_SIZE(edgeW))) {
+            p += ARRAY_SIZE(edgeW);
+            if(is_ua_compatible_delimiter(*p))
+                mode = COMPAT_MODE_IE11;
+            break;
+        }else if(!(p = parse_compat_version(p, r)))
+            break;
+        if(mode < *r)
+            mode = *r;
+        while(iswspace(*p)) p++;
+    } while(*p++ == ',');
 
-    return parse_compat_version(p, r);
+    *r = mode;
+    return mode != COMPAT_MODE_INVALID;
 }
 
 void process_document_response_headers(HTMLDocumentNode *doc, IBinding *binding)
diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c
index cd4daa84e0a40b22b74807a60ff325df4bbf26b2..d25c7ac0df805101b18c18aacf597be699c6d25c 100644
--- a/dlls/mshtml/tests/dom.c
+++ b/dlls/mshtml/tests/dom.c
@@ -11441,6 +11441,26 @@ static void test_document_mode(IHTMLDocument2 *doc2)
 
 static void test_quirks_mode(void)
 {
+    static const struct {
+        const char *str;
+        unsigned expected_mode;
+    } tests[] = {
+        { "9",          9 },
+        { " \t9 ",      9 },
+        { " 5 , 8 , 7", 8 },
+        { " 8 , 7 , 5", 8 },
+        { " 5 , 5 , 7", 7 },
+        { " 5 , 9 , 7", 9 },
+        { " 5, 7,9",    9 },
+        { " 5, 7;9",    7 },
+        { " 5, edge,8", 11 },
+        { " 5, foo,8",  5 },
+        { " 5, 8,foo",  8 },
+        { " 5, ,,7",    5 },
+        { " 5, , ,7",   5 },
+    };
+    unsigned i;
+
     run_domtest("<html></html>", check_quirks_mode);
     run_domtest("<!DOCTYPE html>\n<html></html>", check_strict_mode);
     run_domtest("<!-- comment --><!DOCTYPE html>\n<html></html>", check_quirks_mode);
@@ -11455,15 +11475,14 @@ static void test_quirks_mode(void)
     if(!is_ie9plus)
         return;
 
-    expected_document_mode = 9;
-    run_domtest("<!DOCTYPE html>\n"
-                "<html>"
-                " <head>"
-                "  <meta http-equiv=\"x-ua-compatible\" content=\"IE=9\" />"
-                " </head>"
-                " <body>"
-                " </body>"
-                "</html>", test_document_mode);
+    for(i = 0; i < ARRAY_SIZE(tests); i++) {
+        char buf[128];
+        expected_document_mode = tests[i].expected_mode;
+        sprintf(buf, "<!DOCTYPE html>\n<html><head>"
+                     " <meta http-equiv=\"x-ua-compatible\" content=\"IE=%s\" />"
+                     "</head><body></body></html>", tests[i].str);
+        run_domtest(buf, test_document_mode);
+    }
 
     expected_document_mode = 8;
     run_domtest("<!DOCTYPE html>\n"