Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
268 views
in Technique[技术] by (71.8m points)

javascript - How to vertically align all text in CSS?

The issue seems to be that certain letters like g, y, q, etc. that have a tail that slopes downwards, do not allow for vertical centering. Here's an image to showcase the problem a.

The characters in the green box are basically perfect, as they have no downward tail. Those in the red box demonstrate the problem.

I would like for all characters to be perfectly vertically centered. In the image, characters with a downward tail are not vertically centered. Is this possible to rectify?

Here is the fiddle that demonstrates the problem in full.

.avatar {
    border-radius: 50%;
    display: inline-block;
    text-align: center;
    width: 125px;
    height: 125px;
    font-size: 60px;
    background-color: rgb(81, 75, 93);
    font-family: "Segoe UI";
    margin-bottom: 10px;
}

.character {
    position: relative;
    top: 50%;
    transform: translateY(-50%);
    line-height: 100%;
    color: #fff;
}
<div class="avatar">
  <div class="character">W</div>
</div>

<div class="avatar">
  <div class="character">y</div>
</div>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Here is my solution using JS. The idea is to transform the element into an image in order to get its data as pixel then loop through them to find the top and bottom of each character and apply a translation to fix the alignment. This will work with dynamic font properties.

The code is not optimized but it highlight the main idea:

var elems = document.querySelectorAll(".avatar");

var fixes = [];


for (var i = 0; i < elems.length; i++) {
  var current = elems[i];
  domtoimage.toPixelData(current)
    .then(function(im) {
      /* Search for the top limit */
      var t = 0;
      for (var y = 0; y < current.scrollHeight; ++y) {
        for (var x = 0; x < current.scrollWidth; ++x) {
          var j = (4 * y * current.scrollHeight) + (4 * x);
          if (im[j] == 255 && im[j + 1] == 255 && im[j + 2] == 255) {
            t = y;
            break;
          }
        }
      }
      /* Search the bottom limit*/
      var b = 0;
      for (var y = (current.scrollHeight - 1); y >= 0; --y) {
        for (var x = (current.scrollWidth - 1); x >= 0; --x) {
          var j = (4 * y * current.scrollHeight) + (4 * x);
          if (im[j] == 255 && im[j + 1] == 255 && im[j + 2] == 255) {
            b = current.scrollHeight - y;
            break;
          }
        }
      }
      /* get the difference and apply a translation*/
      var diff = (b - t)/2;
      fixes.push(diff);
      /* we apply the translation when all are calculated*/
      if(fixes.length == elems.length) {
        for (var k = 0; k < elems.length; k++) {
          elems[k].querySelector('.character').style.transform = "translateY(" + fixes[k] + "px)";
        }
      }
    });
}
.avatar {
  border-radius: 50%;
  display: inline-flex;
  vertical-align:top;
  justify-content: center;
  align-items: center;
  width: 125px;
  height: 125px;
  font-size: 60px;
  background: 
    linear-gradient(red,red) center/100% 1px no-repeat,
    rgb(81, 75, 93);
  font-family: "Segoe UI";
  margin-bottom: 10px;
}

.character {
  color: #fff;
}
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/dom-to-image.js"></script>
<div class="avatar">
  <div class="character">W</div>
</div>

<div class="avatar">
  <div class="character">y</div>
</div>

<div class="avatar">
  <div class="character" style="font-size:35px">a</div>
</div>

<div class="avatar">
  <div class="character" style="font-size:25px">2</div>
</div>
<div class="avatar">
  <div class="character">o</div>
</div>
<div class="avatar">
  <div class="character">|</div>
</div>
<div class="avatar">
  <div class="character">@</div>
</div>
<div class="avatar">
  <div class="character">?</div>
</div>

<div class="avatar">
  <div class="character" style="font-family:arial">Q</div>
</div>
<div class="avatar">
  <div class="character">~</div>
</div>
<div class="avatar">
  <div class="character">8</div>
</div>

<div class="avatar">
  <div class="character">?</div>
</div>
<div class="avatar">
  <div class="character">?</div>
</div>

<div class="avatar">
  <div class="character">$</div>
</div>

<div class="avatar">
  <div class="character">></div>
</div>
<div class="avatar">
  <div class="character">%</div>
</div>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...