diff --git a/articles/components/context-menu/index.asciidoc b/articles/components/context-menu/index.asciidoc
index 022943779a..1b6040542d 100644
--- a/articles/components/context-menu/index.asciidoc
+++ b/articles/components/context-menu/index.asciidoc
@@ -191,6 +191,39 @@ include::{root}/frontend/demo/component/contextmenu/react/context-menu-presentat
endif::[]
--
+== Styling Menu Items
+
+Individual menu items can be styled by [since:com.vaadin:vaadin@V24.3]#applying custom class names# to them, and writing CSS style blocks targeting those class names.
+
+[.example]
+--
+
+ifdef::lit[]
+[source,typescript]
+----
+include::{root}/frontend/demo/component/contextmenu/context-menu-classname.ts[render,tag=snippet,indent=0,group=TypeScript]
+----
+endif::[]
+
+ifdef::flow[]
+[source,java]
+----
+include::{root}/src/main/java/com/vaadin/demo/component/contextmenu/ContextMenuClassname.java[render,tags=snippet,indent=0,group=Java]
+----
+endif::[]
+
+ifdef::react[]
+[source,tsx]
+----
+include::{root}/frontend/demo/component/contextmenu/react/context-menu-classname.tsx[render,tags=snippet,indent=0,group=React]
+----
+endif::[]
+--
+
+.Use theme names instead of class names in V24.2 and older
+[NOTE]
+In versions prior to 24.3, theme names must be used instead (`theme` property / `addThemeNames` Java method). The CSS syntax for targeting a theme name is `[theme~="custom-theme"]`
+
== Disabled Menu Items
You can disable menu items to show that they are unavailable.
diff --git a/frontend/demo/component/contextmenu/context-menu-classname.ts b/frontend/demo/component/contextmenu/context-menu-classname.ts
new file mode 100644
index 0000000000..be0c33612b
--- /dev/null
+++ b/frontend/demo/component/contextmenu/context-menu-classname.ts
@@ -0,0 +1,34 @@
+import 'Frontend/demo/init'; // hidden-source-line
+import { html, LitElement } from 'lit';
+import { customElement, state } from 'lit/decorators.js';
+import '@vaadin/button';
+import '@vaadin/context-menu';
+import type { ContextMenuItem } from '@vaadin/context-menu';
+import { applyTheme } from 'Frontend/generated/theme';
+
+@customElement('context-menu-classname')
+export class Example extends LitElement {
+ protected override createRenderRoot() {
+ const root = super.createRenderRoot();
+ // Apply custom theme (only supported if your app uses one)
+ applyTheme(root);
+ return root;
+ }
+
+ // tag::snippet[]
+ @state()
+ private accessor items: ContextMenuItem[] = [
+ { text: 'Share' },
+ { text: 'Duplicate' },
+ { text: 'Delete', className: 'text-error' },
+ ];
+ // end::snippet[]
+
+ protected override render() {
+ return html`
+
+ Actions
+
+ `;
+ }
+}
diff --git a/frontend/demo/component/contextmenu/react/context-menu-classname.tsx b/frontend/demo/component/contextmenu/react/context-menu-classname.tsx
new file mode 100644
index 0000000000..466a219a5b
--- /dev/null
+++ b/frontend/demo/component/contextmenu/react/context-menu-classname.tsx
@@ -0,0 +1,22 @@
+import { reactExample } from 'Frontend/demo/react-example'; // hidden-source-line
+import React, { useState } from 'react';
+import { Button } from '@hilla/react-components/Button.js';
+import { ContextMenu, type ContextMenuItem } from '@hilla/react-components/ContextMenu.js';
+
+function Example() {
+ // tag::snippet[]
+ const [items] = useState([
+ { text: 'Share' },
+ { text: 'Duplicate' },
+ { text: 'Delete', className: 'text-error' },
+ ]);
+ // end::snippet[]
+
+ return (
+
+
+
+ );
+}
+
+export default reactExample(Example); // hidden-source-line
diff --git a/src/main/java/com/vaadin/demo/component/contextmenu/ContextMenuClassname.java b/src/main/java/com/vaadin/demo/component/contextmenu/ContextMenuClassname.java
new file mode 100644
index 0000000000..6313430217
--- /dev/null
+++ b/src/main/java/com/vaadin/demo/component/contextmenu/ContextMenuClassname.java
@@ -0,0 +1,32 @@
+package com.vaadin.demo.component.contextmenu;
+
+import com.vaadin.demo.DemoExporter; // hidden-source-line
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.contextmenu.ContextMenu;
+import com.vaadin.flow.component.contextmenu.MenuItem;
+import com.vaadin.flow.component.html.Div;
+import com.vaadin.flow.router.Route;
+
+@Route("context-menu-classname")
+public class ContextMenuClassname extends Div {
+
+ public ContextMenuClassname() {
+ Button button = new Button("Actions");
+ ContextMenu menu = new ContextMenu();
+
+ menu.setTarget(button);
+ menu.setOpenOnClick(true);
+
+ menu.addItem("Share");
+ menu.addItem("Duplicate");
+ // tag::snippet[]
+ MenuItem item = menu.addItem("Delete");
+ item.setClassName("text-error");
+ // end::snippet[]
+
+ add(button);
+ }
+
+ public static class Exporter extends DemoExporter { // hidden-source-line
+ } // hidden-source-line
+}