文本描边(-webkit-text-lines)css问题

ago*_*umi 11 css frontend sass next.js tailwind-css

我正在使用 NextJs 和 TailwindCSS 开发一个个人项目。

完成项目后,我使用私人导航器来查看进度,但似乎笔画没有按应有的方式工作,我在除 Chrome 之外的所有浏览器中都遇到了这种情况。

这是我得到的:

在此输入图像描述

这是所需的行为:

在此输入图像描述

代码:

<div className="outline-title text-white pb-2 text-5xl font-bold text-center mb-12 mt-8">
      Values &amp; Process
</div>
Run Code Online (Sandbox Code Playgroud)

CSS:

.outline-title {
  color: rgba(0, 0, 0, 0);
  -webkit-text-stroke: 2px black;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
Run Code Online (Sandbox Code Playgroud)

有人可以解释或帮助解决这个问题吗?

浏览器兼容性: 在此输入图像描述

her*_*zel 8

TL;DR:-webkit-text-stroke仍然很难预测

\n

@Satheesh Kumartext-shadow提出的可能是最可靠的解决方案。

\n

@Luke Taylor将文本复制到背景伪元素 \xe2\x80\x93 的方法 \xe2\x80\x93 也提供了一个很好的解决方法。

\n

可变字体的剖析

\n

正如@diopside:指出这种渲染行为与可变字体有关。
\n这些内部轮廓的原因是基于某些可变字体的结构。

\n

“传统”字体(因此在可变字体之前)\xe2\x80\x93 仅包含轮廓形状,并且可能包含反形状,例如小写e字形的切出内部“孔” 。

\n

否则,您会遇到不希望的偶数/奇数问题,导致由于重叠路径区域而导致排除形状。

\n

应用这种构造方法,您将永远不会看到任何形状的重叠。您可以将它们想象为“合并”的复合路径。类似上述孔的计数器形状基于简单的规则,例如逆时针路径方向 \xe2\x80\x93 顺便说一句。您可能仍然会在 svg 剪切路径中遇到这个概念 - 在某些浏览器中无法完美呈现)。

\n

在此输入图像描述

\n

然而,可变字体允许字形/字符的分段/重叠 构造,以促进不同字体粗细和宽度之间的插值。

\n

显然,webkit-text-stroke勾勒出字形/字符的精确 b\xc3\xa9zier 解剖结构,导致每个字形组件出现不需要的轮廓。

\n

这本身并不是可变字体的问题,因为粗细和宽度插值已在字体设计中使用了至少 25 年。因此,这个奇怪的渲染问题取决于所使用的字体 \xe2\x80\x93 许多经典/较旧的字体编译为较新的可变字体格式仍将依赖于旧的学校方法(避免任何重叠)。

\n

其他问题-webkit-text-stroke

\n
    \n
  • 渲染不一致:Firefox 渲染的笔划带有圆角
  • \n
  • 锐角上奇怪的“扭结和尖端”
  • \n
\n

文字笔划问题

\n
    \n
  1. Firefox - Roboto Flex(可变字体);2. Chromium - Roboto Flex(可变字体);3. Chromium - Roboto(静态字体);
  2. \n
\n

示例片段:测试-webkit-text-stroke渲染

\n

\r\n
\r\n
addOutlineTextData();\n\nfunction addOutlineTextData() {\n  let textOutline = document.querySelectorAll(".textOutlined");\n  textOutline.forEach((text) => {\n    text.dataset.content = text.textContent;\n  });\n}\n\nlet root = document.querySelector(\':root\');\n\n\nsampleText.addEventListener("input", (e) => {\n  let sampleText = e.currentTarget.textContent;\n  let textOutline = document.querySelectorAll(".textOutlined");\n  textOutline.forEach((text) => {\n    text.textContent = sampleText;\n    text.dataset.content = sampleText;\n  });\n});\n\nstrokeWidth.addEventListener("input", (e) => {\n  let width = +e.currentTarget.value;\n  strokeWidthVal.textContent = width + \'em\'\n  root.style.setProperty("--strokeWidth", width + "em");\n});\n\nfontWeight.addEventListener("input", (e) => {\n  let weight = +e.currentTarget.value;\n  fontWeightVal.textContent = weight;\n  document.body.style.fontWeight = weight;\n});\n\nuseStatic.addEventListener("input", (e) => {\n  let useNonVF = useStatic.checked ? true : false;\n  if (useNonVF) {\n    document.body.style.fontFamily = \'Roboto\';\n  } else {\n    document.body.style.fontFamily = \'Roboto Flex\';\n  }\n});
Run Code Online (Sandbox Code Playgroud)\r\n
@font-face {\n  font-family: \'Roboto Flex\';\n  font-style: normal;\n  font-weight: 100 1000;\n  font-stretch: 0% 200%;\n  src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXpRJ6cXW4O8TNGoXjC79QRyaLshNDUf9-EmFw.woff2) format(\'woff2\');\n}\n\nbody {\n  font-family: \'Roboto Flex\';\n  font-weight: 500;\n  margin: 2em;\n}\n\n.p,\np {\n  margin: 0;\n  font-size: 10vw;\n}\n\n.label {\n  font-weight: 500!important;\n  font-size: 15px;\n}\n\n.resize {\n  resize: both;\n  border: 1px solid #ccc;\n  overflow: auto;\n  padding: 1em;\n  width: 40%;\n}\n\n:root {\n  --textOutline: #000;\n  --strokeWidth: 0.1em;\n}\n\n.stroke {\n  -webkit-text-stroke: var(--strokeWidth) var(--textOutline);\n  color: #fff\n}\n\n.textOutlined {\n  position: relative;\n  color: #fff;\n}\n\n.textOutlined:before {\n  content: attr(data-content);\n  position: absolute;\n  z-index: -1;\n  color: #fff;\n  top: 0;\n  left: 0;\n  -webkit-text-stroke: var(--strokeWidth) var(--textOutline);\n  display: block;\n  width: 100%;\n}
Run Code Online (Sandbox Code Playgroud)\r\n
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700;900" rel="stylesheet">\n<p class="label">stroke width<input id="strokeWidth" type="range" value="0.3" min=\'0.01\' max="0.5" step="0.001"><span id="strokeWidthVal">0.25em</span> | font-weight<input id="fontWeight" type="range" value="100" min=\'100\' max="900" step="10"><span id="fontWeightVal">100</span>\n  <label><input id="useStatic" type="checkbox">Use static Roboto</label><br><br>\n</p>\n\n\n<div id="sampleText" class="stroke p" contenteditable>AVATAR last <br>Airbender</div>\n<p class="label">Outline via pseudo element in background</p>\n<div class="resize">\n  <p class="textOutlined">AVATAR last Airbender\n  </p>\n</div>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

然而,只要您的笔画宽度不显着大于 ~0.1em(或当前字体大小的 10%),这些渲染问题就很少见。

\n

另请参阅“文本轮廓效果”

\n


Sat*_*mar 5

由于浏览器兼容性的原因,某些浏览器不支持-webkit-text-lines 。可以利用阴影来达到轮廓效果。

希望这有效!

.outline-title {
font-family: sans-serif;
   color: white;
   text-shadow:
       1px 1px 0 #000,
     -1px -1px 0 #000,  
      1px -1px 0 #000,
      -1px 1px 0 #000,
       1px 1px 0 #000;
      font-size: 50px;
}
Run Code Online (Sandbox Code Playgroud)
<div class="outline-title text-white pb-2 text-5xl font-bold text-center mb-12 mt-8">
      Values &amp; Process
</div>
Run Code Online (Sandbox Code Playgroud)

- -更新- -

-webkit-文本笔画 |  MDN 网络文档