Gracelle Mesina Gracelle Mesina - 2 months ago 14
CSS Question

SVG icon animation leaves a pixel gap

I'm working on SVG animations with CSS and I've noticed that with my line drawing animations, any SVG rect (#clipboard-border and #clipboard-clip-border) stroke always excludes a bit of the top-left corner, which makes it an incomplete rectangle.

I've tried adjusting the stroke-dasharray and stroke-dashoffset measurements within the CSS, as well as adjusting the sizes and pixel coordinated within the SVG code, but neither are the problem it seems. Help?



html,
body {
width: 100%;
height: 100%;
background-color: #CECECE;
}
div {
text-align: center;
}
svg {
display: inline-block;
width: 120px;
margin: 3% auto;
padding: 0px 100px;
}
/* ---------------------
SVG RULES
--------------------- */

/* All grey strokes */

#clipboard-border,
.clipboard-content,
.clipboard-borders,
.mech-pencil-borders {
fill: none;
stroke: #4D5152;
stroke-width: 6;
stroke-miterlimit: 10;
}
/* All things white */

#clipboard-paper-fill,
#mech-pencil-eraser-fill {
fill: #F3F7F6;
}
/* All things green */

#mech-pencil-point-fill,
#mech-pencil-top-fill {
fill: #25B686;
}
/* All things blue */

#clipboard-fill {
fill: #85D0D3;
}
/* All things yellow */

#clipboard-clip-fill,
#mech-pencil-grip {
fill: #FBFBCE;
}
#clipboard-knob-1,
#clipboard-knob-2,
#clipboard-knob-3,
#mech-pencil-bottom-btn,
#mech-pencil-top-btn {
stroke-dasharray: 8px;
stroke-dashoffset: 8px;
animation: trace .5s ease-out forwards;
}
/* ---------------------
ANIMATION KEYFRAMES
--------------------- */

@keyframes trace {
100% {
stroke-dashoffset: 0px;
}
}
@keyframes fill-it {
100% {
opacity: 1;
}
}
@keyframes grow {
0% {
transform: scale(0);
}
30% {
transform: scale(1.1);
}
60% {
transform: scale(.9);
}
}
/* ---------------------
SVG ANIMATION: INSIGHT & PLANNING ICON
--------------------- */

#clipboard-clip-border {
stroke-dasharray: 180px;
stroke-dashoffset: 180px;
animation: trace .2s ease-out forwards;
}
#clipboard-clip-fill {
opacity: 0;
animation: fill-it .2s .2s ease-in-out forwards;
}
#clipboard-border {
stroke-dasharray: 640px;
stroke-dashoffset: 640px;
animation: trace 1.25s ease-in-out forwards;
}
#clipboard-fill,
#mech-pencil-point-fill,
#mech-pencil-top-fill {
opacity: 0;
animation: fill-it .25s 1.25s ease-in-out forwards;
}
#clipboard-paper-border {
stroke-dasharray: 400px;
stroke-dashoffset: 400px;
animation: trace 1s ease-out forwards;
}
#clipboard-paper-fill,
#mech-pencil-eraser-fill,
#mech-pencil-grip {
opacity: 0;
animation: fill-it .75s 1s ease-in-out forwards;
}
#clipboard-content-line-1 {
stroke-dasharray: 30px;
stroke-dashoffset: 30px;
animation: trace .5s ease-out forwards;
}
#clipboard-content-line-7,
#clipboard-clip-detail {
stroke-dasharray: 52px;
stroke-dashoffset: 52px;
animation: trace .5s ease-out forwards;
}
#clipboard-content-line,
#clipboard-content-line-even,
#mech-pencil-eraser-border {
stroke-dasharray: 80px;
stroke-dashoffset: 80px;
animation: trace .75s ease-out forwards;
}
#mech-pencil-border-left,
#mech-pencil-border-right {
stroke-dasharray: 115px;
stroke-dashoffset: 115px;
animation: trace .75s ease-out forwards;
}
#mech-pencil-point-border {
stroke-dasharray: 60px;
stroke-dashoffset: 60px;
animation: trace .5s ease-out forwards;
}
#mech-pencil-tip,
#mech-pencil-top {
stroke-dasharray: 10px;
stroke-dashoffset: 10px;
animation: trace .4s ease-out forwards;
}
/* ---------------------
ANIMATION DELAYS
--------------------- */

#clipboard-knob-1,
#clipboard-knob-2 {
animation-delay: .25s;
}
#clipboard-clip-detail,
#clipboard-content-line,
#clipboard-content-line-7,
#clipboard-knob-2 {
animation-delay: .5s;
}
#mech-pencil-bottom-btn,
#mech-pencil-top-btn {
animation-delay: 1.25s;
}

<div class="wrapper">

<!-- INSIGHT & PLANNING ICON -->

<svg id="insight-planning" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="200px" height="200px" viewBox="0 0 200 200">
<g class="clipboard">
<rect id="clipboard-fill" x="15.015" y="11.44" width="132" height="182" />
<rect id="clipboard-paper-fill" x="30.753" y="11.44" width="100" height="151" />
<g class="clipboard-content">
<line id="clipboard-content-line-even" x1="46.491" y1="68.096" x2="115.738" y2="68.096" />
<line id="clipboard-content-line" x1="46.491" y1="80.687" x2="115.738" y2="80.687" />
<line id="clipboard-content-line-even" x1="46.491" y1="93.277" x2="115.738" y2="93.277" />
<line id="clipboard-content-line" x1="46.491" y1="105.867" x2="115.738" y2="105.867" />
<line id="clipboard-content-line-even" x1="46.491" y1="118.458" x2="115.738" y2="118.458" />
<line id="clipboard-content-line-7" x1="46.491" y1="131.048" x2="96.852" y2="131.048" />
<line id="clipboard-content-line-1" x1="115.738" y1="49.211" x2="90.557" y2="49.211" />
</g>
<rect id="clipboard-border" x="15.015" y="11.44" width="132" height="182" />
</g>
<g class="mech-pencil-fills">
<rect id="mech-pencil-grip" x="166.099" y="96.425" width="18" height="47" />
<rect id="mech-pencil-top-fill" x="166.099" y="30.325" width="18" height="66" />
<rect id="mech-pencil-eraser-fill" x="166.099" y="11.44" width="18" height="18" />
<polygon id="mech-pencil-point-fill" points="184.985,143.639 184.985,159.376 175.542,168.819 166.099,159.376 166.099,143.639" />
</g>
<g class="mech-pencil-borders">
<line id="mech-pencil-border-left" x1="166.099" y1="143.639" x2="166.099" y2="30.325" />
<line id="mech-pencil-border-right" x1="184.985" y1="30.325" x2="184.985" y2="145" />
<rect id="mech-pencil-eraser-border" x="166.099" y="11.44" width="18" height="18" />
<polygon id="mech-pencil-point-border" points="184.985,143.639 184.985,159.376 175.542,168.819 166.099,159.376 166.099,143.639" />
<line id="mech-pencil-top" x1="175.542" y1="11.44" x2="175.542" y2="1.997" />
<line id="mech-pencil-tip" x1="175.542" y1="168.819" x2="175.542" y2="175.114" />
<line id="mech-pencil-bottom-btn" x1="175.542" y1="127.901" x2="175.542" y2="121.605" />
<line id="mech-pencil-top-btn" x1="175.542" y1="115.31" x2="175.542" y2="109.015" />
</g>
<g class="clipboard-clip">
<rect id="clipboard-clip-fill" x="49.639" y="5.144" width="62" height="25" />
</g>
<g class="clipboard-borders">
<polyline id="clipboard-paper-border" points="131.476,11.44 131.476,162.524 30.753,162.524 30.753,11.44" />
<rect id="clipboard-clip-border" x="49.639" y="5.144" width="62" height="25" />
<line id="clipboard-clip-detail" x1="59.081" y1="17.735" x2="103.148" y2="17.735" />
<line id="clipboard-knob-1" x1="65.376" y1="178.262" x2="71.672" y2="178.262" />
<line id="clipboard-knob-2" x1="77.967" y1="178.262" x2="84.262" y2="178.262" />
<line id="clipboard-knob-3" x1="90.557" y1="178.262" x2="96.852" y2="178.262" />
</g>
</svg>
</div>





Also posted in Codepen.

Answer

Just add stroke-linecap: square; to the CSS declarations for the SVG object.

svg {
  display: inline-block;
  width: 120px;
  margin: 3% auto;
  padding: 0px 100px;
  stroke-linecap: square;  /* <-- Add this */
}

Example:

Here's an SVG with two paths (open, not closed). The path drawn with "butt" line endings has a bit missing in the top corner, but the other path (drawn with "square" line endings) doesn't have this issue.

<svg width="250" height="100" viewBox="0 0 250 100">
  <path d="M10 10h80v80h-80v-80" style="stroke:#000; stroke-width:10px; fill:none; stroke-linecap: square;"/>
  <text x="50" y="70" text-anchor="middle">Square</text>
  <path d="M160 10h80v80h-80v-80" style="stroke:#000; stroke-width:10px; fill:none; stroke-linecap: butt;"/>
  <text x="200" y="70" text-anchor="middle">Butt</text>
 </svg>


P.S. I like your work, but next time please consider making a minimal, complete and verifiable example to illustrate the problem. That way people won't have to wade through reams of code to discover what's going wrong :-)

Comments