Shared publicly  - 
 
I want to tell the browser: make this text as big as possible without scrolling.
1
James Babcock's profile photoLucas Sanders's profile photoJeff Kaufman's profile photoChris Lahey's profile photo
7 comments
 
I'm pretty sure there's no way to do it with HTML and CSS alone; the text kerning and wrapping characteristics are complicated enough that any HTML+CSS implementation would have the browser doing a similar loop behind the scenes, and CSS seems to mostly avoid that. You can speed it up by using a binary search instead of small increments (with some possible caveats where it's not monotonic), but I'm pretty sure there's no closed-form solution.
 
+James Babcock I think the constraints for tables may be a similar level of complexity, though I'm not sure.  Still, the browser doing the looping and solving ought to be better than me doing it in javascript.

The javascript solution is instant, even on my phone, so I don't really /need/ something else.  I just feel a bit icky doing this.
 
+Jeff Kaufman I don't think there's a pure HTML+CSS solution that does what you want. Your most obvious problem here is that percentages in CSS typography are relative to the base font size, not the size of the containing block (as in the rest of CSS). Secondarily, CSS isn't enthusiastic about using the viewport height in layout calculations -- it'd much rather take the viewport width as the only constraint, thereby letting the layout height be defined by the flow of content. (This also makes vertical centering hard, unless you use the table layout algorithm.)

It looks like manual line wrapping is appropriate for this use case, so I think you could pretty easily create SVG layouts for these cards, and/or write a one-off local script for converting from your HTML to the appropriate SVG layout. Then you can simply use CSS to scale each SVG "image" to make full use of the viewport.

Similarly, you could use white-space:nowrap with manual line breaks and float:left to shrinkwrap a container around your text, then use a script to calculate a scaling factor from the rendered layout metrics and the viewport dimensions. This scaling factor can then be applied as a CSS transform. (I'm not aware of a way to apply a CSS transform with dimensions relative to the containing block, instead of relative to the intrinsic content rendering -- but I'm not 100% certain that a creative application of transforms couldn't get the job done without a script.)

Alternatively, if you're willing to settle for a more deliberate starting point with your current techniques: you could set the line-height to (viewport height ÷ number of lines) and set the font-size to something like 0.8 or 0.9x line-height. Then, if horizontal line wrapping is an issue, iteratively crank down the font-size, just like you're doing now.
 
+Lucas Sanders "It looks like manual line wrapping is appropriate for this use case"

I'd like this to work on things with different aspect ratios.  It's nice that the current solution looks good on my laptop as well as my phone.  The other problem with manual line breaking is then I need to be testing how each one looks, instead of just letting the browser sort it out.
 
This is basically what my code for fitting text on my cards looks like, though I multiple the font size by  .7 or something instead of subtracting a value.  Mine actually doesn't do any wrapping, which I think I'm going to add next.  Also, I need to do a bunch of work on my card database.  Perhaps I'll go work on that.

How does your database store the dances?  Are they text or semantic?
 
+Jeff Kaufman "I'd like this to work on things with different aspect ratios."

Sure, soft wrapping of text can be helpful. Given that and your other constraints, I would expect to use JavaScript to adapt the layout, at which point your original approach seems like a fully reasonable way to go.

I'm not sure how one would specify the behavior of a text scaling property for CSS that would achieve your intuitive aims in a general case, so the scripting solutions don't seem so kludgy to me -- I think you almost inherently need to know something about the aims of the content in order to do the right thing.
Add a comment...