文本的轮廓效果

在CSS中有什么方法可以给不同颜色的文本提供轮廓吗?我想突出我的文本的一些部分,使其更直观-如名称,链接等。改变链接的颜色等是常见的现在,所以我想要一些新的东西。

740986 次浏览

在CSS3中有一个实验性的webkit属性称为text-stroke,我一直试图让它工作一段时间,但到目前为止还没有成功。

我所做的是使用已经支持的text-shadow属性(我相信在Chrome, Firefox, Opera和IE 9中都支持)。

使用四个阴影来模拟笔画文本:

.strokeme {
color: white;
text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
}
<div class="strokeme">
This text should have a stroke in some browsers
</div>

我已经做了一个演示给你

一个悬浮的例子是可以在这里


正如Jason C在评论中提到的,text-shadow CSS属性现在被所有主流浏览器支持,除了Opera Mini。这个解决方案将向后兼容(不是真正的浏览器自动更新的问题),我认为应该使用text-stroke CSS。

我正在寻找一个跨浏览器的文本笔画解决方案,工作时叠加在背景图像。我想我有一个解决方案,不涉及额外的标记,js和工作在IE7-9(我还没有测试6),也不会导致混淆问题。

这是一个使用CSS3文本阴影的组合,它有很好的支持,除了IE (http://caniuse.com/#search=text-shadow),然后使用IE过滤器的组合。目前CSS3文本笔画支持很差。

即过滤器

辉光滤镜(http://www.impressivewebs.com/css3-text-shadow-ie/)看起来很糟糕,所以我没有使用它。

大卫·休伊特的回答涉及到在组合方向上添加阴影过滤器。ClearType随后不幸被删除,因此我们最终得到了严重的别名文本。

然后,我将useragentman中建议的一些元素与dropshadow过滤器结合起来。

把它们放在一起

这个例子是带有白色描边的黑色文本。顺便说一下,我使用条件html类目标IE (http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/)。

#myelement {
color: #000000;
text-shadow:
-1px -1px 0 #ffffff,
1px -1px 0 #ffffff,
-1px 1px 0 #ffffff,
1px 1px 0 #ffffff;
}


html.ie7 #myelement,
html.ie8 #myelement,
html.ie9 #myelement {
background-color: white;
filter: progid:DXImageTransform.Microsoft.Chroma(color='white') progid:DXImageTransform.Microsoft.Alpha(opacity=100) progid:DXImageTransform.Microsoft.dropshadow(color=#ffffff,offX=1,offY=1) progid:DXImageTransform.Microsoft.dropshadow(color=#ffffff,offX=-1,offY=1) progid:DXImageTransform.Microsoft.dropshadow(color=#ffffff,offX=1,offY=-1) progid:DXImageTransform.Microsoft.dropshadow(color=#ffffff,offX=-1,offY=-1);
zoom: 1;
}

你可以尝试叠加多个模糊阴影,直到阴影看起来像笔画,如下所示:

.shadowOutline {
text-shadow: 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black;
}

这里有一把小提琴:http://jsfiddle.net/GGUYY/

我提到它只是为了以防有人感兴趣,尽管我不会称之为解决方案,因为它在很多方面都失败了:

  • 它不能在旧的IE中工作
  • 它在每种浏览器中的呈现方式都不一样
  • 应用这么多阴影是非常沉重的处理:S

我用6种不同的阴影得到了更好的结果:

.strokeThis{
text-shadow:
-1px -1px 0 #ff0,
0px -1px 0 #ff0,
1px -1px 0 #ff0,
-1px 1px 0 #ff0,
0px 1px 0 #ff0,
1px 1px 0 #ff0;
}

使用更粗的笔画会有点混乱,如果你有sass的乐趣尝试这个mixin,不完美,取决于笔画的重量,它会生成相当多的css。

 @mixin stroke($width, $colour: #000000) {
$shadow: 0 0 0 $colour; // doesn't do anything but I couldn't work out how to create a blank string and maintain commas
@for $i from 0 through $width {
$shadow: $shadow,
-$i + px -$width + px 0 $colour,
$i + px -$width + px 0 $colour,
-$i + px $width + px 0 $colour,
$i + px $width + px 0 $colour,
-$width + px -$i + px 0 $colour,
$width + px -$i + px 0 $colour,
-$width + px $i + px 0 $colour,
$width + px $i + px 0 $colour,
}
text-shadow: $shadow;
}

__abc3 __abc0 __abc4。它更容易,更清晰,更精确。如果你的浏览器用户可以支持它,你现在应该首先使用text-stroke,而不是text-shadow


你可以而且应该只使用text-shadow效果而不使用任何偏移量:

.outline {
color: #fff;
text-shadow: #000 0px 0px 1px;
-webkit-font-smoothing: antialiased;
}
< p >为什么?当你偏移多个阴影效果时,你会开始注意到笨拙、锯齿状的角: Shadow effect offsets result in noticeable jagged corners. < br > < br > < br > 在一个位置上使用文本阴影效果可以消除偏移,这意味着 如果你觉得太薄,想要一个深色的轮廓,没有问题-你可以重复同样的效果(保持相同的位置和模糊),几次。像这样:< / p >
text-shadow: #000 0px 0px 1px,   #000 0px 0px 1px,   #000 0px 0px 1px,
#000 0px 0px 1px,   #000 0px 0px 1px,   #000 0px 0px 1px;

下面是一个例子(上图),同样的效果重复了14次(下图):

< p > < br > Sample text render with text-shadow

.

还要注意:因为行变得很细,所以使用
-webkit-font-smoothing: antialiased关闭亚像素渲染是个好主意。

简单!SVG起到了拯救作用。

这是一个简化的方法:

svg{
font   : bold 70px Century Gothic, Arial;
width  : 100%;
height : 120px;
}


text{
fill            : none;
stroke          : black;
stroke-width    : .5px;
stroke-linejoin : round;
animation       : 2s pulsate infinite;
}


@keyframes pulsate {
50%{ stroke-width:5px }
}
<svg viewBox="0 0 450 50">
<text y="50">Scalable Title</text>
</svg>

这是一个更复杂的演示

CSS-only:

h1 {
font: 800 40px Arial;
-webkit-text-fill-color: transparent;
-webkit-text-stroke: 1px;
}
<h1>I am outlined</h1>

💡 Note that as of writing, the -webkit-text-stroke property cannot be transitioned/animated.

< br > < p >多个text-shadows . . 就像这样:

var steps = 10,
i,
R = 0.6,
x,
y,
theStyle = '1vw 1vw 3vw #005dab';
for (i = -steps; i <= steps; i += 1) {
x = (i / steps) / 2;
y = Math.sqrt(Math.pow(R, 2) - Math.pow(x, 2));
theStyle = theStyle + ',' + x.toString() + 'vw ' + y.toString() + 'vw 0 #005dab';
theStyle = theStyle + ',' + x.toString() + 'vw -' + y.toString() + 'vw 0 #005dab';
theStyle = theStyle + ',' + y.toString() + 'vw ' + x.toString() + 'vw 0 #005dab';
theStyle = theStyle + ',-' + y.toString() + 'vw ' + x.toString() + 'vw 0 #005dab';
}
document.getElementsByTagName("H1")[0].setAttribute("style", "text-shadow:" + theStyle);

演示:http://jsfiddle.net/punosound/gv6zs58m/

h1 {
color: black;
-webkit-text-fill-color: white; /* Will override color (regardless of order) */
-webkit-text-stroke-width: 1px;
-webkit-text-stroke-color: black;
}
<h1>Properly stroked!</h1>

这个用于SASS的mixin将给出平滑的结果,使用8轴:

@mixin stroke($size: 1px, $color: #000) {
text-shadow:
-#{$size} -#{$size} 0 $color,
0        -#{$size} 0 $color,
#{$size} -#{$size} 0 $color,
#{$size}  0        0 $color,
#{$size}  #{$size} 0 $color,
0         #{$size} 0 $color,
-#{$size}  #{$size} 0 $color,
-#{$size}  0        0 $color;
}

和普通CSS:

text-shadow:
-1px -1px 0 #000,
0   -1px 0 #000,
1px -1px 0 #000,
1px  0   0 #000,
1px  1px 0 #000,
0    1px 0 #000,
-1px  1px 0 #000,
-1px  0   0 #000;

我也有这个问题,并且text-shadow不是一个选项,因为角落看起来很糟糕(除非我有很多很多阴影),而且我不想要任何模糊,因此我唯一的其他选择是做以下:有2个div,对于背景div,在它上面放一个-webkit-text-stroke,然后允许尽可能大的轮廓。

div {
font-size: 200px;
position: absolute;
white-space: nowrap;
}


.front {
color: blue;
}


.outline {
-webkit-text-stroke: 30px red;
user-select: none;
}
<div class="outline">
outline text
</div>


<div class="front">
outline text
</div>  

使用这个,我能够实现line,因为如果你想让你的文本在非常大的轮廓下保持易读,stroke-width方法不是一个选项(因为使用stroke-width,轮廓将从字母内部开始,这使得它在宽度大于字母时不可读。

注意:我需要这么粗的轮廓的原因是我在“谷歌地图”中模拟街道标签,我想在文本周围有一个白色的粗光晕。这个解决方案对我来说非常有效。

这是一个小提琴显示这个解决方案

enter image description here

只要加上这个答案。“Stroking"正文与“大纲”不一样。

提纲看起来很棒。抚摸看起来很可怕。

其他地方列出的SVG解决方案也存在同样的问题。如果你想要一个大纲,你需要输入两次文本。一次抚摸,又一次不抚摸。

描边不是勾勒

body {
font-family: sans-serif;
margin: 20px;
}


.stroked {
color: white;
-webkit-text-stroke: 1px black;
}


.thickStroked {
color: white;
-webkit-text-stroke: 10px black;
}


.outlined {
color: white;
text-shadow:
-1px -1px 0 #000,
0   -1px 0 #000,
1px -1px 0 #000,
1px  0   0 #000,
1px  1px 0 #000,
0    1px 0 #000,
-1px  1px 0 #000,
-1px  0   0 #000;
}


.thickOutlined {
color: white;
text-shadow: 0.0px 10.0px 0.02px #000, 9.8px 2.1px 0.02px #000, 4.2px -9.1px 0.02px #000, -8.0px -6.0px 0.02px #000, -7.6px 6.5px 0.02px #000, 4.8px 8.8px 0.02px #000, 9.6px -2.8px 0.02px #000, -0.7px -10.0px 0.02px #000, -9.9px -1.5px 0.02px #000, -3.5px 9.4px 0.02px #000, 8.4px 5.4px 0.02px #000, 7.1px -7.0px 0.02px #000, -5.4px -8.4px 0.02px #000, -9.4px 3.5px 0.02px #000, 1.4px 9.9px 0.02px #000, 10.0px 0.8px 0.02px #000, 2.9px -9.6px 0.02px #000, -8.7px -4.8px 0.02px #000, -6.6px 7.5px 0.02px #000, 5.9px 8.0px 0.02px #000, 9.1px -4.1px 0.02px #000, -2.1px -9.8px 0.02px #000, -10.0px -0.1px 0.02px #000, -2.2px 9.8px 0.02px #000, 9.1px 4.2px 0.02px #000, 6.1px -8.0px 0.02px #000, -6.5px -7.6px 0.02px #000, -8.8px 4.7px 0.02px #000, 2.7px 9.6px 0.02px #000, 10.0px -0.6px 0.02px #000, 1.5px -9.9px 0.02px #000, -9.3px -3.6px 0.02px #000, -5.5px 8.4px 0.02px #000, 7.0px 7.2px 0.02px #000, 8.5px -5.3px 0.02px #000, -3.4px -9.4px 0.02px #000, -9.9px 1.3px 0.02px #000, -0.8px 10.0px 0.02px #000, 9.6px 2.9px 0.02px #000, 4.9px -8.7px 0.02px #000, -7.5px -6.7px 0.02px #000, -8.1px 5.9px 0.02px #000, 4.0px 9.2px 0.02px #000, 9.8px -2.0px 0.02px #000, 0.2px -10.0px 0.02px #000, -9.7px -2.3px 0.02px #000, -4.3px 9.0px 0.02px #000, 7.9px 6.1px 0.02px #000
}


svg {
font-size: 40px;
font-weight: bold;
width: 450px;
height: 70px;
fill: white;
}


.svgStroke {
fill: white;
stroke: black;
stroke-width: 20px;
stroke-linejoin: round;
}
<h1 class="stroked">Properly stroked!</h1>
<h1 class="outlined">Properly outlined!</h1>


<h1 class="thickStroked">Thickly stroked!</h1>
<h1 class="thickOutlined">Thickly outlined!</h1>


<svg viewBox="0 0 450 70">
<text class="svgStroke" x="10" y="45">SVG Thickly Stroked!</text>
</svg>
<svg viewBox="0 0 450 70">
<text class="svgStroke" x="10" y="45">SVG Thickly Outlined!</text>
<text class="svgText" x="10" y="45">SVG Thickly Outlined!</text>
</svg>

PS:我想知道如何使SVG是任何任意文本的正确大小。我感觉这相当复杂,包括生成SVG,用Javascript查询它以获得范围,然后应用结果。如果有更简单的非js方式,我很想知道。


正如@12me21指出的那样,在SVG中,你可以使用paint-order="stroke"在填充之前使其描边,这样你就不必重复文本了

svg {
font-size: 40px;
font-weight: bold;
width: 450px;
height: 70px;
fill: white;
}


.svgText {
fill: white;
stroke: black;
stroke-width: 15px;
stroke-linejoin: round;
paint-order: stroke;
}
<svg viewBox="0 0 450 70">
<text class="svgText" x="10" y="45">SVG Thickly Outlined!</text>
</svg>

文本阴影生成器

这里有很多很棒的答案。看起来文本阴影可能是最可靠的方法来做到这一点。我不会详细说明如何使用文本阴影来做到这一点,因为其他人已经这样做了,但基本思想是在文本元素周围创建多个文本阴影。文本轮廓越大,需要的文本阴影就越多。

所有提交的答案(截至本文)都为文本阴影提供了静态解决方案。我采用了不同的方法,并编写了这JSFiddle,它接受轮廓颜色、模糊和宽度值作为输入,并为元素生成适当的文本阴影属性。只需填写空白,检查预览,然后单击复制css并将其粘贴到您的样式表。


不必要的阑尾

显然,包含指向JSFiddle链接的答案不能被发布,除非它们也包含代码。如果你愿意,你可以完全忽略这个附录。这是我的小提琴生成文本阴影属性的JavaScript。请注意,你做不< em > < / em >需要实现这段代码在你自己的作品:

function computeStyle() {
var width = document.querySelector('#outline-width').value;
width = (width === '') ? 0 : Number.parseFloat(width);
var blur = document.querySelector('#outline-blur').value;
blur = (blur === '') ? 0 : Number.parseFloat(blur);
var color = document.querySelector('#outline-color').value;
if (width < 1 || color === '') {
document.querySelector('.css-property').innerText = '';
return;
}
var style = 'text-shadow: ';
var indent = false;
for (var i = -1 * width; i <= width; ++i) {
for (var j = -1 * width; j <= width; ++j) {
if (! (i === 0 && j === 0 && blur === 0)) {
var indentation = (indent) ? '\u00a0\u00a0\u00a0\u00a0' : '';
style += indentation + i + "px " + j + "px " + blur + "px " + color + ',\n';
indent = true;
}
}
}
style = style.substring(0, style.length - 2) + '\n;';
document.querySelector('.css-property').innerText = style;


var exampleBackground = document.querySelector('#example-bg');
var exampleText = document.querySelector('#example-text');
exampleBackground.style.backgroundColor = getOppositeColor(color);
exampleText.style.color = getOppositeColor(color);
var textShadow = style.replace(/text-shadow: /, '').replace(/\n/g, '').replace(/.$/, '').replace(/\u00a0\u00a0\u00a0\u00a0/g, '');
exampleText.style.textShadow = textShadow;
}

字母背后的简单轮廓。 适用于任何字体。

enter image description here

<style>
text {
stroke-linejoin: round;
text-anchor: middle;
fill: black;
stroke: white;
stroke-width: 12px;
paint-order: stroke;
}
</style>


<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<text x="50%" y="50%" dominant-baseline="central" text-anchor="middle">Text</text>
</svg>

Codepen: https://codepen.io/RilDev/pen/vYeOjgj?editors=1000

我们可以使用文本笔画

超文本标记语言

<h1>Sample Text</h1>

CSS

  h1{
-webkit-text-stroke: 2px red;
text-stroke: 2px red;
}

小菜一碟。试试这个,而不是使用文本阴影

试一试:

<!DOCTYPE html>
<html>
<head>
<style>
h1 {
text-shadow: 2px 2px;
}
h1.m1 {
text-shadow: 2px 2px red;
}
h1.m2 {
text-shadow: 2px 2px 5px red;
}
h1.m3 {
color: white;
text-shadow: 2px 2px 4px #000000;
}
h1.m4 {
text-shadow: 0 0 3px #FF0000;
}
h1.m5{
color: #FFFFFF;
background: #232323;
text-shadow: 0 0 5px #FFF, 0 0 10px #FFF, 0 0 15px #FFF, 0 0 20px #49ff18, 0 0 30px #49FF18, 0 0 40px #49FF18, 0 0 55px #49FF18, 0 0 75px #49ff18;
}
h1.m6{
color: #FFFFFF;
background: #FFFFFF;
text-shadow: 2px 2px 0 #4074b5, 2px -2px 0 #4074b5, -2px 2px 0 #4074b5, -2px -2px 0 #4074b5, 2px 0px 0 #4074b5, 0px 2px 0 #4074b5, -2px 0px 0 #4074b5, 0px -2px 0 #4074b5;
}
h1.m7
{
color: #444444;
background: #FFFFFF;
text-shadow: 1px 0px 1px #CCCCCC, 0px 1px 1px #EEEEEE, 2px 1px 1px #CCCCCC, 1px 2px 1px #EEEEEE, 3px 2px 1px #CCCCCC, 2px 3px 1px #EEEEEE, 4px 3px 1px #CCCCCC, 3px 4px 1px #EEEEEE, 5px 4px 1px #CCCCCC, 4px 5px 1px #EEEEEE, 6px 5px 1px #CCCCCC, 5px 6px 1px #EEEEEE, 7px 6px 1px #CCCCCC;
}
</style>
</head>
<body>
<h1 class="m6">Text-shadow effect!</h1>
<h1 class="m7">Text-shadow effect!</h1>
<h1>Text-shadow effect!</h1>
<h1 class="m1">Text-shadow effect!</h1>
<h1 class="m2">Text-shadow effect!</h1>
<h1 class="m3">Text-shadow effect!</h1>
<h1 class="m4">Text-shadow effect!</h1>
<h1 class="m5">Text-shadow effect!</h1>
</body>
</html>

我很抱歉,但是如果您已经了解到这里,您将意识到所有其他答案都是不够的,或者需要SVG。

Take-Two v Anderson

< p > 注意:这个漂亮的大纲将花费你在data-content属性中维护文本副本的小代价,该属性由分层CSS3::before元素使用,该元素将填充文本呈现在实际大纲之上
.outline {
color: black;
-webkit-text-stroke: 0.15em black;
}


.outline::before {
content: attr(data-content);
-webkit-text-fill-color: white;
-webkit-text-stroke: 0;
position: absolute;
}


.outline-wrapper {
font-family: "DaytonaW01-CondensedBold", Impact, Times, serif;
font-size: 50px;
}
<div class="outline-wrapper">
<div class="outline" data-content="Take-Two v Anderson">Take-Two v Anderson
</div>
</div>
<link href="https://db.onlinewebfonts.com/c/998b5de3cda797387727724405beb7d4?family=DaytonaW01-CondensedBold" rel="stylesheet" type="text/css"/>

外部样式链接只是为了包含字体,而不是必需的——尽管使用细字体可能需要调整描边参数。