diff --git a/docs/pages/resources/changelog.md b/docs/pages/resources/changelog.md
index e4dab556..92668385 100644
--- a/docs/pages/resources/changelog.md
+++ b/docs/pages/resources/changelog.md
@@ -12,6 +12,10 @@ Components with the Experimental bad
New versions of Shoelace are released as-needed and generally occur when a critical mass of changes have accumulated. At any time, you can see what's coming in the next release by visiting [next.shoelace.style](https://next.shoelace.style).
+## Next
+
+- Fixed accessibility issues for elements that are closed while having slotted focused children.
+
## 2.20.0
- Added the ability to set a custom snap function and use `repeat(n)` to `` [#2340]
diff --git a/src/components/alert/alert.component.ts b/src/components/alert/alert.component.ts
index 2f2ffbd9..7b442cd6 100644
--- a/src/components/alert/alert.component.ts
+++ b/src/components/alert/alert.component.ts
@@ -1,4 +1,5 @@
import { animateTo, stopAnimations } from '../../internal/animate.js';
+import { blurActiveElement } from '../../internal/closeActiveElement.js';
import { classMap } from 'lit/directives/class-map.js';
import { getAnimation, setDefaultAnimation } from '../../utilities/animation-registry.js';
import { HasSlotController } from '../../internal/slot.js';
@@ -157,6 +158,7 @@ export default class SlAlert extends ShoelaceElement {
this.emit('sl-after-show');
} else {
// Hide
+ blurActiveElement(this);
this.emit('sl-hide');
clearTimeout(this.autoHideTimeout);
diff --git a/src/components/dialog/dialog.component.ts b/src/components/dialog/dialog.component.ts
index 54f62d02..724b9c0b 100644
--- a/src/components/dialog/dialog.component.ts
+++ b/src/components/dialog/dialog.component.ts
@@ -1,4 +1,5 @@
import { animateTo, stopAnimations } from '../../internal/animate.js';
+import { blurActiveElement } from '../../internal/closeActiveElement.js';
import { classMap } from 'lit/directives/class-map.js';
import { getAnimation, setDefaultAnimation } from '../../utilities/animation-registry.js';
import { HasSlotController } from '../../internal/slot.js';
@@ -208,6 +209,7 @@ export default class SlDialog extends ShoelaceElement {
this.emit('sl-after-show');
} else {
// Hide
+ blurActiveElement(this);
this.emit('sl-hide');
this.removeOpenListeners();
this.modal.deactivate();
diff --git a/src/components/drawer/drawer.component.ts b/src/components/drawer/drawer.component.ts
index 21d4207f..a1ce0c52 100644
--- a/src/components/drawer/drawer.component.ts
+++ b/src/components/drawer/drawer.component.ts
@@ -1,4 +1,5 @@
import { animateTo, stopAnimations } from '../../internal/animate.js';
+import { blurActiveElement } from '../../internal/closeActiveElement.js';
import { classMap } from 'lit/directives/class-map.js';
import { getAnimation, setDefaultAnimation } from '../../utilities/animation-registry.js';
import { HasSlotController } from '../../internal/slot.js';
@@ -237,6 +238,7 @@ export default class SlDrawer extends ShoelaceElement {
this.emit('sl-after-show');
} else {
// Hide
+ blurActiveElement(this);
this.emit('sl-hide');
this.removeOpenListeners();
diff --git a/src/internal/closeActiveElement.ts b/src/internal/closeActiveElement.ts
new file mode 100644
index 00000000..0602a0ea
--- /dev/null
+++ b/src/internal/closeActiveElement.ts
@@ -0,0 +1,13 @@
+/**
+ * Calls the blur method on the current active element if it is a child of the provided element.
+ * Needed for fixing a11y errors in console.
+ * @see https://github.com/shoelace-style/shoelace/issues/2283
+ * @param elm The element to check
+ */
+export const blurActiveElement = (elm: HTMLElement) => {
+ const { activeElement } = document;
+ console.log(activeElement, elm);
+ if (activeElement && elm.contains(activeElement)) {
+ (document.activeElement as HTMLElement)?.blur();
+ }
+};