From 52ac756518a708c39ad0ed5dc553ac56c4f59f4b Mon Sep 17 00:00:00 2001 From: adamsilverstein Date: Tue, 21 Jul 2026 12:30:21 -0700 Subject: [PATCH] Notes: keep the highlight tint at one low alpha, emphasize with an underline The per-author tint sits behind the marker's text, so it is subtracted from whatever text/background contrast the theme provides, and the canvas background comes from theme.json, so the composited result cannot be measured from CSS. Doubling the alpha on hover, focus, and selection doubled that loss: on a mid-tone canvas an orange-authored marker dropped from a passing 4.54:1 to 2.67:1. Hold the tint at the rest alpha in every state and carry emphasis with an opaque underline in the author's color instead, which reads more strongly than a heavier wash without touching what sits behind the text. --- packages/editor/CHANGELOG.md | 1 + .../collab-sidebar/note-highlight-styles.js | 46 ++++++++++++++----- .../test/note-highlight-styles.js | 34 ++++++++++++-- .../specs/editor/various/block-notes.spec.js | 38 +++++++++++---- 4 files changed, 93 insertions(+), 26 deletions(-) diff --git a/packages/editor/CHANGELOG.md b/packages/editor/CHANGELOG.md index aaeed12c50c67c..766c6ab2e2f89e 100644 --- a/packages/editor/CHANGELOG.md +++ b/packages/editor/CHANGELOG.md @@ -8,6 +8,7 @@ ### Bug Fixes +- Notes: Stop deepening an inline note marker's tint on hover, focus, and selection. The tint sits behind the text and is subtracted from whatever contrast the theme provides, so emphasis is now an author-colored underline instead ([#80543](https://github.com/WordPress/gutenberg/issues/80543)). - `mediaUpload`: Add an `isTransportOnly` parameter, set by the `@wordpress/upload-media` queue, which owns progress tracking and save locking for its own items and uses this function only as its server transport. Fixes the progress snackbar showing "1 of 2" for a single HEIC upload in Safari ([#80369](https://github.com/WordPress/gutenberg/issues/80369)). ## 14.51.0 (2026-07-14) diff --git a/packages/editor/src/components/collab-sidebar/note-highlight-styles.js b/packages/editor/src/components/collab-sidebar/note-highlight-styles.js index b0c53e178c14ae..86ad5a693c5e34 100644 --- a/packages/editor/src/components/collab-sidebar/note-highlight-styles.js +++ b/packages/editor/src/components/collab-sidebar/note-highlight-styles.js @@ -9,11 +9,31 @@ import { useStyleOverride } from '@wordpress/block-editor'; */ import { getAvatarBorderColor } from './utils'; -// Hex alpha suffixes for the rest / active states. Kept low so the marker -// reads as a soft tint at rest and gets noticeably stronger when focused or -// hovered. (0x40 ≈ 25%, 0x80 ≈ 50%.) -const REST_ALPHA = '40'; -const ACTIVE_ALPHA = '80'; +/* + * Hex alpha suffix for the tint painted behind the marker's text. One low value + * for every state, on purpose: the tint sits behind the glyphs, so raising it + * eats into whatever text/background contrast the theme already provides, and + * the canvas background comes from `theme.json`, so the composited result + * cannot be measured from CSS. (0x40 ≈ 25%.) + */ +const TINT_ALPHA = '40'; + +/** + * Emphasis for hover / focus / the selected note. Carried by an opaque + * underline in the author's color rather than a stronger tint, so the marker + * reads more strongly without changing what sits behind the text. + * + * @param {string} color The author's `#RRGGBB` color. + * @return {string} Declarations for the emphasized state. + */ +function emphasis( color ) { + return ( + 'text-decoration-line:underline;' + + `text-decoration-color:${ color };` + + 'text-decoration-thickness:0.125em;' + + 'text-underline-offset:0.15em;' + ); +} // Reset the browser's default `` styling so the per-author rules below // are what readers actually see (without it, `mark` ships with a bright yellow @@ -25,6 +45,10 @@ const BASE_RESET = 'mark.wp-note{background-color:transparent;color:inherit;}'; * Build the CSS rule set that tints each inline-note marker with its author's * avatar color. Pure helper extracted so it can be unit-tested without React. * + * The tint stays at a single low alpha in every state and emphasis is expressed + * as an underline, so marking a note can only cost the theme's text contrast + * the one fixed amount, never more when the note is hovered or selected. + * * @param {Array} threads Unresolved note threads (each with `id` and `author`). * @param {string|null} selectedId ID of the currently selected note, if any. * @return {string} A serialized CSS string targeting the in-content note markers. @@ -43,14 +67,12 @@ export function buildHighlightCss( threads, selectedId = null ) { // from stored data. const escapedId = String( thread.id ).replace( /["\\]/g, '\\$&' ); const sel = `mark.wp-note[data-id="${ escapedId }"]`; - rules.push( `${ sel }{background-color:${ color }${ REST_ALPHA };}` ); + rules.push( `${ sel }{background-color:${ color }${ TINT_ALPHA };}` ); rules.push( - `${ sel }:hover,${ sel }:focus-within{background-color:${ color }${ ACTIVE_ALPHA };}` + `${ sel }:hover,${ sel }:focus-within{${ emphasis( color ) }}` ); if ( selectedId && String( selectedId ) === String( thread.id ) ) { - rules.push( - `${ sel }{background-color:${ color }${ ACTIVE_ALPHA };}` - ); + rules.push( `${ sel }{${ emphasis( color ) }}` ); } } return rules.join( '' ); @@ -65,8 +87,8 @@ export function buildHighlightCss( threads, selectedId = null ) { * Uses `useStyleOverride` so the styles reach the iframed canvas; a plain * `