Auto-sizing text to fit container


#1

I would be interested in having a CSS feature that would allow font to be sized relative to it’s container size.

Reasoning

There is quite a lot of interest in this:

While vw and vh can provide a certain workaround, relying on viewport size would not be sufficient for a relatively complex page.

Another thing is precision. Basic Kinetic Typography could be done with standard CSS animations if the text can be positioned precisely, taking exact vertical space (from top pixel of the text to bottom pixel).

Specification

This is a very rough description of an idea – I am pretty sure there are quite a lot of problems with it. But here is the basic thing:

font-size: fit-width | fit-height | fit-height-precise;

fit-height-precise would be ascent-to-descent (if I understand font terminology correctly) – basically from top pixel to bottom pixel.

Problems

  • How does this work with multiline text?
    Not quite sure at the moment – any feedback?
    One option is an additional constraint that would describe preferred line length.

  • How does this work with text-overflow?
    Overflow would have to be ignored if this is set.

  • How does this work when calculating the container size?
    Setting this property makes container ignore its text content when calculating it’s size.

  • How does it work when there are other elements in the container?
    Not quite sure, but we could ignore the property in that case.

  • Shouldn’t we support percentage sizes relative to the container instead of 100% fit?
    I would say it’s not worth it – it’s always possible to wrap in another element or use padding instead.


#2

Having written the current text-sizing logic for big.js, I can tell you that handling this for word-wrapped content is a computationally-complex packing problem, solveable by only brute force (although the search space could probably be reduced significantly with better text metric APIs). As such, I believe the multi-line case should remain a problem solvable by only JS (on the other hand, I think Flexbox has a similar sizing mode regarding wrapping content, so maybe this isn’t as intractable as I think).


#3

This is a thing I’ve wanted for ages, and it doesn’t make sense why there is no plain CSS solution up to date.

The last time I thought about it (it was today) I came up with that it should be a new value for text-overflow property, like text-overflow: scale, alongside with two new properties min-font-size and max-font-size, both of which would allow us to control things for the most use-cases .

Issues that should be solved:

  1. Whenever there is a multiline text and only one line overflows, should the font-size of the whole text be scaled, or only the one for the line that overflows? The best would be to have a way to do both, and the easiest would be to scale everything.
  2. Should only font-size be scaled, or both font-size and line-height? What about font-weight and other possible properties of the font? I’d say that for the start we should be able to allow both line-height scaling and no line-height scaling, possibly by different values?

Most of the use-cases are already solved in JS in a number of ways (for example, https://github.com/rikschennink/fitty), and performance or complexity shouldn’t be valid reasons not to implement it in CSS. That’s a thing that developers need really often and it just should be in CSS, one way or another. Performance shouldn’t be worse than that of the JS tools already provide (and it should be on developers to use it properly), and any complexity issues should be fixed by having compromises that would allow the most use cases to be achievable (and for the more complex ones not to be, at least at first).


#4

We already do this for (background) images, using contain, so I imagine something similar could certainly be done with font-size. It definitely has use cases ─ I don’t think that’s even in question.


#5

You can do it with SVG, but you might not like it: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/lengthAdjust


#6

Sure, but what if the text can be any number of values? The vast majority of people won’t want to edit SVGs on the fly.


#7

I am liking this solution so far