【问题标题】:How to compute the baseline of text如何计算文本的基线
【发布时间】:2026-01-12 13:25:02
【问题描述】:

我正在尝试编写一个测试来确定<input> 中呈现的文本是否与标签具有相同的基线:

为了做到这一点,我想计算已在每个元素中呈现的文本的基线,并比较这两个值。这可能吗?如果可以,它是如何完成的?如果不是,是否有更好的方法来确定两个元素的基线相同?

我找到了一种确定标签基线的方法,该方法似乎可靠地工作:

function getBaseline(element) {
    var span = document.createElement("span");
    span.setAttribute("style", "font-size:0");
    span.innerText = "A";
    jQuery(element).prepend(span);
    return span.getBoundingClientRect().bottom;
}

但是,此方法不适用于<input>,因为在这种情况下我无法插入跨度。

【问题讨论】:

  • 这是个多大的问题?因为这些东西默认是vertical-align:baseline,如果你不写任何乱七八糟的CSS,它们确实有相同的基线。
  • @MrLister 问题是人们确实编写的 CSS 会把这些事情搞砸,这就是为什么我试图编写单元测试,但这样做会失败!
  • This is messy, but explains my thinking。它将输入元素替换为一个跨度,该跨度具有从输入复制的每个 CSS 属性。你能做类似的事情来进行检查吗? CSS 复制脚本是over here

标签: javascript html css baseline


【解决方案1】:

我找到了一种根据您的函数获取计算基线的方法。诀窍是创建一个包装器并将元素中的所有样式应用到它。我可以确认它可以在 OSX 上的 Firefox (v38) 和 Chrome (v44) 中运行。不幸的是,它在 Safari 中无法正常工作。

DEMO

function getBaseline(element) {
    element = jQuery(element);
    var span = document.createElement("span");
    span.setAttribute("style", "font-size:0");
    span.innerText = "A";

    var wrapper = document.createElement("span");
    applyCSSProperties.call(wrapper, element);
    element.wrap(wrapper);
    element.before(span);

    var computed = span.getBoundingClientRect().bottom;

    span.remove();
    element.unwrap(wrapper);

    return computed;
}

function applyCSSProperties(element) {
    var styles = {};
    var comp = getComputedStyle(element[0]);

    for(var i = 0; i < comp.length; i++){
        styles[comp[i]] = comp.getPropertyValue(comp[i]);
    }

    jQuery(this).css(styles);
}

【讨论】:

  • 最后我采用了类似的技术,即创建一个单独的跨度并将计算的样式应用于它,而不是将输入包装在一个跨度中。但是,一般方法是相同的,所以谢谢。