There are some different ways to do this, I’m going to propose 2, one with SVG which is by far the most suitable option. The other you will need to build each "edge" individually and make a slightly longer CSS to handle each of these individual edges.
Option 1 SVG
This option can be intimidating at the beginning Pous uses SVG properties, but these properties are animated by CSS which greatly facilitates understanding.
Is just a svg rect
within the link with 100% height and width within that link
<svg>
<rect></rect>
</svg>
The main thing is to keep in mind that property stroke-dasharray
and strok-dashoffset
the stippling of the edge line with regard to the size of the stippling and the distance between one stippling and the other. The idea is to have 1 dotted the size of the Btn, and a offset
tb the size of Btn, and with CSS we control this transition offset
in the hover
.
To better understand see the code. Imagine that it is only 1 dashoffset
(empty space) that will occupy the entire BTN, and then with 1 dash
Let’s make the edge of the whole button.
.btn {
display: inline-block;
text-align: center;
width: 100px;
height: 60px;
line-height: 60px;
text-transform: uppercase;
font-family: sans-serif;
text-decoration: none;
font-size: 30px;
transition: 1.5s;
position: relative;
}
svg,
svg rect {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
fill: transparent;
}
a svg rect {
stroke: blue;
stroke-width: 4;
transition: all 500ms;
stroke-dasharray: 320;
stroke-dashoffset: 320;
}
a:hover svg rect {
stroke-dashoffset: 0;
}
<a href="#" class="btn">
<svg>
<rect></rect>
</svg>
Btn
</a>
Option 2 HTML/CSS
As I said at the beginning you will need an element for each "edge". In addition you need to fractionate the transition values to make the animation very married. And use the rule :hover
and :not(:hover)
to make the animation go back and forth. It’s a little more extensive CSS, but it’s not very complex...
Run the code below
.subcont {
width: 250px;
height: 180px;
background: purple;
}
.border1 {
position: absolute;
width: 5px;
height: 0;
margin-left: 250px;
margin-top: -5px;
background: red;
transition-delay: 0;
transition-duration: 0.3s;
}
.border2 {
position: absolute;
width: 0px;
height: 5px;
margin-left: 250px;
margin-top: 180px;
background: red;
transition-delay: 0.3s;
transition-duration: 0.3s;
}
.border3 {
position: absolute;
width: 5px;
height: 0;
margin-left: -5px;
margin-top: 180px;
background: red;
transition-delay: 0.6s;
transition-duration: 0.3s;
}
.border4 {
position: absolute;
width: 0;
height: 5px;
margin-left: -5px;
margin-top: -5px;
background: red;
transition-delay: 0.9s;
transition-duration: 0.3s;
}
.subcont:hover>.border1 {
height: 190px;
}
.subcont:not(:hover)>.border1 {
position: absolute;
width: 5px;
height: 0;
margin-left: 250px;
margin-top: -5px;
background: red;
transition-delay: 0.9s;
transition-duration: 0.3s;
}
.subcont:hover>.border2 {
width: 255px;
margin-left: -5px;
}
.subcont:not(:hover)>.border2 {
position: absolute;
width: 0px;
height: 5px;
margin-left: 250px;
margin-top: 180px;
background: red;
transition-delay: 0.6s;
transition-duration: 0.3s;
}
.subcont:hover>.border3 {
height: 190px;
margin-top: -5px;
}
.subcont:not(:hover)>.border3 {
position: absolute;
width: 5px;
height: 0;
margin-left: -5px;
margin-top: 180px;
background: red;
transition-delay: 0.3s;
transition-duration: 0.3s;
}
.subcont:hover>.border4 {
width: 255px;
}
.subcont:not(:hover)>.border4 {
position: absolute;
width: 0;
height: 5px;
margin-left: -5px;
margin-top: -5px;
background: red;
transition-delay: 0s;
transition-duration: 0.3s;
}
<div class="subcont">
<div class="border1"></div>
<div class="border2"></div>
<div class="border3"></div>
<div class="border4"></div>
</div>
Related: Effect of skirting a div’s edge, as if drawing "by hand" and Incomplete edge with CSS
– Bacco
Do not edit the question and put the answer to the question, create an answer and answer your own question.
– Wictor Chaves
You said, "The idea is to slowly fill the border with every action the user takes." The solution to this question is not simple. It’s actually quite a challenge. Some premises are indispensable, otherwise the solution becomes extremely complex. 1) The user action must be well defined: For example: Set number of clicks (N) within the DIV that will receive the animated border. At each click the edge grows 1/N.
– Maujor