Svg/CSS Stroke Dashed Line with Two Colors - Is It Possible

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

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>

Adding different colors to dashes of an SVG stroke

You can construct a linear gradient for many lines that can give you different color dashes - but its quite difficult because you have to arrange it so that that gradient transitions all occur in the gaps between stroke dashes. If the dash gaps are too narrow or the line is too squiggly - then you have to go through severe contortions to make it work. It's easier to just use different overlaid paths with customized stroke-dash arrays.

But it IS often possible - here is an example that works with your specific line.

 .c-dashed-line__path {
stroke: url(#special-gradient);
stroke-dasharray: 200 40 200 40 480 40;
/* this is the entire length of the line */
stroke-dashoffset: 0;
/* this is the entire length of the line */
stroke-width: 60;

}

.c-dashed-line__overlay {
animation: c-dashed-line-path 5s forwards;
fill: none;
stroke: white;
/* this must match the background color */
stroke-dashoffset: -1475;
stroke-dasharray: 1475;
/* draws a 10px dash line with a 16px gap between */
stroke-width: 70;
/* make the dashed line slightly bigger than the one it's covering */
}

@keyframes c-dashed-line-path {
from {
stroke-dashoffset: 0;
}
to {
stroke-dashoffset: -1475;
}
}

svg{
width:100%;
height:100%;
position: absolute;
}
<svg id="svg11"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 2133.3333 1200"
height="1200"
width="2133.3333"
version="1.1">

<defs>

<linearGradient id="special-gradient" y1="0%" y2="130%" x1="0%" x2="200%">
<stop offset="0%" stop-color="gold" />
<stop offset="9%" stop-color="gold" />
<stop offset="9%" stop-color="red" />
<stop offset="18.4%" stop-color="red" />
<stop offset="18.4%" stop-color="green" />
<stop offset="39%" stop-color="green" />
<stop offset="39%" stop-color="blue" />
<stop offset="48%" stop-color="blue" />
<stop offset="48%" stop-color="gray" />
<stop offset="100%" stop-color="grey" />
</linearGradient>

<path
id="c-dashed-line" class="path2"
d="m 548.50746,29.104478 c 0,0 136.56717,279.850742 228.35821,293.283582 91.79105,13.43284 91.79105,13.43284 91.79105,13.43284 0,0 154.47758,22.38806 214.92538,134.32835 60.4478,111.9403 40.2985,203.73135 147.7612,295.52239 107.4627,91.79105 208.2089,-6.71642 380.597,114.17911"
style="fill:none;" />

</defs>
<use class="c-dashed-line__path" xlink:href="#c-dashed-line"/>
<!--overlay -->
<use class="c-dashed-line__overlay" xlink:href="#c-dashed-line"/>

<rect x="80%" y="0%" width="20%" height="20%" fill="url(#special-gradient)"/>
</svg>

How to create a dashed border with two alternating colours?

Built on Yadab's answer, adding a pseudo element to fix the vertical border.

Basically you create a line with repeating-linear-gradient and set it to border-image.

:root {
--border-size: 2px;
--box-width: 36em;
--box-height: 8em;
--dash-size: 1em;
}

.box,
.box::after {
height: var(--box-height);
width: var(--box-width);
border: solid;
}

.box {
border-image: repeating-linear-gradient( to right, red 0, red var(--dash-size), transparent var(--dash-size), transparent calc(var(--dash-size) * 2), blue calc(var(--dash-size) * 2), blue calc(var(--dash-size) * 3), transparent calc(var(--dash-size) * 3), transparent calc(var(--dash-size) * 4));
border-image-slice: 16;
border-image-width: var(--border-size) 0;
}

.box::after {
content: "";
top: 0;
position: absolute;
border-image: repeating-linear-gradient( to bottom, blue 0, blue var(--dash-size), transparent var(--dash-size), transparent calc(var(--dash-size) * 2), red calc(var(--dash-size) * 2), red calc(var(--dash-size) * 3), transparent calc(var(--dash-size) * 3), transparent calc(var(--dash-size) * 4));
border-image-slice: 16;
border-image-width: 0 var(--border-size);
}
<div class="box"></div>

Double stroke color of circle in svg

Sadly, you can't set an SVG to have a double stroke, only a dashed or solid stroke.

Instead, just create an element exactly the same but reduce the size/radius of it by however much you require.

.circle {  fill: none;  stroke: black;}
<svg height="100" width="100">  <circle class="circle" cx="50" cy="50" r="40" stroke-width="1" />  <circle class="circle" cx="50" cy="50" r="38" stroke-width="1" /></svg>

Svg line half solid, half dashed

  • Put a pathLength="100" on the line so the total length is calculated as 100 units

    https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/pathLength

  • set the stroke-dasharray units to the pattern you want:

    Sample Image

<svg>
<line pathLength="100" stroke-dasharray="50,2,5,2,5,2,5,2,5,2,5,2,5"
stroke="black" stroke-width="4"
x1="10" x2="280" y1="10" y2="10" />
</svg>

Animate SVG dotted line a different color progressively

Use an SVG mask animation.

  • The bottom layer is a blue curve

  • Top layer - gray curve

When the mask is animated from left to right, the upper gray curve is cut through and the lower blue curve becomes visible as a result.

 <animate attributename="x" begin="svg1.click" dur="4s" values="-452;0" repeatCount="indefinite" />

An illusion is created of filling the curve gray color with a blue.

Animation will start after clicking

<svg id="svg1" width="455" height="102" viewBox="0 0 455 102" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<mask id="msk">
<rect width="100%" height="100%" fill="white" />
<rect fill="black" x="-452" y="0" width="450" height="100" >
<animate id="an" attributeName="x" begin="svg1.click;an.end+0.5s" dur="7s" values="-452;10" repeatCount="1" fill="freeze" />
</rect>
</mask>
</defs>

<path id="path" d="M451.556 25.1576C435.152 73.3258 366.885 125.586 296.309 84.449C257.221 59.9286 203.507 18.9945 182.449 13.1117C114.633 -12.4168 41.0939 12.8604 2.57437 66.1813" stroke="#007CFF" stroke-width="5" stroke-miterlimit="10" stroke-linecap="round" stroke-dasharray="10 20"/>

<path mask="url(#msk)" d="M451.556 25.1576C435.152 73.3258 366.885 125.586 296.309 84.449C257.221 59.9286 203.507 18.9945 182.449 13.1117C114.633 -12.4168 41.0939 12.8604 2.57437 66.1813" stroke="#BCBCBC" stroke-width="5" stroke-miterlimit="10" stroke-linecap="round" stroke-dasharray="10 20"/>
</svg>

Declaratively stroke a line with a composite line symbol using SVG

You can do this with a morphology filter and some fanciness. This filter works by

  • Starting with a green dash-stroke and red fill
  • Then creating a layer with the red fill set to transparent (just stroke)
  • And a layer with the stroke set to transparent (just fill)
  • Then taking the dash-stroked path and dilating it until the gaps overlap :)
  • Adding a blur and an opacity clip to get a nice path (morphology results are usually pixelated and need a bit of help to look good)
  • Changing the original green stroke path to black
  • Overlaying the newly black stroke path on the fat green line we produced from morphology
  • Clipping the result with the original fill so we get the dash stroke at the edge of the main line rather than the middle.

In all, you're probably better off using two paths. But if you must... :)

<svg width="2000px" height="2000px" viewBox="0 0 4000 4000">  <defs>    <filter id="dual-line" primitiveUnits="userSpaceOnUse">      <feColorMatrix result="just-stroke" type="matrix" values="0 0 0 0 0                                           0 1 0 0 0                                            0 0 1 0 0                                            -1 0 0 1 0"/>             <feColorMatrix in="SourceGraphic" result="just-fill" type="matrix"                                    values="0 0 0 0 1                                           0 0 0 0 0                                            0 0 0 0 0                                            0 0 0 1 0"/>                    <feMorphology in="just-stroke" operator="dilate" radius="10"/>       <feGaussianBlur stdDeviation="6"/>      <feComponentTransfer result="pre-outer">        <feFuncA type="table" tableValues="0 0 0 0.95 .95 .95 .95 .95  1">      </feComponentTransfer>                <feColorMatrix result="blackstroke" in="just-stroke" type="matrix" values=" 0 0 0 0 0                                                                0 0 0 0 0                                                                0 0 0 0 0                                                                 0 0 0 1 0"/>               <feComposite operator="over" in2="pre-outer" in="blackstroke"/>        <feComposite operator="in" in2="just-fill"/>       </filter>    </defs><g filter="url(#dual-line)">  <path d="M100 800 C 400 100, 650 100, 950 800 S 1500 1500, 100 800" stroke-width="5" stroke="green" fill="red" stroke-dasharray="25, 5, 3, 5"/></g></svg>

Filling an SVG path with multiple colors

I think you would be able to use a linear gradient and use two color-stops for each solid color. Something like this

<svg height="200" width="600">  <defs>    <linearGradient id="solids" x1="0%" y1="0%" x2="100%" y2="0%">      <stop offset="0%" style="stop-color:rgb(255,0,0);stop-opacity:1" />      <stop offset="33%" style="stop-color:rgb(255,0,0);stop-opacity:1" />      <stop offset="33%" style="stop-color:rgb(0,255,0);stop-opacity:1" />      <stop offset="67%" style="stop-color:rgb(0,255,0);stop-opacity:1" />      <stop offset="67%" style="stop-color:rgb(0,0,255);stop-opacity:1" />      <stop offset="100%" style="stop-color:rgb(0,0,255);stop-opacity:1" />    </linearGradient>  </defs>  <rect width="600" height="200" fill="url(#solids)" /></svg>


Related Topics



Leave a reply



Submit