SVG/CSS两色虚线描边是否可行?

22

是否可以使用CSS定义一条具有两种交替颜色且为虚线的线条(或形状边缘)?也就是说,如果1和2是不同颜色的像素,则:

1212121212121212或112211221122

我基本上想找到一种方法来使用stroke-dasharray和两种颜色。线本身完全着色。

如果这不可能,有什么好的方法可以近似实现它?例如,我可以创建一个重复的线性渐变,其中两种颜色交替出现,但是这将很难从JavaScript中设置两种颜色。


一种方法:http://www.webdevout.net/test?01v&raw (即,在具有一个颜色的第一层元素的后面,用另一种颜色形式的虚线描边绘制另一个颜色的第二层元素) - reisio
Reisio所说的似乎是迄今为止最好和最安全的答案。如果浏览器出现问题,Duopixel的解决方案似乎有更多潜在的错误可能性。能否把你的评论转换成答案? - Andrew Mao
6个回答

34

在 SVG 中,不能只使用一个元素实现这一点,但你可以使用两个不同的矩形,然后应用 stroke-dashoffset: x ...

rect.stroke-red {
  stroke: red;
  fill: none;
  stroke-width: 5;
}

rect.stroke-green {
  stroke: green;
  fill: none;
  stroke-dasharray: 5,5; 
  stroke-width: 5;
}
<svg xmlns="http://www.w3.org/2000/svg">
    <rect class="stroke-red" x="10" y="10" width="101" height="101" />
    <rect class="stroke-green" x="10" y="10" width="101" height="101" />
</svg>


2
你的回答很好,但我想指出我更喜欢上面评论中的实现方式——实线矩形后面跟着虚线矩形——因为它更少容易出错。如果CSS略有偏差或浏览器从不同位置开始虚线,stroke-dashoffset可能会导致矩形看起来很奇怪。 - Andrew Mao
1
我认为,如果浏览器在不同的位置开始虚线,那么这是一个浏览器的bug,如果CSS略有偏差,您将遇到与@reisio提供的解决方案相同的问题。然而,该答案适用于不支持SVG的浏览器。 - Colin Young
1
第一个版本其实更好。@AndrewMao,将条纹叠加在实心描边上会破坏抗锯齿效果。http://jsfiddle.net/rkzpC/ - Wray Bowling

21

在@duopixel的回答基础上,您可以使用stroke-dasharray属性来构建具有多种颜色的相对复杂的图案:

.L4 {
    stroke: #000;
    stroke-dasharray: 20,10,5,5,5,10;
}
.L5 {
    stroke: #AAA;
    stroke-dasharray: 0,20,10,15,10,0
}
.L6 {
    stroke: #DDD;
    stroke-dasharray: 0,35,5,15
}

查看 http://jsfiddle.net/colin_young/Y38u9/,演示了由复合虚线模式形成的线和圆。

已更新SO片段:

svg {
    width: 100%;
    height: 160px;
}
path, circle {
    stroke-width: 4;
}
text {
    alignment-baseline: central;
    font-family: sans-serif;
    font-size: 10px;
    stroke-width: 0;
    fill: #000;
    text-anchor: middle;
}
.dim {
    stroke: #AAA;
    stroke-width: 1;
    stroke-dasharray: 1, 1;
}
circle.dim {
    fill: #FFF;
}
.L4 {
    stroke: #000;
    stroke-dasharray: 20, 10, 5, 5, 5, 10;
}
.L5 {
    stroke: #AAA;
    stroke-dasharray: 0, 20, 10, 15, 10, 0
}
.L6 {
    stroke: #DDD;
    stroke-dasharray: 0, 35, 5, 15
}
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
    <g fill="none" stroke="black">
        <path class="dim" d="M5 20 l0 80" />
        <path class="dim" d="M25 20 l0 80 l-10 20" />
        <path class="dim" d="M35 20 l0 80 l-10 30" />
        <path class="dim" d="M40 20 l0 120" />
        <path class="dim" d="M45 20 l0 80 l10 30" />
        <path class="dim" d="M50 20 l0 80 l10 20" />
        <path class="dim" d="M60 20 l0 80 l15 10" />

        <text x="5" y="110">0</text>
        <text x="5" y="125">20</text>
        <text x="25" y="135">30</text>
        <text x="40" y="150">35</text>
        <text x="55" y="140">40</text>
        <text x="65" y="125">45</text>
        <text x="82" y="115">55</text>

        <path class="L4" d="M5 20 l215 0" />
        <path class="L5" d="M5 20 l215 0" />
        <path class="L6" d="M5 20 l215 0" />

        <!-- separated to show composition -->
        <text x="5" y="70" style="text-anchor:start">Separated to show composition:</text>
        <path class="L4" d="M5 80 l215 0" />
        <path class="L5" d="M5 90 l215 0" />
        <path class="L6" d="M5 100 l215 0" />

        <circle class="L4" cx="400" cy="80" r="60" />
        <circle class="L5" cx="400" cy="80" r="60" />
        <circle class="L6" cx="400" cy="80" r="60" />
    </g>
</svg>


1
非常好的例子。 - Chuck

3

一种方法:

<!doctype html>
<html>
	<head>
		<title></title>
		<style>
div {
	width: 100px;
	height: 100px;
}
.dashbox {
	border: 4px dashed blue;
	background: orange;
}
.dashbox > div {
	background: white;
}
		</style>
	</head>
	<body>
		<div class="dashbox">
			<div></div>
		</div>
	</body>
</html>

也就是说,用一种虚线边框和另一种颜色的背景层覆盖在另一种颜色的图层上。


1
这里有一个纯CSS的解决方案。

<div style="
    margin:1rem;
    width:4rem;
    height:4rem;
    border:5px solid red;
    outline:5px dashed green;
    outline-offset: -5px;"
></div>


0

可能适合您的一种方法是在描边上使用重复线性渐变。这是一个解决方法,对于line来说效果很好,因为您可以旋转渐变以匹配线条。

对于其他形状-它可能有效,但不如虚线数组好。好的一面是,它仅使用CSS,不需要额外的形状。

Codepen示例:

https://codepen.io/michbarsinai/pen/YzwXYwg


-4

对于底部有50个破折号的边框,创建50个带有递增margin-left的div,并使用overflow:hidden的整体容器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接