w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.52k stars 673 forks source link

[css-highlight-api] Support for some font styles and decorations #8355

Open fabiospampinato opened 1 year ago

fabiospampinato commented 1 year ago

I'm currently building a new code editor for the web that uses the CSS Custom Highlight API for syntax highlighting, with the idea being that it would simplify things significantly while at the same time improve performance.

But, some basic forms of font styles and decoration (italic, bold, underline, strikethrough) are not supported by this API. As I understand it only properties that can be applied efficiently are supported, but arguably a subset of the font-style and font-decoration properties can be applied efficiently in some scenarios, even if this capability were limited to monospaced fonts it would unconstraint my use case, which would be amazing.

As far as I know the folks at VS Code are also exploring using highlights for syntax highlighting, which would potentially enable optimized syntax highlighting for millions of developers worldwide, so it'd be extra nice if highlights could be used for 100% of normal grammar-based syntax highlighting, rather than the current 99%.

SebastianZ commented 1 year ago

Decorations like underlines and strikethroughs are already supported via text-decoration. The spec. currently explicitly excludes layout-affecting properties.

Sebastian

fabiospampinato commented 1 year ago

Oh nice! I was basing my assumption on an outdated article apparently.

A way to make text italic and/or bold seems to be the only thing missing before this API can be used fully for syntax highlighting then. I mean it's not the end of the world if those are not supported, but ideally a modern syntax highlighter should support those.

sanketj commented 1 year ago

Custom highlights support the same set of properties as all other highlight pseudos. These are defined in the CSS pseudo spec: https://drafts.csswg.org/css-pseudo-4/#highlight-styling.

@fantasai Has adding support for bold/italic come up in past discussions?

samuelbradshaw commented 1 year ago

I would like to see this as well. However, I suspect that bold and italic would be considered "layout-affecting" because font weight and style can make things wider or narrower.

fabiospampinato commented 1 year ago

@samuelbradshaw not if the font is monospaced, presumably. Like in an editor kind of situation we want each character to have the same height and width as any other character, it doesn't matter if it's italic or bold or not.

frivoal commented 1 year ago

To avoid being layout affecting, we'd need more than just a monospaced font. We'd need the two fonts we're swapping from/to to be:

All in all, swapping fonts is, in the general case, layout affecting, and I doubt that's going to be practical here.

fabiospampinato commented 1 year ago

I feel like this could be special cased in practice though, like if the user explicitly wants to make the font bold or italic via custom highlights then hopefully the browser could measure the box that a regular character would occupy, render the bold or italic character in there, and chop away anything that overflows, forcing the highlight to not be layout affecting, whether it would have been layout affecting all things considered or not.

Like I think there's enough good that would be unlocked by this capability that is worth considering.

fabiospampinato commented 1 year ago

Another property missing seems opacity. Which presumably would make the text more transparent, which won't cause any layout shifts. Though I think that need would disappear once color-mix is able to manipulated inherited colors, if that ships.

fabiospampinato commented 1 year ago

text-decoration-color seems missing too, which is a bit annoying because it makes highlighting the same thing with the same colors, but once with normal CSS and once with custom highlights, slightly inconsistent with each other.

schenney-chromium commented 1 year ago

All of the text-decoration-* properties are supported, including color. From the Pseudos 4 spec: "text-decoration ... and its associated properties (including text-underline-position and text-underline-offset)". The spec is only calling out the text decoration properties that begin with text-underline- to be clear that those are decoration properties.

fabiospampinato commented 1 year ago

@schenney-chromium empirically under Chrome v116.0.5845.97, under Electron v26.1.0, text-decoration-color inside a custom highlight is just not working for me 🤷‍♂️

yisibl commented 10 months ago

Is it possible to support background-image?

schenney-chromium commented 10 months ago

@fabiospampinato I have no idea why that would not be working. There are numerous WPT tests covering the feature that might guide how to use it (see https://wpt.fyi/results/css/css-highlight-api/painting?label=experimental&label=master&aligned). It might just be that the feature is not enabled.

@yisibl Background-image poses significant challenges, first among them being the definition of the positioning area to allow for good behavior on highlights of numerous sizes and shapes, with different fonts and highlighted content. I don't think there's any desire to standardize such a thing at this time.

bramus commented 9 months ago

(#) To avoid being layout affecting, we'd need more than just a monospaced font. …

What if we added this with the mentioned bullets as guidelines to authors? There are fonts out there that tick all boxes I think, e.g. https://fonts.google.com/specimen/Roboto+Mono/tester

The author need is syntax highlighting source code, with a special mention of highlighting markdown à la iA Writer:

image

samuelbradshaw commented 6 months ago

@fabiospampinato, could you emulate bold by using text-shadow, which the highlight API supports?

For those familiar with the spec and what might be considered "layout-affecting," would outline and box-shadow properties be safe to include in the highlight API? These could be ways to emulate border, given that border properties are out.

fabiospampinato commented 6 months ago

@fabiospampinato, could you emulate bold by using text-shadow, which the highlight API supports?

Not really, the effect is pretty different 🤔 Ideally I think we want the real thing, real bold variants, when it's possible to do that. For some characters of some fonts this should be implementable, i.e. it's possible for bold characters to occupy the same space as non-bold characters, especially in monospaced fonts using for development, which is where the Highlight API provides sort of a step change improvement.

johannesmutter commented 3 months ago

For plaintext font styling (bold/ italic/ ...) without excessive markup, OpenType contextual alternates are another option (unlike the css highlight API this also works with input or textarea)

Instead of defining syntax rules in javascript, they are defined within the font file using the OpenType Feature File Specification. These rules enable character substitutions, such as replacing regular characters with their italic or bold variants. (Intro into OpenType programming). Additionally one could use certain markup characters, e.g. markdown to annotate the plaintext with a customised font (example, demo).

CleanShot 2024-08-19 at 19 17 32@2x

This technique can be combined with Colr fonts, as demonstrated in this example (original article), allowing for fully featured styling and syntax highlighting without any html markup transformation.

41552

With this approach, only hyperlinks would require rendering as actual DOM nodes.

There are some discussions here on hackernews regarding performance of shifting syntax highlighting from JS to the font.

Though I would favour if font-weight/ style/ … would be part of css highlights.

samuelbradshaw commented 1 month ago

All of the text-decoration-* properties are supported, including color. From the Pseudos 4 spec: "text-decoration ... and its associated properties (including text-underline-position and text-underline-offset)". The spec is only calling out the text decoration properties that begin with text-underline- to be clear that those are decoration properties.

The additional text decoration styles work great on Chrome! Unfortunately, they're not yet supported in Safari. I haven't found a good workaround so far (other than waiting and hoping for a fix). See https://stackoverflow.com/questions/79060854/css-custom-highlight-api-with-underlined-text-on-safari