文本在Safari中的位置与其他浏览器中的不同

时间:2018-12-26 07:07:01

标签: html css safari webkit typography

文本在Safari中的定位与在其他浏览器中的定位不同。有这个原因吗?有没有一种样式可以确保它满足精确的测量。

* {
  margin: 0;
  padding: 0;
}
#btn_signup {
  opacity: 1;
  position: absolute;
  width: 185px;
  height: 50px;
  left: 10px;
  top: 10px;
  overflow: visible;
}
#Rectangle_1 {
  opacity: 1;
  fill: transparent;
  stroke: rgb(67, 66, 93);
  stroke-width: 1px;
  stroke-linejoin: miter;
  stroke-linecap: butt;
  stroke-miterlimit: 4;
  shape-rendering: auto;
}
.Rectangle_1 {
  position: absolute;
  overflow: visible;
  width: 185px;
  height: 50px;
  left: 0px;
  top: 0px;
}
#Sign_up {
  opacity: 1;
  position: absolute;
  left: 58px;
  top: 16px;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  overflow: visible;
  width: 63px;
  white-space: nowrap;
  text-align: center;
}
#Path_1 {
  opacity: 1;
  fill: rgba(0,0,0,0);
  stroke: rgb(112, 112, 112);
  stroke-width: 0.5px;
  stroke-linejoin: miter;
  stroke-linecap: butt;
  stroke-miterlimit: 4;
  shape-rendering: auto;
}
.Path_1 {
  overflow: visible;
  position: absolute;
  top: 16.5px;
  left: 1px;
  width: 183.5px;
  height: 0.5px;
  transform: matrix(1,0,0,1,0,0);
}
<div id="A5">
  <div id="btn_signup">
    <svg class="Rectangle_1">
      <rect id="Rectangle_1" rx="4" ry="4" x="0" y="0" width="185" height="50"></rect>
    </svg>
    <div id="Sign_up">
      <span style="font-family:Helvetica;font-style:normal;font-weight:normal;font-size:18px;color:rgba(77,79,92,1);display:inherit;">Sign up</span>
    </div>
    <svg viewBox="12.5 0 183.5 0.5" class="Path_1">
      <path id="Path_1" d="M 12.5 0 L 196 0"></path>
    </svg>
  </div>
</div>

在Firefox中,文本与该行齐平。在Safari中,有一些像素间隙,如下所示:

enter image description here

如何消除差距?

添加了赏金。询问是否需要进一步说明。

更新
感谢所有垂直居中的建议。我有一半的情况将通过垂直居中进行固定,而其余的情况是顶部对齐情况。

看起来我想要的是文本内容,该内容的边框在大写高度处与文本行的顶部边缘对齐,如图所示。

资源:
看来这是跨平台的常见问题。
Cap height and x-height metrics are inaccurate
Vertical Metrics

6 个答案:

答案 0 :(得分:3)

查看此问题和答案: WebKit vs Mozilla vertical alignment of font glyphs in box

基本上,CSS允许您使用文本元素的位置,但是实际字母相对于元素的位置取决于字体和浏览器。您不能直接修改它,这意味着从理论上讲,您不能真正确定字母本身的实际位置。

CSS允许您间接访问,例如使用 vertical-align ,您可以将文本与父文本对齐。因此,根据值,元素将相对于实际字母定位。例如:

div {
  font-size: 20px;
  line-height: 1.2;
  border-top: solid lightgray 1px;
  font-family: arial;
}

div span {
  display: inline-block;
  background-color: lightblue;
  border-top: solid red 1px;
}

.topalign span {
  vertical-align: top;
}

.bottomalign span {
  vertical-align: bottom;
}
<div class="topalign">
  <span style="font-family: 'helvetica neue'; ">Helvetica N</span>
  <span style="font-family: 'arial'; font-size: 30px">Arial</span>
  <span style="font-family: 'Times new roman';  ">Times NR</span>
  <span style="font-family: 'Tahoma'; font-size: 15px;">Tahoma</span>
</div>
<div class="bottomalign">
  <span style="font-family: 'helvetica neue'; ">Helvetica N</span>
  <span style="font-family: 'arial'; font-size: 30px">Arial</span>
  <span style="font-family: 'Times new roman';  ">Times NR</span>
  <span style="font-family: 'Tahoma'; font-size: 15px;">Tahoma</span>
</div>

您还可以使用 line-height 进行操作,这将更改文本元素的高度而不会更改字体大小,这意味着您可以或多或少地控制想要放置字母的位置。但是同样,不同的字体/浏览器将呈现不同的外观。您仍然无法准确定位字母。例如:

div {
  font-size: 30px;
  line-height: 1.2;
  border-top: solid lightgray 1px;
  font-family: arial;
}

div span {
  display: inline-block;
  background-color: lightblue;
  border-top: solid red 1px;
}

.topalign span {
  vertical-align: top;
}
<div class="topalign">
  <span style="font-family: 'helvetica neue'; ">Helvetica N</span>
  <span style="font-family: 'arial'; line-height: 1.5;">Arial</span>
  <span style="font-family: 'Times new roman';  line-height: 0.5;">Times NR</span>
  <span style="font-family: 'Tahoma'; ">Tahoma</span>
</div>

因此,从理论上讲,您无法精确地将实际字母的位置准确地定义在所需的位置。它不能是明确的,因此可能导致整个浏览器不一致。

话虽如此,您指出的情况似乎是Helvetica字体的Firefox错误。 Helvetica的字母定位与其他字体或其他浏览器不一致。与 Helvetica Neue Arial 进行比较时,这一点尤其明显,它们应该大致相同。参见:

div {
  font-size: 30px;
  line-height: 1.2;
  border-top: solid lightgray 1px;
  font-family: arial;
}

div span {
  display: inline-block;
  background-color: lightblue;
  border-top: solid red 1px;
}

.topalign span {
  vertical-align: top;
}
<div class="topalign">
  <span style="font-family: 'helvetica';  ">Helvetica </span>
  <span style="font-family: 'helvetica neue'; ">Helvetica N</span>
  <span style="font-family: 'arial'; ">Arial</span>
</div>

即使您不能明确说明字母的位置,也可以期望达到一定程度的一致性。正常情况下,顶部和底部的正常填充和前后填充大致相同。它可能因字体而异,以及因浏览器而异,但是在Firefox中呈现helvetica的方式肯定似乎是个错误(至少对我来说,也许是有原因的,但我不知道为什么)。

因此,如果您可以将 Helvetica 替换为 Helvetica Neue ,则可以使用 line-height 来定位字母与元素的位置并实现你想要什么。例如,通常约0.75的行高将与大写字母的顶部和底部齐平,这意味着通过定位元素,可以定位字母。例如:

* {
  margin: 0;
  padding: 0;
}
#btn_signup {
  opacity: 1;
  position: absolute;
  width: 185px;
  height: 50px;
  left: 10px;
  top: 10px;
  overflow: visible;
}
#Rectangle_1 {
  opacity: 1;
  fill: transparent;
  stroke: rgb(67, 66, 93);
  stroke-width: 1px;
  stroke-linejoin: miter;
  stroke-linecap: butt;
  stroke-miterlimit: 4;
  shape-rendering: auto;
}
.Rectangle_1 {
  position: absolute;
  overflow: visible;
  width: 185px;
  height: 50px;
  left: 0px;
  top: 0px;
}
#Sign_up {
  opacity: 1;
  position: absolute;
  left: 58px;
  top: 16px;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  overflow: visible;
  width: 63px;
  white-space: nowrap;
  text-align: center;
}
#Path_1 {
  opacity: 1;
  fill: rgba(0,0,0,0);
  stroke: rgb(112, 112, 112);
  stroke-width: 0.5px;
  stroke-linejoin: miter;
  stroke-linecap: butt;
  stroke-miterlimit: 4;
  shape-rendering: auto;
}
.Path_1 {
  overflow: visible;
  position: absolute;
  top: 16.5px;
  left: 1px;
  width: 183.5px;
  height: 0.5px;
  transform: matrix(1,0,0,1,0,0);
}
<div id="A5">
  <div id="btn_signup">
    <svg class="Rectangle_1">
      <rect id="Rectangle_1" rx="4" ry="4" x="0" y="0" width="185" height="50"></rect>
    </svg>
    <div id="Sign_up">
      <span style="font-family:Helvetica neue;font-style:normal;font-weight:normal;font-size:18px;color:rgba(77,79,92,1);display:inherit;line-height: 0.75;">Sign up</span>
    </div>
    <svg viewBox="12.5 0 183.5 0.5" class="Path_1">
      <path id="Path_1" d="M 12.5 0 L 196 0"></path>
    </svg>
  </div>
</div>

答案 1 :(得分:2)

不同的浏览器对小数点定位的处理方式不同。处理小数像素不在CSS规范中,因此即使现在一切都正确放置,在浏览器更新后它也可能再次中断。如果您删除所有小数像素值并添加line-height:1,它将正常工作。

如果这不起作用,请尝试执行此操作,然后告诉我您所看到的内容(我不使用Safari或FF)。在每个浏览器中检查span,该工具应突出显示一个矩形。查看矩形的顶部是否不触碰线条或文本的顶部是否不触碰矩形的顶部。在Chrome中,文本的顶部不接触矩形的顶部,因此解决方案是line-height:1

答案 2 :(得分:1)

position: relative;保留为#btn_signup。 同时使用以下CSS将Sign_up居中

#Sign_up {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

在所有浏览器中都可以使用。

* {
  margin: 0;
  padding: 0;
}

#btn_signup {
  opacity: 1;
  position: relative;
  width: 185px;
  height: 50px;
  left: 10px;
  top: 10px;
  overflow: visible;
}

#Rectangle_1 {
  opacity: 1;
  fill: transparent;
  stroke: rgb(67, 66, 93);
  stroke-width: 1px;
  stroke-linejoin: miter;
  stroke-linecap: butt;
  stroke-miterlimit: 4;
  shape-rendering: auto;
}

.Rectangle_1 {
  position: absolute;
  overflow: visible;
  width: 185px;
  height: 50px;
  left: 0px;
  top: 0px;
}

#Sign_up {
  opacity: 1;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  overflow: visible;
  width: 63px;
  white-space: nowrap;
  text-align: center;
}

#Path_1 {
  opacity: 1;
  fill: rgba(0, 0, 0, 0);
  stroke: rgb(112, 112, 112);
  stroke-width: 0.5px;
  stroke-linejoin: miter;
  stroke-linecap: butt;
  stroke-miterlimit: 4;
  shape-rendering: auto;
}

.Path_1 {
  overflow: visible;
  position: absolute;
  top: 16.5px;
  left: 1px;
  width: 183.5px;
  height: 0.5px;
  transform: matrix(1, 0, 0, 1, 0, 0);
}
<div id="A5">
  <div id="btn_signup">
    <svg class="Rectangle_1">
      <rect id="Rectangle_1" rx="4" ry="4" x="0" y="0" width="185" height="50"></rect>
    </svg>
    <div id="Sign_up">
      <span style="font-family:Helvetica;font-style:normal;font-weight:normal;font-size:18px;color:rgba(77,79,92,1);display:inherit;">Sign up</span>
    </div>
    <svg viewBox="12.5 0 183.5 0.5" class="Path_1">
      <path id="Path_1" d="M 12.5 0 L 196 0"></path>
    </svg>
  </div>
</div>

答案 3 :(得分:1)

字体在不同的浏览器上呈现不同。这是同一行文本的捕获。它已在所有主要浏览器上捕获,并相互叠加以说明问题的严重性。 (摘自this article

enter image description here

不同的字体会产生不同的结果

当我需要使文本垂直对齐像素完美时,我们有一个团队进行了一些研究。我们发现某些字体在垂直方向上比其他字体更好-因此值得测试。

您可以始终使用JS对其进行破解

如果是野生动物园-更改行高(或边距或其他值)

if (navigator.userAgent.toLowerCase().indexOf('safari') > -1) {
  $('.your-element').css({lineHeight: "21px"});
}

答案 4 :(得分:0)

请在CSS中替换此代码:

docker-compose

答案 5 :(得分:-4)

*{
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}

尝试