TL;DR: -webkit-text-stroke
仍然是相当不可预测的
the text-shadow
根据提议@萨西什·库马尔 https://stackoverflow.com/questions/69253420/text-stroke-webkit-text-stroke-css-problem/69937834#69908700可能是最可靠的解决方案。
@卢克·泰勒的方法 https://stackoverflow.com/questions/69253420/text-stroke-webkit-text-stroke-css-problem/69937834#73146972– 将文本复制到背景伪元素 – 也提供了一个很好的解决方法。
可变字体的剖析
正如@diopside:指出这种渲染行为是与可变字体有关。
这些内部轮廓的原因是基于一些可变字体的结构。
“传统”字体(因此在可变字体之前) - 仅包含轮廓形状,可能还包含反形状,例如小写字母的内部“孔”e glyph.
否则,您会遇到不希望的偶数/奇数问题,导致路径区域重叠而导致形状被排除。
应用这种构造方法,您将永远不会看到任何形状的重叠。您可以将它们想象为“合并”的复合路径。像前面提到的孔这样的计数器形状是基于简单的规则,比如逆时针路径方向——顺便说一句。您可能仍然会在 svg 剪切路径中遇到这个概念 - 在某些浏览器中无法完美呈现)。
然而,可变字体允许分段/重叠构建字形/字符以方便不同字体粗细和宽度之间的插值。
明显地webkit-text-stroke
勾勒出字形/字符的精确贝塞尔曲线解剖结构,从而导致每个字形组件出现不需要的轮廓。
这本身并不是可变字体的问题,因为粗细和宽度插值已在字体设计中使用了至少 25 年。因此,这个奇怪的渲染问题取决于所使用的字体 - 许多经典/较旧的字体编译为较新的可变字体格式仍将依赖于旧的学校方法(避免任何重叠)。
其他问题-webkit-text-stroke
- 渲染不一致:Firefox 渲染的笔划带有圆角
- 锐角上奇怪的“扭结和尖端”
- Firefox - Roboto Flex(可变字体); 2. Chromium - Roboto Flex(可变字体); 3. Chromium - Roboto(静态字体);
示例片段:测试-webkit-text-stroke
渲染
addOutlineTextData();
function addOutlineTextData() {
let textOutline = document.querySelectorAll(".textOutlined");
textOutline.forEach((text) => {
text.dataset.content = text.textContent;
});
}
let root = document.querySelector(':root');
sampleText.addEventListener("input", (e) => {
let sampleText = e.currentTarget.textContent;
let textOutline = document.querySelectorAll(".textOutlined");
textOutline.forEach((text) => {
text.textContent = sampleText;
text.dataset.content = sampleText;
});
});
strokeWidth.addEventListener("input", (e) => {
let width = +e.currentTarget.value;
strokeWidthVal.textContent = width + 'em'
root.style.setProperty("--strokeWidth", width + "em");
});
fontWeight.addEventListener("input", (e) => {
let weight = +e.currentTarget.value;
fontWeightVal.textContent = weight;
document.body.style.fontWeight = weight;
});
useStatic.addEventListener("input", (e) => {
let useNonVF = useStatic.checked ? true : false;
if (useNonVF) {
document.body.style.fontFamily = 'Roboto';
} else {
document.body.style.fontFamily = 'Roboto Flex';
}
});
@font-face {
font-family: 'Roboto Flex';
font-style: normal;
font-weight: 100 1000;
font-stretch: 0% 200%;
src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXpRJ6cXW4O8TNGoXjC79QRyaLshNDUf9-EmFw.woff2) format('woff2');
}
body {
font-family: 'Roboto Flex';
font-weight: 500;
margin: 2em;
}
.p,
p {
margin: 0;
font-size: 10vw;
}
.label {
font-weight: 500!important;
font-size: 15px;
}
.resize {
resize: both;
border: 1px solid #ccc;
overflow: auto;
padding: 1em;
width: 40%;
}
:root {
--textOutline: #000;
--strokeWidth: 0.1em;
}
.stroke {
-webkit-text-stroke: var(--strokeWidth) var(--textOutline);
color: #fff
}
.textOutlined {
position: relative;
color: #fff;
}
.textOutlined:before {
content: attr(data-content);
position: absolute;
z-index: -1;
color: #fff;
top: 0;
left: 0;
-webkit-text-stroke: var(--strokeWidth) var(--textOutline);
display: block;
width: 100%;
}
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700;900" rel="stylesheet">
<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>
<label><input id="useStatic" type="checkbox">Use static Roboto</label><br><br>
</p>
<div id="sampleText" class="stroke p" contenteditable>AVATAR last <br>Airbender</div>
<p class="label">Outline via pseudo element in background</p>
<div class="resize">
<p class="textOutlined">AVATAR last Airbender
</p>
</div>
然而,这些渲染只要您的描边宽度不明显大于 ~0.1em,问题就很少见(或当前字体大小的 10%)。
也可以看看“文字轮廓效果” https://stackoverflow.com/questions/4919076/outline-effect-to-text/74418325#74418325