SVG/CSS stroke dashed line with two colors - is it possible?

33,178

Solution 1

This is not possible in SVG with just one element, but you can use two different rects and then apply a 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>

Solution 2

Building on the answer from @duopixel, you can use the stroke-dasharray property to build up a fairly complex pattern with multiple colors:

.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
}

See http://jsfiddle.net/colin_young/Y38u9/ demonstrating lines and a circle with the composite dash pattern.

Updated with SO snippet:

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>

Solution 3

One way:

<!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>

That is, layer one element with one color behind another with another color [in the form of a dashed stroke].

Solution 4

Here is a CSS only solution.

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

Share:
33,178
Andrew Mao
Author by

Andrew Mao

https://github.com/mizzao

Updated on July 05, 2022

Comments

  • Andrew Mao
    Andrew Mao almost 2 years

    Is it possible to use CSS to define a line (or shape edge) with two alternating colors that are dashed? That is, if 1 and 2 are different colored pixels, then

    1212121212121212 or 112211221122

    I basically want some way to use stroke-dasharray with two colors. The line itself is completely colored.

    If this is not possible, what is a good way to approximate it? For example, I could create a repeated linear gradient with two colors alternating, but this would be hard to set the two colors from javascript.

  • Andrew Mao
    Andrew Mao over 11 years
    Your answer is good, but I'll point out that I prefer the implementation in the above comment - solid line rectangle behind a dashed line rectangle - for being less error-prone. It seems like the stroke-dashoffset could result in funny looking rectangles if the CSS was slightly off or the browser started the dashes in different places.
  • Colin Young
    Colin Young about 11 years
    I think if the browser is starting the dashes in different places that's a browser bug, and if the CSS is slightly off, you're going to have the same issues with the solution from @reisio. However, that answer will work for browsers that don't support SVG.
  • Wray Bowling
    Wray Bowling about 10 years
    The first version was actually better. @AndrewMao, overlaying the stripes on top of a solid stroke messes up the anti-aliasing. jsfiddle.net/rkzpC
  • Chuck
    Chuck almost 5 years
    Really nice example.