field_label_visibility
Field Label Visibility adds a per-widget settings card to Manage form display that lets administrators hide, customize and style the label of any field on selected content types — without touching the field configuration or writing a custom theme.
Features
Each widget exposes 10 controls on Manage form display:
- Hide label — visually hides the label (still accessible to screen readers). Master switch: hides the rest of the controls.
- Custom label — replaces the field label text. Accepts
Singular|Pluralsyntax when the next toggle is on. - Singular / Plural — when enabled, parses the custom label as
Singular|Pluraland picks the singular form if the field currently holds 1 item, plural otherwise. - HTML tag — wraps the label in
h1-h6,p,legendorlabel. - CSS classes — adds a sanitized list of classes.
- HTML id — adds an
idattribute, validated against the HTML id regex. - CKEditor-style toolbar — alignment radios (default / left / center / right) plus Bold, Italic and Underline checkboxes, grouped in a single horizontal toolbar with SVG icons and a CKEditor-like active state.
Use cases
- Make the field label render as a heading (
h2) instead of a regular form label, without writing a Twig override. - Replace a generic field name with a marketing copy on a per-content-type basis.
- Hide labels on summary/teaser fields without touching the field config.
- Apply alignment + format (bold / italic / underline) to a label for visual emphasis.
- Render plural-aware labels:
Image|Imagesautomatically pluralizes based on the current item count.
Accessibility
- The original
label for="…"is always preserved in the DOM, even when a heading or paragraph tag is selected. The input keeps an accessible name on every form. - The injected markup is decorative (
aria-hidden="true"); the accessible name is the originallabel, whose#titleis updated to mirror the custom text. Screen-reader users and visual users hear/see the same string.
Security
- Tag is allowlisted; CSS classes pass through a regex filter; id is regex-validated; alignment values are allowlisted; Bold/Italic/Underline are cast to strict booleans; text is escaped with
Html::escape()before concatenation. - Server-side validators reject invalid id and disallowed CSS class characters at submit time.
- The admin form is GET-only and inherits CSRF protection from
ConfigFormBase. Bundles are intersected with realnode_typemachine names on submit (defense in depth). - Module config is propagated as a cache dependency on every node form widget, so toggling bundles invalidates cached forms (Dynamic Page Cache, BigPipe).
Requirements
- Drupal 10.3+ or Drupal 11.
- PHP 8.3+.
- Core modules
fieldandnode.field_uiis recommended for the Manage form display UI but is not a hard dependency — runtime application keeps working without it once the settings are saved.
Installation
composer require drupal/field_label_visibility drush en field_label_visibility
Configuration
- Go to Configuration → User interface → Field Label Visibility.
- Tick the content types where the per-widget options should be exposed. Save.
- Visit Structure → Content types → [your type] → Manage form display, click the cog icon next to any widget, and configure the 10 controls.
Tests
Ships with kernel coverage (14 tests, 191 assertions): bundle gating, third-party form shape, hide_label precedence, the happy path, every injected tag is decorative, Singular/Plural in both branches and OFF mode, invalid id is dropped, XSS resistance against four payloads, #prefix concatenation, custom label propagation to the original #title, settings summary, and multi-value (cardinality > 1) propagation across all deltas.
Issues
Bug reports and feature requests can be filed in the issue queue.