有没有办法用CSS从背景效果中剪切出透明文本,如下图所示?由于图像替换文本而失去所有宝贵的 SEO 将是可悲的。
https://i.stack.imgur.com/V6Bu7.png
我首先想到了阴影,但我想不出任何东西......
图片是网站背景,绝对定位的 <img>
标记
<h1><img alt="Some Text" /></h1>
比 <h1>Some Text</h1>
对 SEO 更友好的原因。传统上,图像的问题是它们刚刚被转储到页面上,没有任何支持标记。
css3 可以,但并非所有浏览器都支持
带背景剪辑:文本;您可以为文本使用背景,但您必须将其与页面背景对齐
身体{背景:网址(http://www.color-hex.com/palettes/26323.png)重复;边距:10px; } h1 { 背景颜色:#fff;溢出:隐藏;显示:内联块;填充:10px;字体粗细:粗体;字体系列:宋体;颜色:透明;字体大小:200px; } span { 背景: url(http://www.color-hex.com/palettes/26323.png) -20px -20px 重复; -webkit-text-fill-color:透明; -webkit-background-clip:文本;显示:块; }
http://jsfiddle.net/JGPuZ/1337/
自动对齐
使用一点 javascript,您可以自动对齐背景:
$(document).ready(function(){ //页面头部的位置 var position = $("h1").position(); var padding = 10; //设置到头部的padding var left = position .left + padding; var top = position.top + padding; $("h1").find("span").css("background-position","-"+left+"px -"+top+"px" ); });身体{背景:网址(http://www.color-hex.com/palettes/26323.png)重复;边距:10px; } h1 { 背景颜色:#fff;溢出:隐藏;显示:内联块;填充:10px;字体粗细:粗体;字体系列:宋体;颜色:透明;字体大小:200px; } span { 背景: url(http://www.color-hex.com/palettes/26323.png) -20px -20px 重复; -webkit-text-fill-color:透明; -webkit-background-clip:文本;显示:块; }
http://jsfiddle.net/JGPuZ/1336/
虽然这可以通过 CSS 实现,但更好的方法是将 inline SVG 与 SVG masking 一起使用。这种方法比 CSS 有一些优势:
更好的浏览器支持:IE10+、chrome、Firefox、safari...
这不会影响 SEO,因为蜘蛛可以抓取 SVG 内容(自 2010 年以来,谷歌索引 SVG 内容)
CodePen 演示:SVG text mask
https://i.stack.imgur.com/2wa2n.png
body,html{height:100%;margin:0;padding:0;} body{ background:url('https://farm9.staticflickr.com/8760/17195790401_94fcf60556_c.jpg');背景尺寸:封面;背景附件:固定; } svg{width:100%;}
如果您的目标是使文本可供选择和搜索,则需要将其包含在 <defs>
标记之外。以下示例显示了一种使用 <use>
标记保留透明文本的方法:
body,html{height:100%;margin:0;padding:0;} body{ background:url('https://farm9.staticflickr.com/8760/17195790401_94fcf60556_c.jpg');背景尺寸:封面;背景附件:固定; } svg{width:100%;}
<defs>
部分之外包含 <text>
。 (顺便说一句,我不确定 SE 爬虫如何处理 defs 中的 SVG 内容)。这是一种通过可怕的 FF 漏洞利用来保持 OP 想要的方法:jsfiddle.net/tfneqxxb
有一个简单的方法可以用 CSS 做到这一点:
background: black;
color: white;
mix-blend-mode: multiply;
对于黑色背景上的透明文本,或
background: white;
color: black;
mix-blend-mode: screen;
用于白色背景上的透明文本。
将这些样式放在您想要的任何背景的文本元素上。
https://i.stack.imgur.com/N5QgK.jpg
mix-blend-mode
上的 Read up 并尝试使用不同的颜色。
注意事项:
为了在 chrome 中工作,您还需要在 html 元素上显式设置背景颜色。这适用于除 IE 之外的所有现代浏览器。
mix-blend-mode
上使用 color-dodge
、 lighten
或 screen
html
元素上设置背景才能在 Chrome 中工作。
这是可能的,但到目前为止只有基于 Webkit 的浏览器(Chrome、Safari、Rockmelt,任何基于 Chromium 项目的东西。)
诀窍是在白色元素中有一个与正文具有相同背景的元素,然后在内部元素上使用 -webkit- background-clip: text;
,这基本上意味着“不要将背景扩展到文本之外”并使用透明文本。
section
{
background: url(http://norcaleasygreen.com/wp-content/uploads/2012/11/turf-grass1.jpg);
width: 100%;
height: 300px;
}
div
{
background: rgba(255, 255, 255, 1);
color: rgba(255, 255, 255, 0);
width: 60%;
heighT: 80%;
margin: 0 auto;
font-size: 60px;
text-align: center;
}
p
{
background: url(http://norcaleasygreen.com/wp-content/uploads/2012/11/turf-grass1.jpg);
-webkit-background-clip: text;
}
box-shadow
或 border-radius
,如果浏览器不支持这些属性,页面仍然可用,只是看起来不那么漂亮。这不是这个属性的情况。
只是把那个CSS
.banner-sale-1 .title-box .title-overlay {
font-weight: 900;
overflow: hidden;
margin: 0;
padding-right: 10%;
padding-left: 10%;
text-transform: uppercase;
color: #080404;
background-color: rgba(255, 255, 255, .85);
/* that css is the main think (mix-blend-mode: lighten;)*/
mix-blend-mode: lighten;
}
我刚刚发现了一种新的方法来解决这个问题,我不完全确定它是如何工作的(如果其他人想解释,请做)。
它似乎工作得很好,并且不需要双重背景或 JavaScript。
这是代码:JSFIDDLE
身体{填充:0;边距:0; } div { 背景: url(http://www.color-hex.com/palettes/26323.png) 重复;宽度:100vw;高度:100vh; } body::before { 内容:'$ALPHABET';左:0;顶部:0;位置:绝对;颜色:#222;背景颜色:#fff;填充:1rem;字体系列:宋体; z-index:1;混合混合模式:屏幕;字体粗细:800;字体大小:3rem;字母间距:1rem; }
在不久的将来,我们可以使用 element()
来实现这一点
element() 函数允许作者将文档中的元素用作图像。当引用的元素改变外观时,图像也会改变 ref
诀窍是创建一个带有文本的通用 div,然后将 element()
与 mask
结合使用。
这是一个基本示例,目前仅适用于最新版本的 Firefox。
#text { 字体大小:35px;字体粗细:粗体;颜色:#000;字体系列:无衬线;文本转换:大写;空白:nowrap; /* 我们隐藏它 */ position:fixed;右:200vw;底部:200vh } 正文 { 背景:url(https://picsum.photos/id/1018/800/800) 中心/封面; } .main { 边距:50px;高度:100px;背景:红色; -webkit-mask: -moz-element(#text) center/contain no-repeat, /* 这表现得像背景图像*/ linear-gradient(#fff 0 0);掩码复合:排除; }
它将产生以下内容:
https://i.stack.imgur.com/2fXsb.png
它是响应式的,因为我们依赖于基本的背景属性,并且我们可以使用基本的 CSS 轻松更新文本。
我们可以考虑任何类型的内容,也可以创建模式:
#text { 字体大小:30px;字体粗细:粗体;颜色:#000;字体系列:无衬线;文本转换:大写;空白:nowrap;填充:20px; /* 我们隐藏它 */ position:fixed;右:200vw;底部:200vh } #text span { font-family:cursive;字体大小:35px; } 正文 { 背景:网址(https://picsum.photos/id/1018/800/800)中心/封面; } .main { 边距:50px;高度:100px;背景:红色; -webkit-mask: -moz-element(#text) 0 0/20% auto, /* 这表现得像背景图像*/ linear-gradient(#fff 0 0);掩码复合:排除; }
https://i.stack.imgur.com/5RSkm.png
为什么不使用一些动画来创建无限滚动文本:
#text { 字体大小:30px;字体粗细:粗体;颜色:#000;字体系列:无衬线;文本转换:大写;空白:nowrap;填充:20px 5px; /* 我们隐藏它 */ position:fixed;右:200vw;底部:200vh } 正文 { 背景:url(https://picsum.photos/id/1018/800/800) 中心/封面; } .main { 边距:50px;高度:100px; padding-right:calc(50% - 50px);背景:红色; -webkit-mask: -moz-element(#text) 0 50%/200% auto content-box, /* 这表现得像背景图像*/ linear-gradient(#fff 0 0);掩码复合:排除;动画:m 5s 线性无限; } @keyframes m{ 到 {-webkit-mask-position:200% 50%} }
https://i.stack.imgur.com/WdhGK.gif
我想您可以实现类似 using background-clip
的效果,但我尚未对此进行测试。
看这个例子:
http://www.css3.info/wp-content/uploads/2008/03/webkit-backgroundcliptext_color.html
(仅限 Webkit,我还不知道如何将黑色背景更改为白色)
您可以使用倒置/否定/反向字体,并通过 font-face="…"
CSS 规则应用它。您可能必须使用字母间距来避免字母之间出现小的白色间隙。
如果您不需要特定的字体,那很简单。下载一个喜欢的,例如从此 collection of inverted fonts。
如果您需要特定的字体(例如“Open Sans”),那就很难了。您必须将现有字体转换为反转版本。这可以通过 Font Creator、FontForge 等手动实现,但我们当然想要一个自动化的解决方案。我还没有找到相关说明,但有一些提示:
如何将位图字体转换为 TrueType 字体(还有另一种方法)。首先使用 ImageMagick 命令将字体字形渲染为高分辨率光栅图像并反转它们,然后使用上述说明将它们转换回 TrueType 字体。
是否可以使用 FontForge 或其他 PGM 反转字体?
创建反向(黑底白字)字体
您可以使用 myadzel 的 Patternizer jQuery 插件跨浏览器实现此效果。目前,还没有跨浏览器的方法可以仅使用 CSS 来完成此操作。
您可以通过将 class="background-clip"
添加到您希望将文本绘制为图像模式的 HTML 元素来使用 Patternizer,并在附加的 data-pattern="…"
属性中指定图像。请参阅 demo 的来源。 Patternizer 将创建一个带有图案填充文本的 SVG 图像,并将其置于透明渲染的 HTML 元素上。
如果在问题的示例图像中,文本填充图案应该是超出“图案化”元素的背景图像的一部分,我会看到两个选项(未经测试,我最喜欢的第一个):
在 SVG 中使用遮罩而不是背景图像。正如 web-tiki 的回答,使用 Patternizer 仍然会自动生成 SVG,并在顶部添加一个不可见的 HTML 元素,允许文本选择和复制。
或者使用图案图像的自动对齐。可以使用类似于 Gijs 答案中的 JavaScript 代码来完成。
https://i.stack.imgur.com/HHtAP.png
我需要制作看起来与原始帖子中完全相同的文本,但我不能通过排列背景来伪造它,因为元素后面有一些动画。似乎还没有人提出这个建议,所以这就是我所做的:(试图使其尽可能易于阅读。)
var el = document.body; //Parent Element. Text is centered inside.
var mainText = "THIS IS THE FIRST LINE"; //Header Text.
var subText = "THIS TEXT HAS A KNOCKOUT EFFECT"; //Knockout Text.
var fontF = "Roboto, Arial"; //Font to use.
var mSize = 42; //Text size.
//Centered text display:
var tBox = centeredDiv(el), txtMain = mkDiv(tBox, mainText), txtSub = mkDiv(tBox),
ts = tBox.style, stLen = textWidth(subText, fontF, mSize)+5; ts.color = "#fff";
ts.font = mSize+"pt "+fontF; ts.fontWeight = 100; txtSub.style.fontWeight = 400;
//Generate subtext SVG for knockout effect:
txtSub.innerHTML =
"<svg xmlns='http://www.w3.org/2000/svg' width='"+stLen+"px' height='"+(mSize+11)+"px' viewBox='0 0 "+stLen+" "+(mSize+11)+"'>"+
"<rect x='0' y='0' width='100%' height='100%' fill='#fff' rx='4px' ry='4px' mask='url(#txtSubMask)'></rect>"+
"<mask id='txtSubMask'>"+
"<rect x='0' y='0' width='100%' height='100%' fill='#fff'></rect>"+
"<text x='"+(stLen/2)+"' y='"+(mSize+6)+"' font='"+mSize+"pt "+fontF+"' text-anchor='middle' fill='#000'>"+subText+"</text>"+
"</mask>"+
"</svg>";
//Relevant Helper Functions:
function centeredDiv(parent) {
//Container:
var d = document.createElement('div'), s = d.style;
s.display = "table"; s.position = "relative"; s.zIndex = 999;
s.top = s.left = 0; s.width = s.height = "100%";
//Content Box:
var k = document.createElement('div'), j = k.style;
j.display = "table-cell"; j.verticalAlign = "middle";
j.textAlign = "center"; d.appendChild(k);
parent.appendChild(d); return k;
}
function mkDiv(parent, tCont) {
var d = document.createElement('div');
if(tCont) d.textContent = tCont;
parent.appendChild(d); return d;
}
function textWidth(text, font, size) {
var canvas = window.textWidthCanvas || (window.textWidthCanvas = document.createElement("canvas")),
context = canvas.getContext("2d"); context.font = size+(typeof size=="string"?" ":"pt ")+font;
return context.measureText(text).width;
}
只需将其放入您的 window.onload 中,将身体的背景设置为您的图像,然后观看魔术发生!
mix-blend-mode
也是这种效果的一种可能性。
mix-blend-mode CSS 属性设置元素的内容应如何与元素的父级内容和元素的背景混合。
h1 { 背景:白色;混合混合模式:屏幕; /* 这里的演示目的 */ padding:0.25em;混合混合模式:屏幕; } html { 背景:url(https://i.picsum.photos/id/1069/367/267.jpg?hmac=w5sk7UQ6HGlaOVQ494mSfIe902cxlel1BfGUBpEYoRw)中心/封面;最小高度:100vh;显示:弹性; } body {margin:auto;} h1:hover {border:dashed 10px white;background-clip:content-box;box-shadow:inset 0 0 0 2px #fff, 0 0 0 2px #fff}
这在具有相反颜色的容器上对我 mix-blend-mode: color-dodge
有效。
.main{ 背景:url('https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg');高度:80vh;宽度:100vw;内边距:40px; } .container{ 背景颜色:白色;宽度:80%;高度:50px;内边距:40px;字体大小:3em;字体粗细:600;混合混合模式:颜色减淡; } .container span{ 颜色:黑色; }
恐怕现在用 CSS 是不可能的。
您最好的选择是简单地使用图像(可能是 PNG)并在其上放置良好的 alt/title 文本。
或者,您可以使用 SPAN 或 DIV 并将图像作为背景,并在其中包含您想要用于 SEO 目的的文本,但将其文本缩进屏幕之外。
不定期副业成功案例分享
background-clip:text
是一个仅限 Webkit 的非标准选项。 CSS3 不允许此属性 (see) 使用text
值。