将 ::after 和 ::before 伪元素与托管文本元素重叠

Overlap ::after and ::before pseudo elements with hosting text element

更新:

我需要在文本中隐藏 @@,但保留在 HTML 中。


我有 HTML - <mark>@@Text@@</mark> 内的元素,基本上需要从文本的开头和结尾隐藏 @@。使用伪元素隐藏似乎很容易,但还需要从伪元素所在的位置删除 space 和黄色背景。

mark {
  position: relative;
  color: red;
}

mark::before {
  content: '@@';
  position: absolute;
  color: yellow;
  left: 0;
}

mark::after {
  content: '@@';
  position: absolute;
  color: yellow;
  right: 0;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <mark>@@Some Text@@</mark> |
  <mark>@@Some Text@@</mark> |
  <mark>@@Some Text@@</mark>
</body>
</html>

上面的代码带来了这个结果:

而我需要的是:

DEMO

p.s。您可以在演示中看到奇怪的行为 - 从 CSS 中删除一行,结果将与我的第一张图片中的一样。在 HTML 中输入一些内容,它会再次刹车。不知道为什么会发生这种情况,但如果可能的话,我也很想对此有所了解。

在你说的评论中:

Maybe a solution with Javascript then...?

i get as a string and then create mark and set innerhtm

最初我的解决方案(在下面的行下)是在收到时简单地删除它们,但是你说你必须将它们保存在 HTML。

因此,您将它们包装在一个内联元素中并隐藏它们,例如:

mark.innerHTML = theString.replace(/</g, "&lt;")
                          .replace(/&/g, "&amp;")
                          .replace(/^@@|@@$/g, "<span class=at>$&</span>");

(前两个替换是为了标记 <& 所以我们可以使用 innerHTML。如果字符串是 meant[=80 则删除它们=] 在其中包含 HTML 标记。)

有了这个CSS:

span.at {
    display: none;
}

(请注意,我假设这些 @@ 仅出现在实际文本中,而不出现在属性值中。)

实例:

const theString = "@@SOME TEXT@@";

const mark = document.createElement("mark");
mark.innerHTML = theString.replace(/</g, "&lt;")
                          .replace(/&/g, "&amp;")
                          .replace(/^@@|@@$/g, "<span class=at>$&</span>");
document.body.appendChild(mark);
span.at {
    display: none;
}


原解:

那么到目前为止,最好的办法是在您这样做时删除那些 @

mark.innerHTML = theString.replace(/^@@|@@$/g, "");

示例:

const theString = "@@SOME TEXT@@";

const mark = document.createElement("mark");
mark.innerHTML = theString.replace(/^@@|@@$/g, "");
document.body.appendChild(mark);


请注意,当您设置 innerHTML 时,字符串会被 读取为 HTML,而不是纯文本。因此,如果“SOME TEXT”包含 HTML 中的特殊字符,但应按字面意思处理,则结果不会很好:

const theString = "@@<SOME TEXT>huh? where did the rest go?@@";

const mark = document.createElement("mark");
mark.innerHTML = theString.replace(/^@@|@@$/g, "");
document.body.appendChild(mark);

如果是这样,请显式创建一个文本节点:

mark.appendChild(document.createTextNode(theString.replace(/^@@|@@$/g, "")));

示例:

const theString = "@@<SOME TEXT>ah, there it is@@";

const mark = document.createElement("mark");
mark.appendChild(document.createTextNode(theString.replace(/^@@|@@$/g, "")));
document.body.appendChild(mark);

以下解决方案是 hack,应谨慎使用(或根本不使用...)

/* 1.8em is approximately the width of @@, adjust it if needed */

mark {
  position: relative;
  display: inline-block;
  text-indent:-1.8em;  /* Hide the @@ at the left*/
  margin-right:-1.8em; /* Reduce the width of @@ from the right*/
  overflow: hidden; /* Hide the overflow on the left*/
  vertical-align: middle;
  /* Color only the text*/
  background:
    linear-gradient(red,red) left/calc(100% - 1.8em) 100% no-repeat;
  -webkit-background-clip:text;
  background-clip:text;
  color: transparent;
}
/* Replace the yellow background */
mark:before {
  content:"";
  position:absolute;
  z-index:-1;
  top:0;
  left:0;
  right:1.8em;
  bottom:0;
  background:yellow;
}
<mark>@@Some Text@@</mark> |
<mark style="font-size:28px;">@@Some more Text@@</mark> |
<mark>@@Text@@</mark>

试试 javascript

var str = document.getElementsByClassName('mark');

for(var i =0; i <= str.length; i++){
  var res = str[i].innerText.replace("@@", "");
    str[i].innerText = res.replace('@@','');
}