css 删除信件中未使用的空格

cngwdvgl  于 2023-01-28  发布在  其他
关注(0)|答案(2)|浏览(154)

我尝试使用单个字母作为徽标,问题是字母的包含框,也称为“em框”太大和/或太小,如下所示:

我希望它有完全相同的大小,因为信,使我可以把它完美地集中到圆圈,像'w'标志。'B'之一,使用相同的css,是完全关闭。

@import url('https://fonts.googleapis.com/css2?family=Fredoka:wght@200&family=Press+Start+2P&display=swap');
.container {
  display: flex;
  gap: 30px;
}

.circle {
  display: flex;
  height: 175px;
  width: 175px;
  justify-content: center;
  align-items: center;
  border-radius: 100px;
  background: #1231b3;
}

.text {
  display: flex;
  font-family: 'Press Start 2P';
  font-size: 120px;
  color: white;
  background-color: light-blue;
}

.light {
  background: #7c8dd7;
}
<div class="container">
  <div class="circle">
    <div class="text">b</div>
  </div>
  <div class="circle">
    <div class="text light">b</div>
  </div>
</div>
46scxncf

46scxncf1#

CSS不知道字符在哪里开始和结束(根据其可见部分,而不是其整体宽度/高度)。
为了找出字符的顶部/底部/左侧/右侧可见端点,此代码段在画布上绘制该字符,然后扫描画布的行和列,以查找具有非零alpha设置的第一个点。
logo是一个完整的圆角正方形及其内容,内部的圆圈是作为before伪元素绘制的。
字符不是在DOM中绘制的,而是作为after伪元素的内容绘制的,这样就可以根据其可见尺寸调整其位置。
没有上升字母的字符(例如问题示例中的w和c)会稍微上移(取决于它们的整体可见高度),以便居中。
讨论中的字体与标准字体有一点不同,因为下降字体几乎没有任何高度,所以基线相对于整个字符的位置是不同的。
这段代码有一点欺骗性,它构建了一个字符的高度,并带有一个升序(在本例中是小写b)作为需要调整字符的指南。因此,对于任何可能出现的字体,它不是一个完全通用的解决方案。首先需要做更多的工作来确定任何给定字体的高度范围。

<!doctype html>
<html>

<head>
  <title>Chars as logos</title>
  <!-- https://stackoverflow.com/questions/72772445/remove-unused-space-from-letter -->
  <script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
  <style>
    body {
      font-family: 'Press Start 2P';
      letter-spacing: -4px;
      font-size: 30px;
    }
    /* container added just for demo */
    
    .container {
      display: flex;
      gap: 3vw;
      background: #eeeeee;
      rtext-align: center;
    }
    
    .logo {
      width: 70px;
      height: 70px;
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: var(--col1);
      border-radius: 10px;
      position: relative;
      padding: 0;
      margin: 0;
      line-height: 1em;
    }
    
    .logo::before {
      content: '';
      width: 50px;
      height: 50px;
      background-color: var(--col2);
      border-radius: 50%;
      position: absolute;
      top: 10px;
      left: 10px;
      padding: 0;
      margin: 0;
    }
    
    .logo::after {
      content: var(--char1);
      font-family: 'Press Start 2P';
      font-size: 30px;
      height: calc(var(--h) * 1px);
      width: calc(var(--w) * 1px);
      padding: 0;
      margin: 0;
      display: inline-block;
      position: absolute;
      color: white;
      z-index: 1;
      text-align: center;
      margin-top: calc(var(--top) * 1px);
    }
    
    canvas {
      width: 200px;
      height: 200px;
    }
  </style>
</head>

<body>

  <div class="container">
    <div class="logo" style="--char: g; --char1: 'g'; --col1: #c920df; --col2: #e48fef;"></div>
    <div class="logo" style="--char: w; --char1: 'w'; --col1: #df208d; --col2: #ef8fc6;"></div>
    <div class="logo" style="--char: b; --char1: 'b'; --col1: #1231b3; --col2: lightblue;"></div>
  </div>

  <script>
    const logos = document.querySelectorAll('.logo');

    function fontLoaded() {
      logos.forEach(logo => {
        let canvas = document.createElement("canvas");
        canvas.width = 200;
        canvas.height = 200;
        let ctx = canvas.getContext("2d");
        ctx.font = "30px 'Press Start 2P'";
        ctx.fillText(logo.style.getPropertyValue('--char'), 10, 60); //baseline of the character will be at 60

        let d = ctx.getImageData(0, 0, 200, 200);
        let foundTop = false;
        foundBottom = false;
        foundLeft = false;
        foundRight = false;
        let top = [];
        let bottom = [];
        let left = [];
        let right = [];
        let r, c;
        //// Find the visible height ////
        for (r = 0; r < 200; r++) {
          for (c = 3; c < (800 - 1); c += 4) {
            if (d.data[(r * 800) + c] != 0) {
              foundTop = true;
              top = [r, c];
              break;
            }
          }
          if (foundTop) break;
        }

        for (r = 200 - 1; r >= 0; r--) {
          for (c = (800 - 1); c >= 0; c -= 4) {
            if (d.data[(r * 800) + c] != 0) {
              foundBottom = true;
              bottom = [r, c];
              break;
            }
          }
          if (foundBottom) break;
        }
        //// now find the width ////

        for (c = 3; c < (800 - 1); c += 4) {
          for (r = 0; r < (200 - 1); r++) {
            if (d.data[(r * 800) + c] != 0) {
              foundLeft = true;
              left = [r, c];
              break;
            }
          }
          if (foundLeft) break;
        }

        for (c = (800 - 1); c >= 0; c -= 4) {
          for (r = 200 - 1; r >= 0; r--) {
            if (d.data[(r * 800) + c] != 0) {
              foundRight = true;
              right = [r, c];
              break;
            }
          }
          if (foundRight) break;
        }

        logo.style.setProperty('--h', bottom[0] - top[0]);
        logo.style.setProperty('--w', (right[1] - left[1] - 1) / 4);
        if ((bottom[0] - top[0]) < 26) logo.style.setProperty('--top', (top[0] - bottom[0]) / 2);
      });
    }

    WebFont.load({
      google: {
        families: ['Press Start 2P:300,400,700']
      },
      loading: function() {},
      active: function() {
        fontLoaded();
      }
    });
  </script>
</body>

</html>

注意:在画布上绘制字体之前,我们必须确保它已经被加载,因此使用了google库

km0tfn4u

km0tfn4u2#

@A Haworth的答案太棒了。我永远也想不出这个答案。但是如果你想要一个快速而肮脏的css解决方案,去掉flex属性,将text-align设置为center,并调整. text框的填充。使用em度量单位,这样布局就可以缩放而不会中断。
大字体:120px

@import url('https://fonts.googleapis.com/css2?family=Fredoka:wght@200&family=Press+Start+2P&display=swap');

/* only used for this example */
.wrapper {
  display: flex;
  gap: 30px;
}

.container {
      font-size: 120px;
/*      font-size: 24px;*/
    display: inline-block;
    padding: .25em;
    border-radius: .5em;
}

.container.blue {
    background-color: #8fa1ef;
}

.container.purple {
    background-color: #e48fef;
}

.container.red {
    background-color: #ef8fc6;
}

.circle {
    height: 1.5em;
    width: 1.5em;
  border-radius: 1em;
}

.blue .circle {
  background-color: #1231b3;
}

.red .circle {
    background-color: #df208d;
}

.purple .circle {
    background-color: #c920df;
}

.text {
  font-family: 'Press Start 2P';
  color: white;
  text-align: center;
}

.blue .text {
  padding: .18em 0 0 .125em;
}

.red .text {
    padding: .08em 0 .04em .04em;
}

.purple .text {
    padding: .08em 0 0 .1em;
}
<div class="wrapper">

<div class="container blue">
  <div class="circle">
    <div class="text">b</div>
  </div>
</div>

<div class="container red">
  <div class="circle">
    <div class="text">c</div>
  </div>
</div>

<div class="container purple">
  <div class="circle">
    <div class="text">w</div>
  </div>
</div>

</div>

小字体:完全相同,但字体大小设置为24px。
一个二个一个一个

相关问题