Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing CSS Text Wrapping in SVG #942

Open
shepazu opened this issue Apr 21, 2024 · 5 comments
Open

Implementing CSS Text Wrapping in SVG #942

shepazu opened this issue Apr 21, 2024 · 5 comments

Comments

@shepazu
Copy link
Member

shepazu commented Apr 21, 2024

Wrapping text remains a serious problem in SVG. The SVG 2 specification defines a mechanism for text-wrapping using the existing CSS text-wrapping algorithm, which should be pretty simple to implement.

While there doesn't seem to be an appetite for implementing new features for SVG, this particular one is low-hanging fruit that would be a major benefit for authoring SVG and SVG libraries. In particular, SVG has become the default language for charts on the web, and improving text handling would be a boon there.

Do you see a path forward on this one, @tabatkins?

@tabatkins
Copy link
Member

The feature is simple to specify, doesn't involve any fundamentally new or difficult concepts, and is clearly a valuable use-case. I don't think there's anything that needs to be done (or can be done) on the spec level for this; it's just about getting one or more implementations to actually pull the trigger. I'm not sure what the best way to do that would be, tho, besides the usual approaches (file bugs, get people riled up to star the bugs, etc).

@herrstrietzel
Copy link

A native text-wrapping feature in SVG would be a quantum leap!

I'm pretty sure that many implementers are more than willing to do so - I think Inkscape is already a good example of this.
Frankly, I think a lot of implementers are just slightly frustrated by the previous spec history around this topic (I see why textarea in SVG tiny had issues).
But I think this long-standing problem (no multiline SVG text) is partly also caused by previous SVG working groups neglecting or underestimating the importance of this basic text-composing functionality entirely.
And I appologize if some of the following lines may appear a bit cheeky.

In short: Wishlist

Please also consider to ...

  • add a presentation attribute complementing CSS inline-size property – CSS only isn't ideal as many applications don't have great CSS support
  • reintroduce something like a <tbreak> element for manual line-breaks

Simple multiline capabilities first – fancy shape text-composing later (please=)

The specification should focus first on simple multiline/line wrapping capabilities – as used even before CSS and painstakingly implemented by most SVG visualisation libraries.
Sure, SVG was designed primarily to support vector graphics, not complex text layouts, and it doesn't need to compete with HTML/CSS for all the bells and whistles.
However, the ability to have a "block-like" text composing behaviour should be the highest priority.
Text-in-shape capabilities might be nice, but algorithms are certainly way harder to implement and - highly subjective - less relevant (erm, a GUI graphic application is more suitable for this).
For instance: line-height should be mentioned in the first paragraph but certainly not in a caption about gimmicky text-in-shape (sorry).

Manual breaks for SVG

An equivalent to HTML's <br>, such as <tbreak>, would also be helpful - indeed mandatory.

  • It's quite complex to calculate a text width or bounding box to get an appropriate line break.
    Sure, trivial in a browser, but incredibly hard to do in a headless/virtual DOM environment (actually requires parsing a specific font file, reading the metrics, applying scaling, interpreting letterspacing, etc).
  • Manual line breaks could simplify this task, e.g. for data visualisation, to ensure that a long label text breaks at a predefined point - especially if the font is not perfectly defined (e.g. via inlined @font-face source definitions).

CSS vs presentation attributes

If CSS inlne-size is the best candidate - fine!
But SVG presentation attributes are still useful.
Ideally, we should also have an SVG attribute to set the maximum textbox width.
While I totally embrace the concept of controlling SVG more and more via CSS - emulating a full-blown CSS engine is trickier than parsing attributes..
Sure, non-browser applications will eventually have to catch up anyway - but realistically it is also much easier to write a converter based on attribute parsing than to write a full-fledged getComputedStyle() emulation (ask the node.js guys).

Besides, I don't think we can get the perfect CSS-only shift – at least not any time soon:
Many crucial attributes are still not accessible via CSS like viewBox or even element based properties like <polygon> related points where the path data attribute d is stylable (... at least in any engine apart from webkit).
So currently, we (as developers) have to guess which attribute is "stylable" by specs or by implementation or if it's likely to be ever stylable at all.
So I definitly promote an attribute "fallback"!

We'll need a lot of converters

Not an issue at all as we won't fix abysmal SVG support overnight, but as long as we have a reference we can write a conversion tools/scripts.
(I guess it would be poetic justice if the MS office folks may get some trouble ... ah, no they would blame SVG to be incompliant with Office ).
As mentioned before, an additional presentation attribute would certainly facilitate this task.

To be clear, it is not my intention to belittle the efforts of the current or past members of the working group. I'm just very passionate about this mysteriously confused and seemingly intractable SVG core bug concerning SVG's text capabilities.

@shepazu
Copy link
Member Author

shepazu commented Dec 16, 2024

Glad to see enthusiasm on this topic! A few observations about your thoughts:

Simplicity

The overall goals here are simplicity of implementation and familiarity to authors. CSS text layout is the easiest way to accomplish those goals.

An implementation doesn't need to support all of CSS to do this, only those parts of CSS that are applicable to SVG. I'm not aware of any major SVG authoring tool that doesn't support at least a subset of CSS, so I don't see the need to add new presentation attributes.

If an implementation's CSS support is lacking, it would be no harder for them to improve their text layout with CSS syntax than with attribute syntax.

I agree that wrapping text in shapes is unneeded complexity. It has its use cases, but it shouldn't impede the most common case, rectangular blocks of text.

No new syntax

Browsers aren't going to add new elements or attributes. They just aren't. If anything, they're inclined to remove features from SVG.

So asking for additional elements or attributes is simply a non-starter, unfortunately.

Naturally, I agree with your use cases. So we should find a way to leverage existing SVG or CSS syntax and features to accomplish those goals.

In the case of a <tbreak>, you could simply embed the next text section in a <tspan dy="2em">. That would add the visual break. A screen reader could (and should) treat tspan elements as paragraphs, generally. You could even style the tspan to have whatever margin you want, with no need to change the attribute.

Convertors

Any authoring tool based on a browser engine (e.g. an Electron app or a web-based authoring tool) would already have the same support as the browser.

For other authoring tools (e.g. Inkscape or Illustrator), they could simply add the support natively. It's not that much extra work, and they already have text-layout tools; they'd just need to align those to CSS layout.

Of course, it would be nice to have a convertor from automatic to manual text-wrapping SVG for older versions of authoring tools, but honestly that would be trivial to make. I don't see this as a serious roadblock.

Conclusion

In short, the simpler and less demanding the request, the more likely it will be implemented and deployed. Browsers, not other SVG tools, are the blocker for interoperable improvements to SVG.

The simplest ask is for browsers to allow SVG to use their existing CSS text-wrapping, with no special cases or new elements or attributes.

@Tavmjong
Copy link
Contributor

Inkscape already implements SVG 2 text wrapping (and has for a long, long time).

@herrstrietzel
Copy link

@shepazu: Thanks a lot for your response!

Sorry for my line-break obsession.
I see the challenges and on the one hand most devs would certainly be satisfied with any line-breaking capabilities implemented ... On the other hand: if developers are already fundamentally revising the text layout engine anyway. Why not tackle it completely?

Manual line breaks via white-space

Another idea to achieve line-breaks could be taken from Firefox's current implementation respecting white-space property.

The current implementation in Firefox renders line-breaks if:

  • white-space: pre is applied to the <text> element
  • a new line is present in markup

This approach has the benefit that it doesn't require a new element such as <tbreak>.
Apart from new lines in markup we can use &#10; or &NewLine; entities.
Line-height is also respected.
The downside: it doesn't work well with code prettyfying/minification as it would also respect indentations.

However, this concept could imho be a suitable candidate for manual line-breaks and gives some hope not all browser vendors are reluctant to implement new SVG multiline text features.
Ideally, we had a way to apply this behavior with white-space: pre-line so only new lines are respected

See codepen example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants