10

In other words, how do I ignore a character's depth and ascent in instead center it vertically in a surrounding box based just on its bounding box?

Here is a minimal html example:

.box {
  display: inline-block;
  width: 1em;
  height: 1em;
  line-height: 1em;
  border: 1px solid black;
  text-align: center;
}
<span class="box">?</span>
<span class="box">,</span>
<span class="box">`</span>

It produces the following:

non-centered characters

How do I change it to produce the following instead?

centered characters

CSS solutions are preferred if they exist, but Javascript is acceptable as a last resort. I'm looking for a general solution, not just for the three characters pictured. There will be many such boxes in my page, so performance (if Javascript is used) is important.

To clarify things even further, here is how I would do this in LaTeX:

\newlength{\desiredboxsize}
\setlength{\desiredboxsize}{1em}
\newcommand*{\centercharinbox}[1]{%
  % Force width
  \makebox[\desiredboxsize]{%
    % Force height and center vertically
    \raisebox{\dimexpr .5\desiredboxsize - .5\height \relax}[\desiredboxsize][0pt]{%
      % Cancel depth
      \raisebox{\depth}{#1}}}}
Oriol
  • 274,082
  • 63
  • 437
  • 513
Clément
  • 12,299
  • 15
  • 75
  • 115
  • 2
    @Oriol, thanks for the edit! – Clément May 22 '16 at 17:38
  • I was wondering if [`CanvasRenderingContext2D.measureText`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/measureText) could be used to achieve this with JS, but it seems that vertical properties are only supported on Chrome and there they return the same value for all characters. – Oriol May 22 '16 at 17:53

2 Answers2

7

In theory, you can do it by aligning every symbol individually.

Practically, you can't as every symbol has its own depth and ascent in the character map, especially using only CSS.

3

You cannot do that with modern CSS. Neither can you do that out of the box with JavaScript in browsers.

Essentially: you need to get glyph outlines as paths from fonts. Using that information you can get path outline box and render / align in the way you need.

For getting glyph outlines check this How do I get glyph outlines of a letter as bézier paths using JavaScript? answer for example.

Having glyph outline paths you can render them into <canvas> elements.

Community
  • 1
  • 1
c-smile
  • 26,734
  • 7
  • 59
  • 86
  • Thanks, this is a neat suggestion. I think one can push it further and build the corresponding font statically, in fact. – Clément May 22 '16 at 19:52
  • @Clément Yes, if it is just about one font then you can convert it to SVG images (statically). Depends on your use case. – c-smile May 22 '16 at 20:21
  • I was thinking of just building a custom TTF, actually; fontforge has pretty good scripting support for this. – Clément May 22 '16 at 21:03