diff --git a/.changeset/add-use-media-caption-html.md b/.changeset/add-use-media-caption-html.md
new file mode 100644
index 000000000000..c827d2e9ddd6
--- /dev/null
+++ b/.changeset/add-use-media-caption-html.md
@@ -0,0 +1,5 @@
+---
+"@biomejs/biome": minor
+---
+
+Added the rule [`useMediaCaption`](https://biomejs.dev/linter/rules/use-media-caption/) to the HTML language. Enforces that `audio` and `video` elements have a `track` element with `kind="captions"` for accessibility. Muted videos are allowed without captions.
diff --git a/crates/biome_html_analyze/src/lint/a11y.rs b/crates/biome_html_analyze/src/lint/a11y.rs
index 6a1e3562957f..8a7424b25536 100644
--- a/crates/biome_html_analyze/src/lint/a11y.rs
+++ b/crates/biome_html_analyze/src/lint/a11y.rs
@@ -15,6 +15,7 @@ pub mod use_aria_props_for_role;
pub mod use_button_type;
pub mod use_html_lang;
pub mod use_iframe_title;
+pub mod use_media_caption;
pub mod use_valid_aria_role;
pub mod use_valid_lang;
-declare_lint_group! { pub A11y { name : "a11y" , rules : [self :: no_access_key :: NoAccessKey , self :: no_autofocus :: NoAutofocus , self :: no_distracting_elements :: NoDistractingElements , self :: no_header_scope :: NoHeaderScope , self :: no_positive_tabindex :: NoPositiveTabindex , self :: no_redundant_alt :: NoRedundantAlt , self :: no_svg_without_title :: NoSvgWithoutTitle , self :: use_alt_text :: UseAltText , self :: use_aria_props_for_role :: UseAriaPropsForRole , self :: use_button_type :: UseButtonType , self :: use_html_lang :: UseHtmlLang , self :: use_iframe_title :: UseIframeTitle , self :: use_valid_aria_role :: UseValidAriaRole , self :: use_valid_lang :: UseValidLang ,] } }
+declare_lint_group! { pub A11y { name : "a11y" , rules : [self :: no_access_key :: NoAccessKey , self :: no_autofocus :: NoAutofocus , self :: no_distracting_elements :: NoDistractingElements , self :: no_header_scope :: NoHeaderScope , self :: no_positive_tabindex :: NoPositiveTabindex , self :: no_redundant_alt :: NoRedundantAlt , self :: no_svg_without_title :: NoSvgWithoutTitle , self :: use_alt_text :: UseAltText , self :: use_aria_props_for_role :: UseAriaPropsForRole , self :: use_button_type :: UseButtonType , self :: use_html_lang :: UseHtmlLang , self :: use_iframe_title :: UseIframeTitle , self :: use_media_caption :: UseMediaCaption , self :: use_valid_aria_role :: UseValidAriaRole , self :: use_valid_lang :: UseValidLang ,] } }
diff --git a/crates/biome_html_analyze/src/lint/a11y/use_media_caption.rs b/crates/biome_html_analyze/src/lint/a11y/use_media_caption.rs
new file mode 100644
index 000000000000..d103983bb20b
--- /dev/null
+++ b/crates/biome_html_analyze/src/lint/a11y/use_media_caption.rs
@@ -0,0 +1,160 @@
+use biome_analyze::{
+ Ast, Rule, RuleDiagnostic, RuleSource, context::RuleContext, declare_lint_rule,
+};
+use biome_console::markup;
+use biome_diagnostics::Severity;
+use biome_html_syntax::{AnyHtmlElement, HtmlElementList, HtmlFileSource};
+use biome_rowan::AstNode;
+
+declare_lint_rule! {
+ /// Enforces that `audio` and `video` elements must have a `track` for captions.
+ ///
+ /// Captions support users with hearing-impairments. They should be a transcription
+ /// or translation of the dialogue, sound effects, musical cues, and other relevant
+ /// audio information.
+ ///
+ /// :::note
+ /// In `.html` files, this rule matches element names case-insensitively (e.g., `