0

Essentially I'm wondering whether there's any mechanism to map your font's characters to a div's dimensions, taller letters creating taller divs, etc

There's units like em, ex, and ch that are supposed to represent font size but these are the font as a whole, not relative to the present characters

This may just not be possible within css/html

I've created this code example of what I mean, red being the div bounds, blue being my desired output

body {
  margin    : 5px 0 0 5px;
  padding   : 0;
  display   : inline-flex;
  flex-flow : column;
}

.set {
  display   : inline-flex;
  flex-flow : row;
  padding   : 0;
}

.overlay {
  position   : absolute;
  margin     : 5px 0px 5px 5px;
  width      : 60px;
  box-shadow : 0 0 0 2px blue;
}

.text {
  margin      : 5px 5px 5px 5px;
  font-family : sans-serif;
  font-size   : 32px;
  line-height : 32px;
  box-shadow  : 0 0 0 2px red;
  width       : 60px;
  text-align  : center;
}

.overlay.overlay-1 {
  
  margin-top : -26px;
  height : 13px;
}

.overlay.overlay-2 {
  
  margin-top : -34px;
  height : 22px;
}

.overlay.overlay-3 {
  
  margin-top : -28px;
  height : 23px;
}
<html>
    <body>
    
        <div class="set">

          <div>
              <div class="text">xxx</div>
          </div>
          <div>
              <div class="text">xxx</div>
              <div class="overlay overlay-1"></div>
          </div>

        </div>
    
        <div class="set">

          <div>
              <div class="text">Xxx</div>
          </div>
          <div>
              <div class="text">Xxx</div>
              <div class="overlay overlay-2"></div>
          </div>

        </div>

        <div class="set">

            <div>
                <div class="text">xxy</div>
            </div>
            <div>
                <div class="text">xxy</div>
                <div class="overlay overlay-3"></div>
            </div>
            
        </div>
    </body>
</html>
  • 1
    I have never found a way of doing this without some messy JavaScript as CSS doesn’t know about individual descender or ascender heights on individual characters. The way I did it was to draw the text on a canvas then run through each point finding the topmost and bottommost ones that didn’t have zero alpha channel. – A Haworth Jul 26 '22 at 15:52

1 Answers1

0

It seems like there is no programatic way of achieving this with CSS, as the relative heights in CSS refer to the font dimensions, not individual characters.

Edit: found a Javascript code that converts a line of text into an image, then measures the image size in pixels. Maybe you can use that.

Check this post

function measureTextHeight(fontSizeFace) {
      // create a temp canvas
      var width = 1000;
      var height = 60;
      var canvas = document.createElement("canvas");
      canvas.width = width;
      canvas.height = height;
      var ctx = canvas.getContext("2d");

      // Draw the entire a-z/A-Z alphabet in the canvas
      var text = "o";
      ctx.save();
      ctx.font = fontSizeFace;
      ctx.clearRect(0, 0, width, height);
      ctx.fillText(text, 0, 40);
      ctx.restore();

      // Get the pixel data from the canvas
      var data = ctx.getImageData(0, 0, width, height).data,
        first = false,
        last = false,
        r = height,
        c = 0;

      // Find the last line with a non-transparent pixel
      while (!last && r) {
        r--;
        for (c = 0; c < width; c++) {
          if (data[r * width * 4 + c * 4 + 3]) {
            last = r;
            break;
          }
        }
      }

      // Find the first line with a non-transparent pixel
      while (r) {
        r--;
        for (c = 0; c < width; c++) {
          if (data[r * width * 4 + c * 4 + 3]) {
            first = r;
            break;
          }
        }

        // If we've got it then return the height
        if (first != r) return last - first;
      }

      // error condition if we get here
      return 0;
    }
Victor Donoso
  • 411
  • 2
  • 9