javascript - Simulate external stroke::before 伪元素:透明文本的问题

标签 javascript html css svg

我很难相信没有标准和简单(并且独立于浏览器)的方法可以使用 CSS 在文本的外部 周围放置笔触效果。

我们确实有 -webkit-text-stroke 但由于某些奇怪的原因,笔画以文本的边框为中心,而不是 在它之外,作为bemoaned here .

所以我正在尝试根据 this idea 实现解决方法,它将描边文本放置在原始未描边文本后面的伪元素中。我在 this jsfiddle 中对此进行了演示,使用以下代码:

var jQueryAttr = function(selector, attr, setterFunction) {
  document.querySelectorAll(selector).forEach((el, i) => {
    el.setAttribute(attr, setterFunction.call(el, i, attr));
  });
};

jQueryAttr('.myclass', 'data-myclass', function(index, attr) {
  return this.innerHTML;
});
body {
  background: none;
}

.basic {
  color: rgba(186, 218, 85, 1);
  font: 2.5em Georgia, serif;
}

.myclass {
  position: relative;
  background: transparent;
  z-index: 0;
}

.myclass::before {
  content: attr(data-myclass);
  position: absolute;
  -webkit-text-stroke: 0.2em rgba(0, 0, 0, 1);
  z-index: -1;
}

.anotherclass {
  -webkit-text-stroke: 0.2em rgba(0, 0, 0, 1);
}
<p class="basic">Text without any stroke</p>
<p class="myclass basic">Text with outer stroke</p>
<p class="anotherclass basic">Without the trick applied</p>

这工作正常,除了如果文本本身有一些透明度然后你会看到下面的黑色笔划,如 this variant 所示。 (唯一的变化是将文本的不透明度重新设置为 0.3)。如您所见,描边元素的黑色渗入文本(在顶行)。

那么是否有另一个巧妙的技巧可以用来克服这个问题?我想可以在描边层和未描边层之间添加另一个伪元素,使用纯白色文本(或与背景匹配的文本),但我想在我 事先不知道背景的颜色...例如这是放置在任意用户选择的图像上的地方。为此,我在上面的示例中将 bodybackground 设置为 none

最佳答案

这是一个想法,您可以考虑使用 mix-blend-mode 和 text-shadow 的组合来近似此。棘手的部分是调整阴影以防你想要更大的笔触:

.text > span {
  font-family:sans-serif;
  font-size:60px;
  font-weight: bold;
  color:#fff; /*use white*/
  /*create the stroke around text*/
  text-shadow:
    2px 0  0px #000,
    0 2px 0px #000,
    2px 2px 0px #000,
    -2px 0 0px #000,
    0 -2px 0px #000,
    -2px -2px 0px #000,
    -2px 2px 0px #000,
    2px -2px 0px #000;
  mix-blend-mode: darken; /*everything is more dark than white so we always see the background */
}
.text {
  display:inline-block;
  padding:20px;
  background:linear-gradient(to right,red, blue);
}
<div class="text"><span>Some text here</span></div>

使用 CSS 变量可能会更容易调整:

.text > span {
  font-family:sans-serif;
  font-size:60px;
  font-weight: bold;
  color:#fff; /*use white*/
  /*create the stroke around text*/
  text-shadow:
    var(--s,2px) 0  var(--c,0) #000,
    0 var(--s,2px) var(--c,0) #000,
    var(--s,2px) var(--s,2px) var(--c,0) #000,
    calc(-1*var(--s,2px)) 0 var(--c,0) #000,
    0 calc(-1*var(--s,2px)) var(--c,0) #000,
    calc(-1*var(--s,2px)) calc(-1*var(--s,2px)) var(--c,0) #000,
    calc(-1*var(--s,2px)) var(--s,2px) var(--c,0) #000,
    var(--s,2px) calc(-1*var(--s,2px)) var(--c,0) #000;
  mix-blend-mode: darken; /*everything is more dark than white so we always see the background */
}
.text {
  display:inline-block;
  padding:20px;
  background:linear-gradient(to right,red, blue);
  background-size:cover;
  background-position:center;
}
<div class="text"><span>Some text here</span></div>

<div class="text" style="--s:4px;--c:2px;background-image:url(https://picsum.photos/800/600?image=1069)"><span>Some text here</span></div>

<div class="text" style="--s:6px;--c:4px;background-image:url(https://picsum.photos/800/600?image=1051)"><span>Some text here</span></div>

如果你想要文本的透明颜色,你可以使用伪元素复制它:

.text > span {
  font-family:sans-serif;
  font-size:60px;
  font-weight: bold;
  position:relative;
  display:inline-block;
}
.text > span::before,
.text > span::after {
  content:attr(data-text);
}
.text > span::before {
  color:#fff; /*use white*/
  /*create the stroke around text*/
  text-shadow:
    var(--s,2px) 0  var(--c,0) #000,
    0 var(--s,2px) var(--c,0) #000,
    var(--s,2px) var(--s,2px) var(--c,0) #000,
    calc(-1*var(--s,2px)) 0 var(--c,0) #000,
    0 calc(-1*var(--s,2px)) var(--c,0) #000,
    calc(-1*var(--s,2px)) calc(-1*var(--s,2px)) var(--c,0) #000,
    calc(-1*var(--s,2px)) var(--s,2px) var(--c,0) #000,
    var(--s,2px) calc(-1*var(--s,2px)) var(--c,0) #000;
  mix-blend-mode: darken; /*everything is more dark than white so we always see the background */
}
.text > span::after {
  position:absolute;
  top:0;
  left:0;
  color:rgba(0,255,0,0.4); 
}
.text {
  display:inline-block;
  padding:20px;
  background:linear-gradient(to right,red, blue);
  background-size:cover;
  background-position:center;
}
<div class="text"><span data-text="Some text here"></span></div>

<div class="text" style="--s:4px;--c:2px;background-image:url(https://picsum.photos/800/600?image=1069)"><span data-text="Some text here"></span></div>

<div class="text" style="--s:6px;--c:4px;background-image:url(https://picsum.photos/800/600?image=1051)"><span data-text="Some text here"></span></div>

关于javascript - Simulate external stroke::before 伪元素:透明文本的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54999526/

相关文章:

javascript - 获取数据后 javascript 将停止工作

javascript - 如何在通过 XMLHttpRequest 上传文件时获得进度

css - 我的搜索在主页上有效,但在其他页面上无效

javascript - React beautiful dnd 与 Material UI 列表中的问题

javascript - 为什么我的 cipher.final 因 key 不正确而失败?

javascript - 带有 YouTube 视频的轮播 slider

javascript - JavaScript 中的 if else 语句无法正常工作

html - outlook 在电子邮件签名中显示 css 代码

html - 删除拉脱维亚字母中的粗体

html - 怎么把文字放在图片下面