diff --git a/src/entry.c b/src/entry.c
index e68ccfa..22b2788 100644
--- a/src/entry.c
+++ b/src/entry.c
@@ -121,6 +121,7 @@ int xcb_xrm_entry_parse(const char *_str, xcb_xrm_entry_t **_entry, bool resourc
     xcb_xrm_component_t *last;
     char *value;
     char *value_walk;
+    xcb_xrm_binding_type_t binding_type;
 
     xcb_xrm_entry_parser_state_t state = {
         .chunk = CS_INITIAL,
@@ -166,8 +167,19 @@ int xcb_xrm_entry_parse(const char *_str, xcb_xrm_entry_t **_entry, bool resourc
                     goto done_error;
                 }
 
+                /* Subsequent bindings must be collapsed into a loose binding if at
+                 * least one was a loose binding and a tight binding otherwise. */
+                binding_type = (*walk == '*') ? BT_LOOSE : BT_TIGHT;
+                while (*(walk + 1) == '.' || *(walk + 1) == '*') {
+                    walk++;
+
+                    if (*walk == '*') {
+                        binding_type = BT_LOOSE;
+                    }
+                }
+
                 xcb_xrm_finalize_component(entry, &state);
-                state.current_binding_type = (*walk == '.') ? BT_TIGHT : BT_LOOSE;
+                state.current_binding_type = binding_type;
                 break;
             case '?':
                 state.chunk = MAX(state.chunk, CS_COMPONENTS);
diff --git a/tests/tests_match.c b/tests/tests_match.c
index b2b2495..1841232 100644
--- a/tests/tests_match.c
+++ b/tests/tests_match.c
@@ -95,6 +95,7 @@ static int test_get_resource(void) {
     err |= check_get_resource("First.?.third: 1", "First.second.third", "", "1", false);
     err |= check_get_resource("First.?.?.fourth: 1", "First.second.third.fourth", "", "1", false);
     err |= check_get_resource("*second: 1", "First.second", "", "1", false);
+    err |= check_get_resource(".second: 1", "First.second", "", NULL, false);
     err |= check_get_resource("*third: 1", "First.second.third", "", "1", false);
     err |= check_get_resource("First*second: 1", "First.second", "", "1", false);
     err |= check_get_resource("First*third: 1", "First.second.third", "", "1", false);
@@ -110,6 +111,17 @@ static int test_get_resource(void) {
     err |= check_get_resource("First:", "First", "", "", false);
     err |= check_get_resource("First: ", "First", "", "", false);
     err |= check_get_resource("First: \t ", "First", "", "", false);
+    /* Consecutive bindings */
+    err |= check_get_resource("*.bar: 1", "foo.foo.bar", "", "1", false);
+    err |= check_get_resource("...bar: 1", "foo.bar", "", NULL, false);
+    err |= check_get_resource("...bar: 1", "foo.foo.foo.bar", "", NULL, false);
+    err |= check_get_resource("***bar: 1", "foo.bar", "", "1", false);
+    err |= check_get_resource(".*.bar: 1", "foo.bar", "", "1", false);
+    err |= check_get_resource(".*.bar: 1", "foo.foo.bar", "", "1", false);
+    err |= check_get_resource("..*bar: 1", "foo.foo.foo.foo.bar", "", "1", false);
+    err |= check_get_resource("a.*.z: 1", "a.b.c.d.e.f.z", "", "1", false);
+    err |= check_get_resource("a...z: 1", "a.z", "", "1", false);
+    err |= check_get_resource("a...z: 1", "a.b.z", "", NULL, false);
     /* Matching among multiple entries */
     err |= check_get_resource(
             "First: 1\n"