Sketch the borders of the element (animated)

Seeking a way to create a button with an animated border that looks like it is being drawn.

Current progress involves some code, but it's not working smoothly with border-radius set. (keep an eye on the corners)

https://codepen.io/anon/pen/MbWagQ

<button class="draw">draw</button>

//Colors
$cyan: #60daaa;
$red: #f45e61;

// Basic styles
button {
  background: none;
  border: 0;
  box-sizing: border-box;
  color: $red;
  font-size: inherit;
  font-weight: 700;
  padding: 1em 2em;
  text-align: center;
  margin: 20px;

  // Necessary for pseudo-elements absolute positioning
  position: relative;
  vertical-align: middle;

  &::before,
  &::after {
    box-sizing: border-box;
    content: '';
    position: absolute;
    width: 100%;
    height: 100%;
  }
}

.draw {
    transition: color 0.25s;
    border-radius: 7px;

  &::before,
  &::after {
    border-radius: 7px;
    border: 3px solid transparent; 
    width: 0;
    height: 0;
  }

  // Top & right borders expanding effect
  &::before {
    top: 0;
    left: 0;
  }

  // Bottom & left borders expanding effect
  &::after {
    bottom: 0;
    right: 0;
  }

  &:hover {
    color: $cyan;
  }

  // Hover effects
  &:hover::before,
  &:hover::after {
    width: 100%;
    height: 100%;
  }

  &:hover::before {
    border-top-color: $cyan; 
    border-right-color: $cyan;
    transition:
      width 0.25s ease-out, 
      height 0.25s ease-out 0.25s; 
  }

  &:hover::after {
    border-bottom-color: $cyan; 
    border-left-color: $cyan;
    transition:
      border-color 0s ease-out 0.5s, 
      width 0.25s ease-out 0.5s, 
      height 0.25s ease-out 0.75s; 
  }
}

Preferably looking to achieve this effect using only HTML and CSS, avoiding SVG files if possible. JavaScript could be considered as well.

Answer №1

It appears that the issue lies in the initial height of your draw::before/draw::after elements being set to 0px during the transition, causing the border radius to appear distorted.

button {
  background: none;
  border: 0;
  box-sizing: border-box;
  color: #f45e61;
  font-size: inherit;
  font-weight: 700;
  padding: 200px;
  text-align: center;
  margin: 20px;
  position: relative;
  vertical-align: middle;
}
button::before,
button::after {
  box-sizing: border-box;
  content: '';
  position: absolute;
  width: 100%;
  height: 100%;
}
.draw {
  -webkit-transition: color 0.25s;
  transition: color 0.25s;
  border-radius: 70px;
}
.draw::before,
.draw::after {
  border-radius: 70px;
  border: 30px solid transparent;
  width: 0;
  height: 0;
}
.draw::before {
  top: 0;
  left: 0;
}
.draw::after {
  bottom: 0;
  right: 0;
}
.draw:hover {
  color: #60daaa;
}
.draw:hover::before,
.draw:hover::after {
  width: 100%;
  height: 100%;
}
.draw:hover::before {
  border-top-color: #60daaa;
  border-right-color: #60daaa;
  -webkit-transition: width 1.25s ease-out, height 1.25s ease-out 1.25s;
  transition: width 1.25s ease-out, height 1.25s ease-out 1.25s;
}
.draw:hover::after {
  border-bottom-color: #60daaa;
  border-left-color: #60daaa;
  -webkit-transition: border-color 0s ease-out 2.5s, width 1.25s ease-out 2.5s, height 1.25s ease-out 3.75s;
  transition: border-color 0s ease-out 2.5s, width 1.25s ease-out 2.5s, height 1.25s ease-out 3.75s;
}
<h1>CSS Border Transitions</h1>
<button class="draw">draw</button>

By adjusting the animation speed and size, you can better visualize the problem. It might be beneficial to include a transition for the right/left border during the height transformation to prevent any unusual shapes at the 'drawing point.'

For a clearer example of the skewed border radius, please refer to this image:

https://i.sstatic.net/db1rE.png

http://codepen.io/anon/pen/mOdOyQ

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Placing two parent flex containers on top of each other

I'm in a situation where I have two .container elements, both set at a height of 50%. Within these containers are the child divs .element, which belong to their respective parent divs .container. The problem arises when applying media queries with f ...

Preloading error alert message displayed during AJAX request

When I send an ajax request with a dropdown change, the loader div is shown using "before send". However, the issue is that the loader only displays for the first time, even though the ajax functionality works all the time. If you want to check this issue ...

In the main.js file of an Electron application, the function $.ajax is not recognized

I attempted to make an asynchronous call in main.js on electron. I initially tried using Jquery but encountered an error stating $.ajax is not a function. I tried the following code: mainWindow.$ = mainWindow.jQuery = require('jquery'); let $ = ...

The addition of input fields on keyup creates problems in the initial field of each row

I am currently working with a table and attempting to calculate the sums as follows: td(1) + td(2) + td(3) = td(4), td(5) + td(6) + td(7) = td(8), td(9) + td(10) + td(11) = td(12). This is the code I have implemented: $(document).ready(function () { ...

Incorporating HTML and JavaScript into TypeScript: How to Embed a Shopify Buy Button in a .tsx document

I am currently looking to integrate Shopify with my personal website. My frontend is built using React (NextJS with TypeScript). The embed code for the Shopify buy button consists of an HTML div tag wrapping JavaScript. I am wondering how I can effectivel ...

Change the default direction of content scrolling in CSS and JavaScript to scroll upwards instead of

I am currently working on a website where the navigation bar spans the entire width and remains fixed in place. Below the navigation bar is a cover image, followed by the main content section. As you scroll down, the navigation bar covers the image from t ...

How can you retrieve script data within HTML and PHP tags?

I am currently working on a web application using CodeIgniter-3 and I have encountered an issue with a form that contains two dropdowns which are dependent on each other. When a selection is made in the first dropdown, the data in the second dropdown sho ...

Tips for including a subquery in query results using axis

I have a query for the objects table using an id. Then, I want to query the same table with the id from my result and add it as a new property. Does that explanation make sense? app.get(`/details`, (req, res) => { const { id } = req.query; connectio ...

Can users be prevented from bookmarking a particular web page?

I'm working on a Python (Django) webpage and I need to prevent users from being able to bookmark a certain page. Is there a way to do this? ...

Error encountered: Invoking the children() method in a class filter context is throwing a typeError

Examining the HTML layout provided: <ul> <li id="a"> <a class="x"> <span class="hidden"></span> </a> <span class="showing">Some text</span> </li> <li id="b"> ...

What is the best way to validate a particular class in javascript?

Need help checking if a specific id has a particular class. Unsure of the process? Here's the code snippet where the attempt at checking the id for a specific class is visible within the homeTransition function. function homeTransition() { ...

Challenges in creating an alternative path in ExpressJS

I am currently working on a website for my studies. I decided to use nodejs/Express, as the technology is free. The first route /home was successful, but I am having trouble creating more routes. Although I thought I had a good understanding of the system ...

Input field modified upon focus

I am currently using selectize js in my section to create a select box. My goal is to make the input editable after selecting an option when it is focused on. Check out the live demo: live demo HTML <label>Single selection <select id=" ...

CSS margin dispute

I'm facing an issue with two CSS classes - container and top_menu. The top_menu should not have a margin on top when used within the container class, but it somehow does. Removing the container div resolves this. How can I resolve this problem? Below ...

At what point does IE7 recalculate styles? It seems to have difficulty functioning consistently when a class is applied to the body

Currently facing a peculiar issue. I'm utilizing a class on the element as a toggle switch to control various layout behaviors on my website. When the class is active, specific actions occur; when it's inactive, these actions do not take place. ...

Achieving peak efficiency: Comparing the execution of actions through dispatching versus passing them as props

I have a technical query. I'm attempting to send a value from a child component to the store by utilizing an action dispatcher inside the child component. This action dispatcher then modifies the state value in the reducer. Would it be wise to pass v ...

I have a task to execute an Ajax request to retrieve and display data from my database table. My approach involves utilizing Perl CGI and attempting to invoke a Perl script using JavaScript

Encountering an issue in the web console with an error in the document.ready function showing an uncaught syntax error unidentified identifier. This CGI script contains JavaScript that calls a Perl script (TestAj.pl) which returns JSON data. I'm atte ...

Unable to access controller using jquery/ajax in CodeIgniter along with a bootstrap template

When loading a page into another, everything seems to be working fine except for the controller loading: The scripts and CSS are being loaded in the default page code, which might be causing the issue. The error message "Failed to load resource: the serve ...

AngularJS not refreshing the view

I'm having an issue in my app where I calculate the total bill and display it on my view. The first time, everything works fine. However, when I increment the $scope.bill_total, the view is not updating even though I can see the change in the console. ...

Tips for creating a countdown timer from scratch without relying on a plugin

Looking at this image, it is clear that jQuery can be used. However, I am wondering if there is a way to create a countdown timer without relying on plugins. Can anyone offer some guidance? ...