javascript - CSS中如何垂直对齐所有文本?

标签 javascript html css vertical-alignment

问题似乎是某些字母,例如 gyq 等,其尾部向下倾斜,不允许垂直居中。这是展示问题的图像 a .

绿框中的 Angular 色基本上是完美的,因为他们没有向下的尾部。红框中的内容说明了问题。

我希望所有字符都完全垂直居中。在图像中,尾部向下的字符未垂直居中。这可以纠正吗?

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>

最佳答案

这是我使用 JS 的解决方案。这个想法是将元素转换为图像,以便获取其数据作为像素,然后循环遍历它们以找到每个字符的顶部和底部,并应用翻译来修复对齐。这将与动态字体属性一起使用。

代码没有优化,但它突出了主要思想:

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>

更新

这是代码的第一次优化:

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

for (var i = 0; i < elems.length; i++) {
  domtoimage.toPixelData(elems[i])
    .then(function(im) {
     var l = im.length;
      /* Search for the top limit */
      var t = 0;
      for (var j = 0; j < l; j+=4) {
          if (im[j+1] == 255) { /* Since we know the colors, we can only test the G composant */
            t = Math.ceil((j/4)/125);
            break;
          }
      }
      /* Search the bottom limit*/
      var b = 0;
      for (var j = l - 1; j >= 0; j-=4) {
          if (im[j+1] == 255) {
            b = 125 - Math.ceil((j/4)/125);
            break;
          }
      }
      /* get the difference and apply a translation*/
      elems[k].querySelector('.character').style.transform = "translateY(" + (b - t)/2 + "px)";
      k++;
    });
}
.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>

我正在使用 dom-to-image插件。

关于javascript - CSS中如何垂直对齐所有文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58924157/

相关文章:

javascript - 如果单击选项“否”,则删除输入值

javascript - 在 HTML5 canvas 准备就绪时调用函数

重写 CSS3 规则以实现跨浏览器兼容性的 PHP 类

html - 使用另一个 css 引导

javascript - class 和 id 名称拼写错误的预防工具

CSS 使用类或 javascript 更改样式/动画样式?

html - 带图像的链接 - 如何在链接图像上方显示链接的背景图像

html - Node js连接mysql数据库出错

html - 如何仅使用 HTML 和 CSS 一键选中所有复选框

html - Node-Html-Pdf 自定义压缩字体无法正确呈现