diff --git a/docs/changelog.md b/docs/changelog.md
index 9c9feffe..b583a8f2 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -1,5 +1,13 @@
 # Changelog
 
+### 3.8.1 - bugfixes
+
+ - Fixed `ScopeMismatch` with parametrized cases in non-trivial test
+   trees. `scope` is now correctly handled for (i) `fixture` cases, and
+   (ii) fixtures defined in `conftest.py` files at any depth. Fixes
+   [#311](https://github.com/smarie/python-pytest-cases/issues/311). PR
+   [#317](https://github.com/smarie/python-pytest-cases/pull/317) by [@michele-riva](https://github.com/michele-riva).
+
 ### 3.8.0 - async, generators and strict-markers 
 
  - `@fixture` and `@parametrize` are now async and generator aware. Fixes
diff --git a/src/pytest_cases/case_parametrizer_new.py b/src/pytest_cases/case_parametrizer_new.py
index 361b742e..63135a06 100644
--- a/src/pytest_cases/case_parametrizer_new.py
+++ b/src/pytest_cases/case_parametrizer_new.py
@@ -557,6 +557,21 @@ def get_or_create_case_fixture(case_id,                # type: str
             # Fix the problem with  "case_foo(foo)" leading to the generated fixture having the same name
             existing_fixture_names += fixtures_in_cases_module
 
+    # If the fixture will be injected in a conftest, make sure its name
+    # is unique. Include also its scope to avoid conflicts. See #311.
+    # Notice target_host.__name__ may just be 'conftest' when tests
+    # are simple modules or a more complicated fully qualified name
+    # when the test suite is a package (i.e., with __init__.py). For
+    # example, target_host.__name__ would be 'tests.conftest' when
+    # executing tests from within 'base' in the following tree:
+    # base/
+    #    tests/
+    #       __init__.py
+    #       conftest.py
+    if 'conftest' in target_host.__name__:
+        extra = target_host.__name__.replace('.', '_')
+        case_id = extra + '_' + case_id + '_with_scope_' + scope
+
     def name_changer(name, i):
         return name + '_' * i
 
diff --git a/src/pytest_cases/fixture_parametrize_plus.py b/src/pytest_cases/fixture_parametrize_plus.py
index d70159c2..13a73431 100644
--- a/src/pytest_cases/fixture_parametrize_plus.py
+++ b/src/pytest_cases/fixture_parametrize_plus.py
@@ -316,6 +316,7 @@ def create(cls,
                i,                  # type: int
                argvalue,           # type: Any
                id,                 # type: Union[str, Callable]
+               scope=None,         # type: str
                hook=None,          # type: Callable
                debug=False         # type: bool
                ):
@@ -362,7 +363,7 @@ def create(cls,
 
         # Create the fixture. IMPORTANT auto_simplify=True : we create a NON-parametrized fixture.
         _create_param_fixture(new_fixture_host, argname=p_fix_name, argvalues=(argvalue,),
-                              hook=hook, auto_simplify=True, debug=debug)
+                              scope=scope, hook=hook, auto_simplify=True, debug=debug)
 
         # Create the alternative
         argvals = (argvalue,) if nb_params == 1 else argvalue
@@ -426,6 +427,7 @@ def create(cls,
                to_i,              # type: int
                argvalues,         # type: Any
                ids,               # type: Union[Sequence[str], Callable]
+               scope="function",  # type: str
                hook=None,         # type: Callable
                debug=False        # type: bool
                ):
@@ -493,8 +495,8 @@ def create(cls,
                 else:
                     ids = [mini_idvalset(argnames, vals, i) for i, vals in enumerate(unmarked_argvalues)]
 
-        _create_param_fixture(new_fixture_host, argname=p_fix_name, argvalues=argvalues, ids=ids, hook=hook,
-                              debug=debug)
+        _create_param_fixture(new_fixture_host, argname=p_fix_name, argvalues=argvalues, ids=ids,
+                              scope=scope, hook=hook, debug=debug)
 
         # Create the corresponding alternative
         # note: as opposed to SingleParamAlternative, no need to move the custom id/marks to the ParamAlternative
@@ -874,6 +876,7 @@ def _create_params_alt(fh, test_func, union_name, from_i, to_i, hook):  # noqa
                 return SingleParamAlternative.create(new_fixture_host=fh, test_func=test_func,
                                                      param_union_name=union_name, argnames=argnames, i=i,
                                                      argvalue=marked_argvalues[i], id=_id,
+                                                     scope="function" if scope is None else scope,
                                                      hook=hook, debug=debug)
             else:
                 # If an explicit list of ids was provided, slice it. Otherwise the provided callable will be used later
@@ -882,6 +885,7 @@ def _create_params_alt(fh, test_func, union_name, from_i, to_i, hook):  # noqa
                 return MultiParamAlternative.create(new_fixture_host=fh, test_func=test_func,
                                                     param_union_name=union_name, argnames=argnames, from_i=from_i,
                                                     to_i=to_i, argvalues=marked_argvalues[from_i:to_i], ids=_ids,
+                                                    scope="function" if scope is None else scope,
                                                     hook=hook, debug=debug)
 
 
diff --git a/tests/cases/issues/issue_311/cases.py b/tests/cases/issues/issue_311/cases.py
new file mode 100644
index 00000000..cf72361a
--- /dev/null
+++ b/tests/cases/issues/issue_311/cases.py
@@ -0,0 +1,6 @@
+from pytest_cases import parametrize
+
+
+@parametrize(arg=(1,))
+def case_parametrized(arg):
+    return arg
diff --git a/tests/cases/issues/issue_311/conftest.py b/tests/cases/issues/issue_311/conftest.py
new file mode 100644
index 00000000..f6be43e3
--- /dev/null
+++ b/tests/cases/issues/issue_311/conftest.py
@@ -0,0 +1,9 @@
+from pytest_cases import fixture, parametrize_with_cases
+
+
+@fixture(scope='session')
+@parametrize_with_cases('arg', cases='cases', scope='session')
+def scope_mismatch(arg):
+    return [arg]
+
+session_scoped = scope_mismatch
diff --git a/tests/cases/issues/issue_311/test_issue_311/conftest.py b/tests/cases/issues/issue_311/test_issue_311/conftest.py
new file mode 100644
index 00000000..535ff9d2
--- /dev/null
+++ b/tests/cases/issues/issue_311/test_issue_311/conftest.py
@@ -0,0 +1,7 @@
+from pytest_cases import fixture, parametrize_with_cases
+
+
+@fixture(scope='class')
+@parametrize_with_cases('arg', cases='cases', scope='class')
+def class_scoped(arg):
+    return [arg]
diff --git a/tests/cases/issues/issue_311/test_issue_311/test_issue_311.py b/tests/cases/issues/issue_311/test_issue_311/test_issue_311.py
new file mode 100644
index 00000000..1e3ad83e
--- /dev/null
+++ b/tests/cases/issues/issue_311/test_issue_311/test_issue_311.py
@@ -0,0 +1,49 @@
+from pytest_cases import fixture, parametrize_with_cases
+
+
+@fixture
+@parametrize_with_cases('arg', cases='cases')
+def function_scoped(arg):
+    return [arg]
+
+# This tests would fail with a ScopeMismatch
+# during collection before #317
+def test_scope_mismatch_collection(scope_mismatch):
+    assert scope_mismatch == [1]
+
+def test_scopes(session_scoped, function_scoped, class_scoped):
+    session_scoped.append(2)
+    function_scoped.append(2)
+    class_scoped.append(2)
+    assert session_scoped == [1, 2]
+    assert function_scoped == [1, 2]
+    assert class_scoped == [1, 2]
+
+def test_scopes_again(session_scoped, function_scoped, class_scoped):
+    session_scoped.append(3)
+    function_scoped.append(3)
+    class_scoped.append(3)
+    assert session_scoped == [1, 2, 3]
+    assert function_scoped == [1, 3]
+    assert class_scoped == [1, 3]
+
+
+class TestScopesInClass:
+
+    def test_scopes_in_class(self, session_scoped,
+                             function_scoped, class_scoped):
+        session_scoped.append(4)
+        function_scoped.append(4)
+        class_scoped.append(4)
+        assert session_scoped == [1, 2, 3, 4]
+        assert function_scoped == [1, 4]
+        assert class_scoped == [1, 4]
+
+    def test_scopes_in_class_again(self, session_scoped,
+                                   function_scoped, class_scoped):
+        session_scoped.append(5)
+        function_scoped.append(5)
+        class_scoped.append(5)
+        assert session_scoped == [1, 2, 3, 4, 5]
+        assert function_scoped == [1, 5]
+        assert class_scoped == [1, 4, 5]
