css 字体大小和行高与基线不匹配

2023-12-24

我正在尝试做一些应该非常简单的事情,但我在失败和论坛之间度过了一天。

我想调整我的字体以匹配我的基线。在 indesign 中只需点击一下即可,但在 css 中这看起来是地球上最困难的事情。

让我们举一个有理值的简单例子。

在这张图片上,我每 20 像素就有一个基线。

所以对于我的<body> I do:

<style>
body {font-size:16px; line-height:20px;}
</style> 

一切都很完美。我的段落与基线相符。

但是当我编写我的脚本时<h>这不再符合基线了..我做错了什么?这应该遵循我的基线,不是吗?

<style type="text/css">
    body{font-size: 16px; line-height: 20px;}
    h1{font-size: 5em; line-height: 1.25em;}
    h2{font-size: 4em; line-height: 1.25em;}
    h3{font-size: 3em; line-height: 1.25em;}
    h4{font-size: 2em; line-height: 1.25em;}
</style>

PS:20/16=1.25em

在我的检查器中,计算返回预期值

h1{font-size: 84px; line-height: 100px;}
h2{font-size: 68px; line-height: 80px;}
h3{font-size: 52px; line-height: 60px;}
h4{font-size: 36px; line-height: 40px;}

So that should display something like this no? enter image description here


这有点复杂 - 你必须首先测量字体(就像 InDesign 所做的那样)并计算“行高”,即你所说的“bottom_gap”和其他一些东西

我很确定我们可以用 JavaScript 做一些事情..

你是对的 - 但对于 Typography JS 用于计算 CSS(取决于字体指标)

在这里演示了第一步(测量字体)https://codepen.io/sebilasse/pen/gPBQqm https://codepen.io/sebilasse/pen/gPBQqm它只是以图形方式显示测量的内容[针对技术背景]

需要进行这种测量,因为每种字体在“行”中的表现完全不同。

这是一个可以生成这样的 Typo CSS 的生成器:

https://codepen.io/sebilasse/pen/BdaPzN https://codepen.io/sebilasse/pen/BdaPzN

测量的函数可以基于<canvas>看起来像这样:

function getMetrics(fontName, fontSize) {
  // NOTE: if there is no getComputedStyle, this library won't work.
  if(!document.defaultView.getComputedStyle) {
    throw("ERROR: 'document.defaultView.getComputedStyle' not found. This library only works in browsers that can report computed CSS values.");
  }
  if (!document.querySelector('canvas')) {
    var _canvas = document.createElement('canvas');
    _canvas.width = 220; _canvas.height = 220;
    document.body.appendChild(_canvas);
  }
  // Store the old text metrics function on the Canvas2D prototype
  CanvasRenderingContext2D.prototype.measureTextWidth = CanvasRenderingContext2D.prototype.measureText;
  /**
   *  Shortcut function for getting computed CSS values
   */
  var getCSSValue = function(element, property) {
    return document.defaultView.getComputedStyle(element,null).getPropertyValue(property);
  };
  /**
   * The new text metrics function
   */
  CanvasRenderingContext2D.prototype.measureText = function(textstring) {
    var metrics = this.measureTextWidth(textstring),
        fontFamily = getCSSValue(this.canvas,"font-family"),
        fontSize = getCSSValue(this.canvas,"font-size").replace("px",""),
        isSpace = !(/\S/.test(textstring));
        metrics.fontsize = fontSize;

    // For text lead values, we meaure a multiline text container.
    var leadDiv = document.createElement("div");
    leadDiv.style.position = "absolute";
    leadDiv.style.margin = 0;
    leadDiv.style.padding = 0;
    leadDiv.style.opacity = 0;
    leadDiv.style.font = fontSize + "px " + fontFamily;
    leadDiv.innerHTML = textstring + "<br/>" + textstring;
    document.body.appendChild(leadDiv);
    // Make some initial guess at the text leading (using the standard TeX ratio)
    metrics.leading = 1.2 * fontSize;
    // Try to get the real value from the browser
    var leadDivHeight = getCSSValue(leadDiv,"height");
    leadDivHeight = leadDivHeight.replace("px","");
    if (leadDivHeight >= fontSize * 2) { metrics.leading = (leadDivHeight/2) | 0; }
    document.body.removeChild(leadDiv);
    // if we're not dealing with white space, we can compute metrics
    if (!isSpace) {
        // Have characters, so measure the text
        var canvas = document.createElement("canvas");
        var padding = 100;
        canvas.width = metrics.width + padding;
        canvas.height = 3*fontSize;
        canvas.style.opacity = 1;
        canvas.style.fontFamily = fontFamily;
        canvas.style.fontSize = fontSize;
        var ctx = canvas.getContext("2d");
        ctx.font = fontSize + "px " + fontFamily;

        var w = canvas.width,
            h = canvas.height,
            baseline = h/2;

        // Set all canvas pixeldata values to 255, with all the content
        // data being 0. This lets us scan for data[i] != 255.
        ctx.fillStyle = "white";
        ctx.fillRect(-1, -1, w+2, h+2);
        ctx.fillStyle = "black";
        ctx.fillText(textstring, padding/2, baseline);
        var pixelData = ctx.getImageData(0, 0, w, h).data;

        // canvas pixel data is w*4 by h*4, because R, G, B and A are separate,
        // consecutive values in the array, rather than stored as 32 bit ints.
        var i = 0,
            w4 = w * 4,
            len = pixelData.length;

        // Finding the ascent uses a normal, forward scanline
        while (++i < len && pixelData[i] === 255) {}
        var ascent = (i/w4)|0;

        // Finding the descent uses a reverse scanline
        i = len - 1;
        while (--i > 0 && pixelData[i] === 255) {}
        var descent = (i/w4)|0;

        // find the min-x coordinate
        for(i = 0; i<len && pixelData[i] === 255; ) {
          i += w4;
          if(i>=len) { i = (i-len) + 4; }}
        var minx = ((i%w4)/4) | 0;

        // find the max-x coordinate
        var step = 1;
        for(i = len-3; i>=0 && pixelData[i] === 255; ) {
          i -= w4;
          if(i<0) { i = (len - 3) - (step++)*4; }}
        var maxx = ((i%w4)/4) + 1 | 0;

        // set font metrics
        metrics.ascent = (baseline - ascent);
        metrics.descent = (descent - baseline);
        metrics.bounds = { minx: minx - (padding/2),
                           maxx: maxx - (padding/2),
                           miny: 0,
                           maxy: descent-ascent };
        metrics.height = 1+(descent - ascent);
    } else {
        // Only whitespace, so we can't measure the text
        metrics.ascent = 0;
        metrics.descent = 0;
        metrics.bounds = { minx: 0,
                           maxx: metrics.width, // Best guess
                           miny: 0,
                           maxy: 0 };
        metrics.height = 0;
    }
    return metrics;
  };

Note您还需要一个好的“reset.css”来重置浏览器边距和填充。
你点击“show CSS”,你还可以使用生成的CSS来混合多种字体:
如果它们具有不同的基本尺寸,请标准化第二个:

var factor = CSS1baseSize / CSS2baseSize;

现在重新计算 CSS2 中的每种字体

var size = size * factor;

请参阅演示https://codepen.io/sebilasse/pen/oENGev?editors=1100 https://codepen.io/sebilasse/pen/oENGev?editors=1100

如果涉及图像怎么办? 以下演示使用两种具有相同规格的字体以及额外的 JS 部分。需要计算基线网格的媒体元素,例如图像:https://codepen.io/sebilasse/pen/ddopBj https://codepen.io/sebilasse/pen/ddopBj

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

css 字体大小和行高与基线不匹配 的相关文章

  • 使用画布仅删除文本而不删除图像

    我正在尝试删除画布元素中的文本 而不丢失Background Image of the Canvas Element 我想我需要保存Imagesrc并把它还给Canvas Element之后clearRect 但我不知道该怎么做 我希望有人
  • 如何在文本区域中使用除“文本插入符号”之外的透明字体?

    我有一个简单的文本区域 我需要制作透明字母 同时允许文本插入符可见 当我应用以下规则时 我会得到隐形插入符 textarea background transparent opacity 0 当我键入不可见文本时 我需要看到文本插入符移动
  • 动态表单标签宽度的 CSS

    我目前正在重构我们的表单控制器之一 以便我们可以将其用于面向公众的网站 目前它正在为表单生成表格布局 但我正在尝试使用 CSS 表单来完成它 我正在尝试重现看起来像这样的东西http www stylephreak com uploads
  • 如何隐藏 URL 中的锚标记

    如何隐藏地址栏中以下链接 href 的哈希值 a href index php dev name 所以它会将我重定向到index php dev name 但我希望地址栏只显示index php 您可以使用 Javascript oncli
  • 使用 CSS 自定义字体?

    我见过一些在其网站上使用自定义字体的新网站 除了常规的 Arial Tahoma 等 他们支持大量的浏览器 如何做到这一点 同时 如果可能的话 还会阻止人们免费下载该字体 一般来说 您可以使用自定义字体 font face在你的 CSS 中
  • 在 HTML5 中创建可拖动和可缩放的网格

    与其他 HTML5 不同如何创建网格问题 我想知道如何制作一个可拖动且可扩展的 绘制网格非常简单 var c document getElementById canvas var ctx c getContext 2d var width
  • 如何通过单击图像预览上的“x”从文件输入中删除图像?

    我目前有一个文件输入 一旦用户上传图像 就会显示图像预览 在图像预览上 有一个 x 可以从列表中删除图像预览 单击此 x 后 有什么方法可以从输入中的文件集中删除图像吗
  • 如何将udp发送到udp node.js服务器?

    我对此很陌生 所以我真的不知道我在做什么 但我已经设置了一个 node js udp 服务器 我想从客户端 来自网站 向它发送一个数据包 但我不知道如何在 javascript 中做到这一点 或者是否可能 我不是在研究如何从 Node js
  • 如何在HTML中的PHP中注释掉HTML和PHP?

    这是我想注释掉的一行代码 h1 class post title a href title a h1 一种流行的注释方法是分别注释 html 和 php 有一个更好的方法吗
  • 如何使用 a-href 标签链接回文件夹? [复制]

    这个问题在这里已经有答案了 好吧 我在文件夹中有一个页面 该页面称为 jobs html 该文件夹简称为 jobs 它是我的 网站 文件夹的子文件夹 在 main 文件夹的主目录中是我的 home html 文件 当我尝试做的时候 a hr
  • 来自 JSON 的 Angular 8 动态表单

    我正在尝试从 JSON 模式递归生成动态表单 但我正在努力解决找不到表单控件的问题 这是代码示例 我收到这个错误 错误错误 找不到名称为 createdAt 的控件 我尝试了不同的方法 但仍然存在问题 我知道我错过了一些东西 所以请帮忙 任
  • VBA / HTML / jQuery 选择自动完成 - 在列表中选择

    我正在尝试使用 Excel 中的 VBA 在网站的列表中选择一个值 这不是一个 正常列表 该网站使用 jQuery 选择自动完成 如下所示 example http davidwalsh name demo jquery chosen ph
  • 在网页上的文本框中键入内容时删除所有空格

    我如何在用户打字时即时删除输入到文本框中的空格 function var txt myTextbox var func function txt val txt val replace s g txt keyup func blur fun
  • 如何为背景图像添加边距?

    我想向背景图像添加边距 以便将其与屏幕中间保持距离 但将其添加到该类中会为整个主体添加边距 body poppage background url Imagenes tip3 png 50 200px no repeat E2E4E9 我怎
  • 如何更改 Bootstrap 3 div 列顺序

    正在做我的第一个响应式设计 在 Bootstrap 3 中可能会出现类似的情况 在 lg 上更改此设置 a b c sm 上的这个 a c b 您可以使用两个 div 一个用于第一类型的布置 另一个用于第二类型的布置 第一个仅在 lg 中显
  • 如何使用 JavaScript 获取没有 HTML 元素的纯文本?

    我的 HTML 中有 1 按钮和一些文本 如下所示 function get content I don t know how to do in here
  • 如何延迟加载嵌入在 iframe 上的 YouTube 视频?

    如何将延迟加载应用于iframe嵌入视频 我尝试添加loading eager loading auto and loading lazyload 您可以使用srcdoc你里面的属性iframe标签来加载图像 请参阅以下示例作为参考
  • 如何在背景剪辑中包含文本装饰:文本;影响?

    我在用 webkit background clip text border and color transparent在锚标记上 下划线似乎永远不可见 我想要的是将文本装饰包含在背景剪辑中 这是我的CSS background clip
  • 覆盖并重置 CSS 样式:auto 或 none 不起作用

    我想覆盖为所有表定义的以下 CSS 样式 table font size 12px width 100 min width 400px display inline table 我有一个特定的表 其类名为 other 最后的餐桌装饰应该是这
  • 需要有关 React Js 的帮助

    我是 React Js 新手 我的代码无法正常工作 请看下面 这是我的脚本文件Main jsx 该文件由 React 编译 输出放置在 dist 文件夹下的 main js 文件中 var react require react react

随机推荐

  • R:可变宽度lookbehind的解决方法

    给定这个向量 ba lt c baa aba abba abbba aaba aabba 我想改变最后的结局a每个单词到i except baa and aba 我写了以下行 gsub lt a ab b 1 2 a i ba perl T
  • 帮助唐纳德·B·约翰逊的算法,我无法理解伪代码(第二部分)

    我无法理解唐纳德 约翰逊发表的关于在图中查找周期 电路 的论文的某些部分 更具体地说 我无法理解以下伪代码行中提到的矩阵 Ak 是什么 Ak 具有最少的强分量K的邻接结构 由 s s 1 n 导出的 G 子图中的顶点 更糟糕的是 后面的几行
  • 尽管令牌正确,但用户未经授权

    我正在尝试将 D365FO 与第三方应用程序集成 我能够进行正确的设置并注册我的应用程序 获取令牌 如下所示 我用的是resource作为开发机器上 D365FO 的链接 这是https usnconeboxax1aos cloud one
  • OpenCV.4.2 VideoCapture 上未处理的异常

    我刚刚安装了 OpenCV2 4 2 并使用 CMake 创建了一个 OpenCV 项目 我没有收到任何编译错误 我有几个处理图像的函数 并且有 2 个应用程序 1 处理视频数据 2 处理模拟数据 除了从视频中提取数据之外 这两个应用程序是
  • 输入上的碗式下划线或边框[重复]

    这个问题在这里已经有答案了 我有一个底部只有边框的输入字段 现在我需要在输入的左侧和右侧创建一条小线 有点难以描述 所以我举个例子 input background color transparent height 20px padding
  • Logstash不处理filebeat发送的文件

    我已经使用 docker 设置了 elk 堆栈基础设施 我看不到 Logstash 正在处理的文件 Filebeat 配置为将 csv 文件从logstash 发送到logstash 再发送到elasticsearch 我看到logstas
  • 比较两个字符串忽略大小写的最佳方法[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我想比较两个不区分大小写的刺痛 但我不确定最好的方法 字符串的平均长度为 20 这个问题更多的是关于最先进的技术 而不是关于最佳性能 我的大部分
  • mongodb中单引号的正则表达式

    在 mongodb shell 客户端中 如何查询查找带单引号的文档 我在正则表达式中转义了引号 但它不起作用 db coll find field 这应该有效 db coll find field x27 0x27 是哪里Unicode
  • C++ 中的共享指针、弱指针和惰性指针

    有谁知道实施shared ptr and weak ptr与惰性初始化伙伴一起 课程的要求是 A lazy ptr允许客户端稍后构造对象 如果有的话 的类 而不需要构造函数实现 A weak lazy ptr具有三种可能状态的类 尚未构造
  • Android Studio 中出现意外令牌:错误:(40, 61) 错误:非法字符:\8232

    当我有时 从 WEB 或其他外部源 将粘贴代码复制到 Android Studio 中时 我会得到一些不可见的字符 并且无法编译 有办法避免这种情况吗 自动重新格式化代码 插入 更改设置 Error 40 61 error illegal
  • 反应:未捕获范围错误:超出最大调用堆栈大小

    我正在使用 React 并且得到了我想要的功能 但由于某个地方的无限循环 它非常慢 我相信它在组件生命周期方法中 但我不确定如何重新格式化以下代码以具有相同的功能但没有无限循环 任何有关最佳实践的建议将不胜感激 class App exte
  • 轨道模型的别名

    我在 Rails 应用程序之一中的模型名称是OrganizationUser有没有办法为此模型创建别名作为 OU 或 OrgUser 以便我可以在 Rails 控制台中使用 如果 kishie 的答案不适合您 您可以创建另一个继承自 Org
  • 从子目录导入文件?

    我有一个名为tester py 位于 project project有一个子目录名为lib 有一个名为BoxTime py project tester py project lib BoxTime py 我想进口BoxTime from
  • 查找将从 Windows 命令行执行的程序的路径

    说我有一个程序X EXE安装在文件夹中c abcd happy 在系统上 该文件夹位于系统路径上 现在假设系统上还有另一个程序 也称为 X EXE 但安装在文件夹中c windows 是否可以从命令行快速找出如果我输入X EXE两者中的哪一
  • 如何在 MVC 索引页面中显示导航属性集合中的值

    我有一个名为 JobTitle 的 EF 实体类型 它有一个名为 Offices 的导航属性 它是另一个名为 Office 的实体类型的集合 我想在索引视图中显示 JobTitle 名称和相关 Office 名称的列表 View 脚手架默认
  • 使用 python 中的 csv 模块写入特定单元格

    我必须向 csv 文件中的特定单元格 例如第 8 个单元格 写入一个值 我可以看到有一个csvwriter writerow row 方法来写入整行 但我没有看到任何将值写入特定单元格的内容 The csv模块 http docs pyth
  • 使用现有 R 会话中的对象运行 Sweave 或 knit

    假设我有一个对象x在我当前的会话中 x lt 1 如何在 Sweave 或 knit 文档中使用此对象 而无需显式分配它 documentclass article begin document lt lt gt gt print x en
  • 如何自动启动 AlarmManager 来启动计划活动?

    本教程来自android er http android er blogspot com 2011 05 using alarmmanager to start scheduled html 主活动 AndroidScheduledActi
  • 在 Android 中改造没有值的 GET

    我在大多数调用中都使用 Retrofit 但在其中一种情况下 我在参数中提供了完整路径 我的网址是这样的http www example com android json http www example com android json
  • css 字体大小和行高与基线不匹配

    我正在尝试做一些应该非常简单的事情 但我在失败和论坛之间度过了一天 我想调整我的字体以匹配我的基线 在 indesign 中只需点击一下即可 但在 css 中这看起来是地球上最困难的事情 让我们举一个有理值的简单例子 在这张图片上 我每 2