Border animation CSS - css

I am facing a bit of a problem and I cant seem to figure it out. The ultimate outcome I am looking for, when the box is hovered, the borders should animate to make a frame that looks like this. - image attached
But the actual outcome I am getting is different. The border don't make a perfect frame. This is my code.
<section class="services">
<div class="grid">
<div class="box">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<line class="top" x1="0" y1="0" x2="900" y2="0"></line>
<line class="left" x1="0" y1="260" x2="0" y2="-520"></line>
<line class="bottom" x1="300" y1="260" x2="-600" y2="260"></line>
<line class="right" x1="300" y1="0" x2="300" y2="780"></line>
</svg>
<div class="icon-wrapper"><i class="fa fa-users custom-icon"><span class="fix-editor"> </span></i></div>
<p>text</p>
</div>
<div class="box">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<line class="top" x1="0" y1="0" x2="900" y2="0"></line>
<line class="left" x1="0" y1="460" x2="0" y2="-920"></line>
<line class="bottom" x1="300" y1="460" x2="-600" y2="460"></line>
<line class="right" x1="300" y1="0" x2="300" y2="1380"></line>
</svg>
<h3>text</h3>
</div>
<div class="box">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<line class="top" x1="0" y1="0" x2="900" y2="0"></line>
<line class="left" x1="0" y1="460" x2="0" y2="-920"></line>
<line class="bottom" x1="300" y1="460" x2="-600" y2="460"></line>
<line class="right" x1="300" y1="0" x2="300" y2="1380"></line>
</svg>
<h3>text</h3>
</div>
</div><!-- /grid -->
</section>
This is the css
html {background:blue;}
.box {
width: 300px;
height:260px;
position: relative;
background: rgba(255,255,255,1);
display: inline-block;
margin: 0 10px;
cursor: pointer;
color: #2c3e50;
box-shadow: inset 0 0 0 3px #2c3e50;
-webkit-transition: background 0.4s 0.5s;
transition: background 0.4s 0.5s;
}
.box:hover {
background: rgba(255,255,255,0);
-webkit-transition-delay: 0s;
transition-delay: 0s;
}
.box svg {
position: absolute;
top: 0;
left: 0;
}
.box svg line {
stroke-width: 3;
stroke: #ecf0f1;
fill: none;
-webkit-transition: all .8s ease-in-out;
transition: all .8s ease-in-out;
}
.box:hover svg line {
-webkit-transition-delay: 0.1s;
transition-delay: 0.1s;
}
.box svg line.top,
.box svg line.bottom {
stroke-dasharray: 330 240;
}
.box svg line.left,
.box svg line.right {
stroke-dasharray: 490 400;
}
.box:hover svg line.top {
-webkit-transform: translateX(-600px);
transform: translateX(-600px);
}
.box:hover svg line.bottom {
-webkit-transform: translateX(600px);
transform: translateX(600px);
}
.box:hover svg line.left {
-webkit-transform: translateY(520px);
transform: translateY(520px);
}
.box:hover svg line.right {
-webkit-transform: translateY(-520px);
transform: translateY(-520px);
}
.services {text-align: center;}
/* Frame */
.services .box {
background: rgba(0,0,0,0);
color: #fff;
box-shadow: none;
-webkit-transition: background 0.3s;
transition: background 0.3s;
}
.services .box:hover {
background: rgba(0,0,0,0.4);
}
.services .box svg line {
-webkit-transition: all .5s;
transition: all .5s;
}
.services .box:hover svg line {
stroke-width: 10;
-webkit-transition-delay: 0s;
transition-delay: 0s;
}
.services .box:hover svg line.top {
-webkit-transform: translateX(-300px);
transform: translateX(-300px);
}
.services .box:hover svg line.bottom {
-webkit-transform: translateX(300px);
transform: translateX(300px);
}
.services .box:hover svg line.left {
-webkit-transform: translateY(260px);
transform: translateY(260px);
}
.services .box:hover svg line.right {
-webkit-transform: translateY(-260px);
transform: translateY(-260px);
}
And this is a fiddle

Your values for this:
.box svg line.left,
.box svg line.right {
stroke-dasharray:
}
Were causing an error for the first box. Try these numbers:
.box svg line.left,
.box svg line.right {
stroke-dasharray: 290 200;
}
Fiddle
You should be able to tweak these values for the remaining boxes as you need.

Related

SVG Animation - CSS Hover Animation For SVG From The Center

I have done this effect in GSAP here is the Codepen as a reference:
https://codepen.io/whitelionx/full/vYGQqBZ
const svgs = document.querySelectorAll("svg");
svgs.forEach((svg) => {
const tl = gsap
.timeline({
defaults: { ease: "power1.in" },
paused: true
})
.to(svg.children[0], { drawSVG: "50% 50%" })
.from(svg.children[1], { drawSVG: "0% 0%" }, 0);
svg.addEventListener("mouseenter", () => tl.play());
svg.addEventListener("mouseleave", () => tl.reverse());
});
Now I wanna do it with CSS solely so that when I hover my svg I get the same effect, here is my code sandbox:
https://codesandbox.io/s/xenodochial-benz-17lss?file=/src/styles.css
I've modified things to animate the stroke-dasharray instead.
body {
background: #000;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
flex-direction: column;
}
svg {
width: 50px;
height: 50px;
margin: 25px;
}
.circle {
stroke-dasharray: 28.3,0,28.3;
transform-origin: 50% 50%;
transform: rotate(180deg);
transition: stroke-dasharray 0.5s linear;
}
.line {
stroke-dasharray: 20;
stroke-dashoffset: 20;
transition: stroke-dashoffset 0.5s linear;
}
svg:hover .circle {
stroke-dasharray: 0,56.0;
}
svg:hover .line {
stroke-dashoffset: 0;
}
<svg
version="1.1"
shape-rendering="auto"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 20 20"
xml:space="preserve">
<path class="circle" fill="none" stroke="#FFFFFF" stroke-miterlimit="10" d="M10,1c5,0,9,4,9,9s-4,9-9,9s-9-4-9-9S5,1,10,1z"/>
<path class="line" fill="none" stroke="#FFFFFF" stroke-miterlimit="10" d="M10,0v20"/>
</svg>
I also did it in the meantime and now I get better understanding of css animations thanks to your answer too :D thinking out of the box
body {
background: #000;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
flex-direction: column;
}
svg {
width: 50px;
height: 50px;
margin: 25px;
cursor: pointer;
}
.circle {
stroke-dasharray: 56.6;
stroke-dashoffset: 0;
transform-origin: 50% 50%;
transition: stroke-dashoffset 0.3s linear, transform 0.3s linear;
}
.line {
stroke-dasharray: 20;
stroke-dashoffset: 20;
transition: stroke-dashoffset 0.3s linear;
}
svg:hover .circle {
stroke-dashoffset: 56.6;
transform: rotate(180deg);
}
svg:hover .line {
stroke-dashoffset: 0;
}
<svg
version="1.1"
shape-rendering="auto"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
viewBox="0 0 20 20"
enable-background="new 0 0 20 20"
xml:space="preserve"
>
<path
class="circle"
fill="none"
stroke="#FFFFFF"
stroke-miterlimit="10"
d="M10,1c5,0,9,4,9,9s-4,9-9,9s-9-4-9-9S5,1,10,1z"
></path>
<path
class="line"
fill="none"
stroke="#FFFFFF"
stroke-miterlimit="10"
d="M10,0v20"
></path>
</svg>

SVG animation with CSS onclick

I have a heart button when onclick it will fill the SVG with red from bottom to top and when unclicked it will unfill the SVG from top to bottom. Heres what I've searched so far:JSFiddle
I'm new with this kind of techniques like keyframes and clip-path thing. These can all be done via css only?
body {
display: -webkit-box;
display: flex;
-webkit-box-pack: center;
justify-content: center;
-webkit-box-align: center;
align-items: center;
height: 100vh;
}
.heart-container {
position: relative;
width: 40px;
height: 40px;
}
.heart-clip {
display: block;
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
-webkit-clip-path: url(#svgPath);
clip-path: url(#svgPath);
}
.heart-clip:hover {
-webkit-animation: pulse .6s .3s infinite;
animation: pulse .6s .3s infinite;
}
.heart-clip:hover::before {
-webkit-transform: scale(1);
transform: scale(1);
opacity: 1;
}
.heart-clip::before {
content: '';
display: block;
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #D32F2F;
opacity: 0;
-webkit-transform: scale(0);
transform: scale(0);
-webkit-transition: opacity .2s linear, -webkit-transform .2s linear;
transition: opacity .2s linear, -webkit-transform .2s linear;
transition: transform .2s linear, opacity .2s linear;
transition: transform .2s linear, opacity .2s linear, -webkit-transform .2s linear;
-webkit-transform-origin: center 60%;
transform-origin: center 60%;
}
.heart-stroke {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
fill: #D32F2F;
}
#-webkit-keyframes pulse {
0% {
-webkit-transform: scale(1);
transform: scale(1);
}
30% {
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
60% {
-webkit-transform: scale(1);
transform: scale(1);
}
}
#keyframes pulse {
0% {
-webkit-transform: scale(1);
transform: scale(1);
}
30% {
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
60% {
-webkit-transform: scale(1);
transform: scale(1);
}
}
<svg height="0" width="0">
<defs>
<clipPath id="svgPath">
<path d="M20,35.09,4.55,19.64a8.5,8.5,0,0,1-.13-12l.13-.13a8.72,8.72,0,0,1,12.14,0L20,10.79l3.3-3.3a8.09,8.09,0,0,1,5.83-2.58,8.89,8.89,0,0,1,6.31,2.58,8.5,8.5,0,0,1,.13,12l-.13.13Z"/>
</clipPath>
</defs>
</svg>
<div class="heart-container">
<svg width="40" height="40" viewBox="0 0 40 40" class='heart-stroke'>
<path d="M20,35.07,4.55,19.62a8.5,8.5,0,0,1-.12-12l.12-.12a8.72,8.72,0,0,1,12.14,0L20,10.77l3.3-3.3A8.09,8.09,0,0,1,29.13,4.9a8.89,8.89,0,0,1,6.31,2.58,8.5,8.5,0,0,1,.12,12l-.12.12ZM10.64,7.13A6.44,6.44,0,0,0,6.07,18.19L20,32.06,33.94,18.12A6.44,6.44,0,0,0,34,9l0,0a6.44,6.44,0,0,0-4.77-1.85A6,6,0,0,0,24.83,9L20,13.78,15.21,9A6.44,6.44,0,0,0,10.64,7.13Z"/>
</svg>
<a href='#' class='heart-clip'></a>
</div>
any alternatives and solutions is much appreciated!
Thanks in advance!
Consider filling with color using the feFlood filters and animating with changing thedy attribute of the feoffset filter.
Repeated clicks change the color direction animation
var svg1 = document.getElementById("svg1"),
close = document.getElementById('close'),
open = document.getElementById("open");
let flag = true;
svg1.addEventListener('click', function() {
if (flag == true) {
close.beginElement();
flag = false;
} else {
open.beginElement();
flag = true;
}
});
<div class="heart-container">
<svg id="svg1" width="40" height="40" viewBox="0 0 40 40" class='heart-stroke'>
<defs>
<filter id="red_fill" x="0%" y="0%">
<feFlood flood-color="#ded9d5" />
<feOffset dx="0">
<!-- Animation fills of color from top to bottom. -->
<animate id="close" attributeName="dy" values="0;40" dur="1s" begin="indefinite" repeatCount="3" restart="whenNotActive" fill="freeze"/>
<!-- Animation fills of color from bottom to top. -->
<animate id="open" attributeName="dy" values="40;0" dur="1s" begin="indefinite" repeatCount="3" restart="whenNotActive" fill="freeze"/>
</feOffset>
<feComposite operator="in" in2="SourceGraphic" />
<feComposite operator="over" in2="SourceGraphic" />
</filter>
</defs>
<path filter="url(#red_fill)" stroke="red" stroke-width="2" fill="red" d="M20,35.07,4.55,19.62a8.5,8.5,0,0,1-.12-12l.12-.12a8.72,8.72,0,0,1,12.14,0L20,10.77l3.3-3.3A8.09,8.09,0,0,1,29.13,4.9a8.89,8.89,0,0,1,6.31,2.58,8.5,8.5,0,0,1,.12,12l-.12.12Z"/>
</svg>
<a href='#' class='heart-clip'></a>
</div>

Changing values of the points attribute on hover - SVG - polyline

So I have this svg element, which is basically a cube:
#rect1 {fill: url(#Gradient1)}
.stop1 {stop-color: black}
.stop2 {stop-color: #5961FF}
#cube {
transform-origin: 50% 30%;
transform: scale(0.5);
transform: translate(-220px, 0);
}
#cube-text {
font-size: 2.5em;
fill: red;
transform: rotate(-30,300, 10);
font-family: 'VT323', monospace;
text-shadow:
-2px 4px 2px rgba(254,254,254,0.5),
-4px 4px 3px rgba(255,255,255,0.4),
-6px 4px 2px rgba(22,44,65,0.62),
-8px 4px 1px rgba(22,44,65,1);
opacity: 1;
}
#top {
transform: translate(0, -300px);
animation: top 0.5s forwards ease-out 1s;
opacity: 0;
fill: url(#blue);
z-index: 99;
}
#right {
transform: translate(300px, 0);
animation: right 0.5s forwards ease-out 2s;
opacity: 0;
fill: #152B40;
z-index: 99;
}
#left {
transform: translate(-300px, 0);
animation: left 0.5s forwards ease-out 3s;
opacity: 0;
fill: url(#blue-shade);
z-index: 99;
}
#left:hover {
points: "500, 100";
}
#keyframes top {
from {
transform: translate(0, -300px);
opacity: 0;
}
to {
transform: translate(0, 0);
opacity: 1;
}
}
#keyframes right {
from {
transform: translate(300px, 0);
opacity: 0;
}
to {
transform: translate(0, 0);
opacity: 1;
}
}
#keyframes left {
from {
transform: translate(-300px, 0);
opacity: 0;
}
to {
transform: translate(0, 0);
opacity: 1;
}
}
#keyframes rotate {
from {
transform: rotate(0);
opacity: 0;
}
to {
transform: rotate(360deg);
opacity: 1;
}
}
#keyframes scale-spin {
from {
transform: scale(1);
}
to {
transform: scale(0);
}
}
<link href="https://fonts.googleapis.com/css?family=Baloo+Tamma|Black+Ops+One|Coda|Codystar|Fugaz+One|IBM+Plex+Mono|Overpass+Mono|PT+Mono|Racing+Sans+One|VT323" rel="stylesheet">
<svg id="cube" height="1000" width="1000">
<defs>
<linearGradient id="blue" gradientUnits="objectBoundingBox" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#152B40"/>
<stop offset="50%" stop-color="#152B40"/>
</linearGradient>
<linearGradient id="blue-shade" gradientUnits="objectBoundingBox" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#152B40"/>
<stop offset="100%" stop-color="#4A9BE5"/>
</linearGradient>
</defs>
<text id="cube-text" x="250" y="560">
<tspan x="414" y="320">Random Text</tspan>
</text>
<polyline id="top" points="500,100 250,150 500,220 750,150 500,100" style="fill: #152B40; stroke: ; stroke-width: "/>
<polyline id="right" points="500,220 500,550 750,400 750,150 500,220" style="fill: #152B40; stroke: #152B40; stroke-width: " />
<polyline id="left" points="500,550 250,400 250,150 500,220" style="fill: ; stroke: #152B40; stroke-width: 2" />
</svg>
When I :hover over the #left polyline, I want to change the values of the points attribute. For some reason I cannot edit that with CSS and therefore think points isn't a valid CSS property.
Unfortunately there is no CSS property that can effect the points attribute of the polyline element.
Instead, you can do it with the onmouseover event and setAttribute() method, e.g.:
function changeLeft() {
var left = document.getElementById('left');
left.setAttribute('points','510,560 260,410 260,160 510,230');
}
#rect1 {fill: url(#Gradient1)}
.stop1 {stop-color: black}
.stop2 {stop-color: #5961FF}
#cube {
transform-origin: 50% 30%;
transform: scale(0.5);
transform: translate(-220px, 0);
}
#cube-text {
font-size: 2.5em;
fill: red;
transform: rotate(-30, 300, 10);
font-family: 'VT323', monospace;
text-shadow:
-2px 4px 2px rgba(254,254,254,0.5),
-4px 4px 3px rgba(255,255,255,0.4),
-6px 4px 2px rgba(22,44,65,0.62),
-8px 4px 1px rgba(22,44,65,1);
opacity: 1;
}
#top {
transform: translate(0, -300px);
animation: top 0.5s forwards ease-out 1s;
opacity: 0;
fill: url(#blue);
z-index: 99;
}
#right {
transform: translate(300px, 0);
animation: right 0.5s forwards ease-out 2s;
opacity: 0;
fill: #152B40;
z-index: 99;
}
#left {
transform: translate(-300px, 0);
animation: left 0.5s forwards ease-out 3s;
opacity: 0;
fill: url(#blue-shade);
z-index: 99;
}
/*
#left:hover {
points: "500, 100";
}
*/
#keyframes top {
from {
transform: translate(0, -300px);
opacity: 0;
}
to {
transform: translate(0, 0);
opacity: 1;
}
}
#keyframes right {
from {
transform: translate(300px, 0);
opacity: 0;
}
to {
transform: translate(0, 0);
opacity: 1;
}
}
#keyframes left {
from {
transform: translate(-300px, 0);
opacity: 0;
}
to {
transform: translate(0, 0);
opacity: 1;
}
}
#keyframes rotate {
from {
transform: rotate(0);
opacity: 0;
}
to {
transform: rotate(360deg);
opacity: 1;
}
}
#keyframes scale-spin {
from {
transform: scale(1);
}
to {
transform: scale(0);
}
}
<link href="https://fonts.googleapis.com/css?family=Baloo+Tamma|Black+Ops+One|Coda|Codystar|Fugaz+One|IBM+Plex+Mono|Overpass+Mono|PT+Mono|Racing+Sans+One|VT323" rel="stylesheet">
<svg id="cube" height="1000" width="1000">
<defs>
<linearGradient id="blue" gradientUnits="objectBoundingBox" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#152B40"/>
<stop offset="50%" stop-color="#152B40"/>
</linearGradient>
<linearGradient id="blue-shade" gradientUnits="objectBoundingBox" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#152B40"/>
<stop offset="100%" stop-color="#4A9BE5"/>
</linearGradient>
</defs>
<text id="cube-text" x="250" y="560">
<tspan x="414" y="320">Random Text</tspan>
</text>
<polyline id="top" points="500,100 250,150 500,220 750,150 500,100" style="fill: #152B40; stroke: ; stroke-width: " />
<polyline id="right" points="500,220 500,550 750,400 750,150 500,220" style="fill: #152B40; stroke: #152B40; stroke-width: " />
<polyline id="left" points="500,550 250,400 250,150 500,220" style="fill: ; stroke: #152B40; stroke-width: 2" onmouseover="changeLeft();" />
</svg>

SVG line animation 2

How to change the heigh of this SVG to 24px and get it work correctly on :hover?
HTML:
<div class="sv_btn">
<svg width="100" height="100">
<line class="top" x1="0" y1="0" x2="600" y2="0" />
<line class="left" x1="0" y1="100" x2="0" y2="-200" />
<line class="bottom" x1="100" y1="100" x2="-200" y2="100" />
<line class="right" x1="100" y1="0" x2="100" y2="600" />
</svg>
</div>
CSS:
.sv_btn {
position: relative;
width: 100px;
height: 100px;
margin: 200px;
}
.sv_btn svg {
position: absolute;
top: 0;
left: 0;
}
.sv_btn line {
stroke-width: 5;
stroke: #000;
fill: none;
stroke-dasharray: 100px;
transition: transform .6s;
}
.sv_btn:hover svg line.top {
transform: translateX(-200px);
}
.sv_btn:hover svg line.bottom {
transform: translateX(200px);
}
.sv_btn:hover svg line.left {
transform: translateY(200px);
}
.sv_btn:hover svg line.right {
transform: translateY(-200px);
}
Demo: http://codepen.io/anon/pen/KdPEvr
The simplest way is to change the first line of your SVG as follows:
<svg width="100%" height="100%" viewBox="0 0 100 100">
Then the SVG will scale to the size of your <div>. So all you then need to do is style the div to 24px:
.sv_btn {
position: relative;
width: 24px;
height: 24px;
margin: 200px;
}
.sv_btn {
position: relative;
width: 24px;
height: 24px;
margin: 200px;
}
.sv_btn .text {
width: 100%;
height: 100%;
text-align: center;
position: absolute;
display: flex;
justify-content: center;
flex-direction: column;
font-size: 16px;
color: whitesmoke;
}
.sv_btn svg {
position: absolute;
top: 0;
left: 0;
}
.sv_btn line {
stroke-width: 5;
stroke: #000;
fill: none;
stroke-dasharray: 100px;
transition: transform .6s;
}
.sv_btn:hover svg line.top {
transform: translateX(-200px);
}
.sv_btn:hover svg line.bottom {
transform: translateX(200px);
}
.sv_btn:hover svg line.left {
transform: translateY(200px);
}
.sv_btn:hover svg line.right {
transform: translateY(-200px);
}
<div class="sv_btn">
<svg width="100%" height="100%" viewBox="0 0 100 100">
<line class="top" x1="0" y1="0" x2="600" y2="0" />
<line class="left" x1="0" y1="100" x2="0" y2="-200" />
<line class="bottom" x1="100" y1="100" x2="-200" y2="100" />
<line class="right" x1="100" y1="0" x2="100" y2="600" />
</svg>
</div>
Update
To change just the height to 24px, and have it squeeze to fit, add preserveAspectRatio="none". In addition, you probably want to add vector-effect="non-scaling-stroke" to the paths, so that the stroke widths of the lines don't get squeezed also.
<svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="none" vector-effect="non-scaling-stroke">
.sv_btn {
position: relative;
width: 100px;
height: 24px;
margin: 200px;
}
.sv_btn .text {
width: 100%;
height: 100%;
text-align: center;
position: absolute;
display: flex;
justify-content: center;
flex-direction: column;
font-size: 16px;
color: whitesmoke;
}
.sv_btn svg {
position: absolute;
top: 0;
left: 0;
}
.sv_btn line {
stroke-width: 5;
stroke: #000;
fill: none;
stroke-dasharray: 100px;
transition: transform .6s;
}
.sv_btn:hover svg line.top {
transform: translateX(-200px);
}
.sv_btn:hover svg line.bottom {
transform: translateX(200px);
}
.sv_btn:hover svg line.left {
transform: translateY(200px);
}
.sv_btn:hover svg line.right {
transform: translateY(-200px);
}
<div class="sv_btn">
<svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="none">
<line class="top" x1="0" y1="0" x2="600" y2="0" vector-effect="non-scaling-stroke" />
<line class="left" x1="0" y1="100" x2="0" y2="-200" vector-effect="non-scaling-stroke" />
<line class="bottom" x1="100" y1="100" x2="-200" y2="100" vector-effect="non-scaling-stroke" />
<line class="right" x1="100" y1="0" x2="100" y2="600" vector-effect="non-scaling-stroke" />
</svg>
</div>
However that stretchy scale will affect the line widths, meaning the verticcal lines are now fatter than the horizontal ones.
Update 2
If you don't want to use the rescale approach, you can change the SVG by manually resizing the vertical sides of the rectangle, and rejigging some of the CSS.
.sv_btn {
position: relative;
width: 100px;
height: 24px;
margin: 200px;
}
.sv_btn .text {
width: 100%;
height: 100%;
text-align: center;
position: absolute;
display: flex;
justify-content: center;
flex-direction: column;
font-size: 16px;
color: whitesmoke;
}
.sv_btn svg {
position: absolute;
top: 0;
left: 0;
}
.sv_btn line {
stroke-width: 5;
stroke: #000;
fill: none;
transition: transform .6s;
}
.sv_btn svg line.top,
.sv_btn:hover svg line.bottom {
stroke-dasharray: 100px;
}
.sv_btn:hover svg line.top {
transform: translateX(-200px);
}
.sv_btn:hover svg line.bottom {
transform: translateX(200px);
}
.sv_btn svg line.left,
.sv_btn svg line.right {
stroke-dasharray: 24px;
}
.sv_btn:hover svg line.left {
stroke-dasharray: 24px;
transform: translateY(48px);
}
.sv_btn:hover svg line.right {
stroke-dasharray: 24px;
transform: translateY(-48px);
}
<div class="sv_btn">
<svg width="100" height="24">
<line class="top" x1="0" y1="0" x2="600" y2="0" />
<line class="left" x1="0" y1="24" x2="0" y2="-48" />
<line class="bottom" x1="100" y1="24" x2="-200" y2="24" />
<line class="right" x1="100" y1="0" x2="100" y2="144" />
</svg>
</div>

SVG line stays in screen after leaving mouse

I've made a div, with 4 svg lines in it.
When hovering the div, the x- and y-axis changes using transition and transform.
Everything works fine, got it working but when i leave the mouse from the hover field, the svg line stays just a couple pixels in screen.
Check the example at the bottom of the page..
Any explanations/solutions will be very appreciated.
HTML:
<div class="blok">
<svg width="200" height="100">
<line class="left" x1="0" y1="0" x2="0" y2="-100"/>
<line class="bottom" x1="-200" y1="100" x2="0" y2="100"/>
<line class="right" x1="200" y1="100" x2="200" y2="200"/>
<line class="top" x1="200" y1="0" x2="400" y2="0"/>
</svg>
</div>
CSS:
.blok{
width: 200px;
height: 100px;
position: relative;
overflow: hidden;
background: #ddd;
}
svg {
position: absolute;
top: 0;
left: 0;
}
svg line {
stroke-width: 10;
stroke: #000;
fill: none;
}
svg line.top, line.bottom {
stroke-dasharray: 200;
-webkit-transition: -webkit-transform .2s ease-out;
transition: transform .2s ease-out;
}
svg line.left, line.right {
stroke-dasharray: 100;
-webkit-transition: -webkit-transform .1s ease-out;
transition: transform .1s ease-out;
}
svg line.top{
-webkit-transition-delay: 0s;
transition-delay: 0s;
}
svg line.right{
-webkit-transition-delay: .2s;
transition-delay: .2s;
}
svg line.bottom{
-webkit-transition-delay: .3s;
transition-delay: .3s;
}
svg line.left{
-webkit-transition-delay: .5s;
transition-delay: .5s;
}
.blok:hover svg line.left {
-webkit-transform: translateY(100px);
transform: translateY(100px);
-webkit-transition-delay: 0s;
transition-delay: 0s;
}
.blok:hover svg line.bottom {
-webkit-transform: translateX(200px);
transform: translateX(200px);
-webkit-transition-delay: .1s;
transition-delay: .1s;
}
.blok:hover svg line.right {
-webkit-transform: translateY(-100px);
transform: translateY(-100px);
-webkit-transition-delay: .3s;
transition-delay: .3s;
}
.blok:hover svg line.top {
-webkit-transform: translateX(-200px);
transform: translateX(-200px);
-webkit-transition-delay: .4s;
transition-delay: .4s;
}
JsFiddle HERE
You could simplify the whole thing and have a single line around the rectangle and transition the stroke-dashoffset rather than moving four individual lines.
SVG
<svg width="200" height="100">
<polyline class="line" points="0,0, 0,100, 200,100, 200,0 0,0"/>
</svg>
CSS
svg .line {
stroke-width: 10;
stroke: #000;
fill: none;
stroke-dasharray: 600;
stroke-dashoffset: 600;
}
svg .line {
stroke-dashoffset: 600;
-webkit-transition: stroke-dashoffset 0.5s ease-out;
transition: stroke-dashoffset 0.5s ease-out;
}
.blok:hover svg .line {
stroke-dashoffset: 0;
-webkit-transition: stroke-dashoffset 0.5s ease-out;
transition: stroke-dashoffset 0.5s ease-out;
}
Demo here
Try starting the lines from outside the svg
<div class="blok">
<svg width="200" height="100">
<line class="left" x1="0" y1="-5" x2="0" y2="-100"/>
<line class="bottom" x1="-205" y1="100" x2="0" y2="100"/>
<line class="right" x1="200" y1="105" x2="200" y2="205"/>
<line class="top" x1="205" y1="0" x2="400" y2="0"/>
</svg>
</div>
http://jsfiddle.net/shedali/vr8xj27n/

Resources